特定の文字列を除いた配列の作成マクロについて

このQ&Aのポイント
  • 特定の文字列を含んだ列を全て削除したデータを配列に格納するマクロを作成したい
  • 特定の文字列は「山田」「佐藤」「田中」の3種類とする
  • 削除後のデータは30000個程度の新しい配列に格納したい
回答を見る
  • ベストアンサー

特定の文字列を除いた配列の作成マクロについて

頭書の件、現在マクロで以下のようなことを行おうとしており悩んでおります。 皆様のお知恵を拝借いたしたく、お願いいたします。 エクセルのSheet1に以下のような形でデータが格納されております。 A行:文字列、B行:数字でそれぞれ60000個程度のデータ格納されております。 この中から、特定の文字列を含んだ列を全て削除したデータを配列に格納するマクロを作成したいと考えています。 「特定の文字列」は、例えば"山田", "佐藤", "田中"の3種類とします。 もし上述の文字列のいずれかを含んだデータが30000個あれば、削除後の30000個程度のデータを新しい配列に格納したいと思っています。 イメージ的には以下のような操作がしたいのですが、「If C(i, 1) <> List Then」では通らないので、この部分に該当するような操作をなにかしらの方法で表現できましたらご教授いただけると助かります。 Sub test() Dim C As Variant Dim D As Variant Dim i As Long Dim j As Long Dim List As Variant List = Array("山田", "佐藤", "田中") C = Worksheets("Sheet1").Range("A1", "B6000") For i = 1 To 60000 If C(i, 1) <> List Then D(j,1)=C(i,1) D(j,2)=C(i,2) j=j+1 Else End If Next End Sub お手数をおかけいたしますが、宜しくお願いいたします。

質問者が選んだベストアンサー

  • ベストアンサー
  • chie65535
  • ベストアンサー率43% (8520/19368)
回答No.2

以下のようにします。 -----ここから '配列の要素を「1から使う」ので「Option Base 1」が必須 Option Base 1 Sub test() Dim C As Variant 'Dを「動的配列」として定義 Dim D() As Variant Dim i As Long Dim j As Long Dim k As Integer '「どれか1つに一致してしまった」を示すフラグを定義 Dim f As Boolean Dim List As Variant List = Array("山田", "佐藤", "田中") '6000行ではなく60000行の間違い C = Worksheets("Sheet1").Range("A1:B60000") j = 1 'Dを「2次元配列」として再定義 ReDim Preserve D(2, 1) For i = 1 To 60000 'フラグを立てておく f = True 'Listの要素数だけループする For k = 1 To UBound(List) 'Listの1つと一致するか調べる If C(i, 1) = List(k) Then 'どれかに一致したらフラグを消す f = False 'それ以上Listを調べる必要はないのでForを抜ける Exit For End If Next 'フラグが立ったままならどれにも一致しないので処理する If f = True Then 'データが増えるので配列の「一番下の次元」を拡張する 'ReDim Preserve D(2, j) 'データをコピーする(行と列が逆になる事に注意) D(1, j) = C(i, 1) D(2, j) = C(i, 2) j = j + 1 End If Next 'Dの配列は「行と列を逆に作った」ので、行と列を入れ替える D = WorksheetFunction.Transpose(D) 'Dの配列の要素数を確認するメッセージボックスを表示 MsgBox UBound(D, 1) & "," & UBound(D, 2) '確認の為、C列、D列に配列の中身を代入してみる Worksheets("Sheet1").Range("C1:D" & j - 1) = D End Sub -----ここまで **注意** 動的配列の「D」は D(2,1)→D(2,2)→D(2,3)→D(2,4)→D(2,5)→D(2,6)→……D(2,60000) のように「一番下の次元」しか変更できません。 そのため「行と列を逆に作成」する必要があります。

220F284
質問者

お礼

ご連絡ありがとうございます。 動的配列では一番下の次元しか変更できないというのは知りませんでした。 詳細なご説明ありがとうございます。 非常に勉強になりました。

その他の回答 (2)

  • chie65535
  • ベストアンサー率43% (8520/19368)
回答No.3

訂正。 変な場所に「コメントマーク」が入ってしまいました。 誤 'データが増えるので配列の「一番下の次元」を拡張する 'ReDim Preserve D(2, j) 正 'データが増えるので配列の「一番下の次元」を拡張する ReDim Preserve D(2, j)

  • dogs_cats
  • ベストアンサー率38% (278/717)
回答No.1

List = Array("山田", "佐藤", "田中")は List(0)に山田 List(1)に佐藤が格納されます。変数Cに対しListをループで比較する方法しかないと思うのですが。 Dは2次配列で要素数は6000,2と宣言しました。 一例です。do~loopを使用しています。 Sub test() Dim C As Variant Dim D(6000, 2) As Variant Dim i, j, k As Long Dim flag As Boolean Dim List As Variant List = Array("山田", "佐藤", "田中") C = Worksheets("Sheet1").Range("A1", "B6000") i = 1 k = 1 Do While i <= 6000 flag = True '配列Listデータを0~2でループさせデータが一致した場合はD0を抜け 'flag = Falseとする(データを格納させないためのflag) j = 0 Do While j <= 2 If C(i, 1) = List(j) Then flag = False: Exit Do j = j + 1 Loop If flag = True Then D(k, 1) = C(i, 1) D(k, 2) = C(i, 2) k = k + 1 End If i = i + 1 Loop End Sub

220F284
質問者

お礼

早速のご連絡ありがとうございます。 ご連絡いただきました方法で、If文の部分をLike "*" & List(j) & "*"とすることで、目的のマクロにすることができました。早々にご対応いただきました誠にありがとうございました。

関連するQ&A

  • 配列での文字列の連続処理

     VBAなので低レベルすぎてここで質問する内容ではないかもしれませんが      Dim 元データ As Variant Dim 文字数 As Variant 元データ = Range("D1:D3087") For i = 1 To 3087 ’元データに格納されている文字列をこの間で操作したい      任意の文字を抜き取ってセルに貼り付ける 文字数 = Len(元データ) MsgBox 文字数 Next i 上記で 元データ に D1:D3087 の文字列を格納し文字列から必要な部分を抜き出しセルに書き込みたいのですが、エラーで止まります D1:D3087 の1行目は麻B060516-MSE300です。 文字列を操作できないのは元データがstringじゃないので無理っぽいかんじがするのですが配列に取り込むにはvariantじゃないといけないみたいなので、良い方法があればご教示いただけると幸いです。

  • マクロの作り方について

    お世話になっております。 エクセルで次のようなテーブルの自動生成マクロを作成したいと考えておりますが、なかなかうまくいきません。 皆さまのお知恵を拝借いたしたく、お願いいたします。 「Data」シート、「Table」シートの2つのシートをエクセルに用意します。 「Data」シートには、200行2列のデータが予め入っています。 1列目にはaaa.F、aaa.W、aaa.R、bbb.F、bbb.W、bbb.Rといった形の文字列が延々と入っています。 2列目には数字のデータが入っています。 行いたいのは、まず1列目のデータを「.」で区切って、2つの配列「st」と「pr」に入れなおすことです。 ただ、単にsplitするだけですと、1列目のデータを分けた際に、 st=(aaa、aaa、aaa、bbb、bbb、bbb) pr=(F、W、R、F、W、R) といった形で同じ値が格納されますが、ダブっている文字ははじく様にしたいのです。 このため、例えばstについて、次のようなマクロを考えたのですが、これだとstをdebug.Print等で出力した際、一番最後のデータだけしか格納されていませんでした。 Dim C As Variant C = Worksheets("DATA").Range("A1:B65000") Dim D As Variant Dim i As Integer Dim st As Variant For i = 1 To 10 D = Split(C(i, 1), ".") If st <> D(0) Then st = D(0) Debug.Print (st)  ↑ここでstを出力している分には、aaa、bbb、cccとダブった文字を省いたすべてのデータが出力されます。 Else End If Next Debug.Print (st)  ↑ここでstを出力すると、最後のデータだけしか出力することができません。  st(3)等、特定の要素を出力しようとしてもできないようです。 stをvariant型にしていることが問題なのかもしれませんが、stをstring型のarrayで定義し、各要素ごとに入力すると、st(0)=aaa、st(1)=aaaといった形で同じ値のものも入ってしまいます。 異なった文字列だけ各要素に入力していくにはどのようにマクロを組めばよいのでしょうか?

  • Excel 文字列を検索して全て置換するマクロ

    当方VBA初心者なのですが、ExcelのVBAで作ったマクロでうまく動かなくて困っています。 もしおわかりになる方がいらっしゃったら是非よろしくお願いいたします。 *実現したいこと '”reference”という名前のシートに、次のようなデータが入っています。 (1) りんご (2) みかん (3) キウイ ・・・ これを、配列を2つ用意し、 (1)を配列Listに、(2)を配列List2へ格納して行きます。 '"data"という名前のシートには、A列の1~10行目までに文章が入っていて、 "家には、(1)があります。" "冬になるとよく(2)を食べます。" ・・・・ この全文をcというRangeに設定し、そのcの中において、 もし、配列1((1)等)のキーワードがあったら、 'そのキーワードを配列2(りんご等)の内容に書き換える。 'キーワードは、データシートに複数回出てくる場合もある。 *困っていること 下記のマクロだと、一度目のObjFindまでは成功するのですが、 List(i)を探しているはずが、2回目から、その変更後の文字列が含まれた全文を検索するようになってしまいます。 以下マクロです。 よろしくお願いいたします。 Sub TEST() Dim List() As String, List2() As String 'List Dim i As Integer Dim iRow As Integer iRow = Worksheets("reference").Cells(Rows.Count, 1).End(xlUp).Row ReDim List(iRow) ReDim List2(iRow) For i = 1 To iRow List(i) = Worksheets("reference").Cells(i, 1).Value List2(i) = Worksheets("reference").Cells(i, 2).Value Next i Dim lngYLine As Long Dim intXLine As Integer Dim objFind As Object Dim strAddress As String Dim strSamp As String Dim objRange As Range Dim c As Range For i = 1 To iRow Set objRange = Worksheets("data").Range("A1:A331") Set objFind = objRange.Cells.Find(List(i)) If Not objFind Is Nothing Then For Each c In objRange If c.Value = objFind Then lngYLine = objFind.Cells.Row intXLine = objFind.Cells.Column strSamp = Worksheets("data").Cells(lngYLine, 1) strSamp = Replace(strSamp, List(i), List2(i)) Worksheets("data").Cells(lngYLine, 1) = strSamp MsgBox List(i) + "は" + List2(i) + "に変更されました" Set objFind = Cells.FindNext(objFind) End If Next c Else MsgBox List(i) + "は見つかりませんでした" End If Next i End Sub

  • 二次元配列のサイズについて

    下記のプログラムにおいて、 Public 文字列格納(,) as Variant とか、 Public 文字列格納(,3) as Variant のような、二次元配列を宣言はできないでしょうか? 下記のプログラムは、A1セルに書かれた文字列を、 一文字ずつに分解してB列に転記し、 逆さにしたものを、1文字ずつにC列に転記する プログラムです。A1セルに書かれる文字列の長さは不定です。 本当の目的は、NCBI等から取得したDNAの塩基配列を入力したら、 相補鎖の塩基配列を作成したり、タンパク質に翻訳したり、 乖離エネルギーを計算したりするためのコードで、その一部を 簡単化したものです。 ===プログラムのソース=== Public 文字列格納 As Variant Public 文字列(100, 2) As Variant Sub テスト() 文字列格納 = Cells(1, 1) 長さ = Len(文字列格納) For i = 1 To 長さ 文字列(i, 1) = Mid(文字列格納, i, 1) 文字列(i, 2) = Mid(文字列格納, 長さ - i + 1, 1) Cells(i, 2) = 文字列(i, 1) Cells(i, 3) = 文字列(i, 2) Next i End Sub

  • Excel VBAで文字列の部分一致の文字列を表示

    以前、こちらで頭5文字までの一致で文字列を表示するVBAを教えて頂きました。今回はFINDなどの部分一致での文字列を表示することをしたいのですが、ご教示いただけますと幸いです。 下記はSheet1のA3に文字を5文字以内いれるとSheet2のC列からピックアップしてSheet1のA列に文字列を表示する及びSheet2のB列のデータをSheet1のC列に表示させるVBAです。 Sub Test2() Dim Ws1 As Worksheet, Ws2 As Worksheet Dim SData As String, i As Long, VRet As Variant Dim c As Range, LastRow As Long Set Ws1 = Sheets("Sheet1") Set Ws2 = Sheets("Sheet2") SData = CStr(Ws1.Range("A3").Value) If SData = "" Then Exit Sub i = 5 LastRow = Ws1.Cells(Rows.Count, "A").End(xlUp).Row If LastRow < i Then LastRow = i End If Ws1.Range(Ws1.Cells(i, "A"), Ws1.Cells(LastRow, "C")).ClearContents With Ws2 For Each c In .Range(.Cells(1, "C"), .Cells(Rows.Count, "C").End(xlUp)) VRet = InStr(1, CStr(c.Value), SData, vbTextCompare) If VRet = 1 And Len(c.Value) >= 10 Then Ws1.Cells(i, "A").Resize(1, 2).Value = c.Resize(1, 2).Value 'とりあえずSheet2のB列のデータ(C列のデータに同期したデータ)をSheet1のC列に Ws1.Cells(i, "C").Value = .Cells(c.Row, "B").Value i = i + 1 End If Next End With End Sub 宜しくお願い致します。

  • 文字列から数式に変換する標準モジュールが不安定

    文字列を数式に変換する標準モジュール「EVALUATE」の更新が不安定です エクセルシート内の文字列を数式に変換して、計算結果を返すために下記標準モジュールを登録して試すのですが うまく行ったりいかなかったり、標準モジュールが安定して機能しない原因などが分かりません。 ●現在の設定とやりたいこと (1)A1⇒=myEvalAry(B1)、B1⇒C1+D1、C1⇒2、D1⇒5 として、A1にC1+D1計算結果の7を表示させたい (2)一つのシートの中に、myEvalAry標準モジュールを数百使っている (3)一つのセルの中で、=myEvalAry(B1)+myEvalAry(B2)のように標準モジュールを複数使っているセルもある ●現在の状況 上記状態で、何かのタイミングで標準モジュールの計算結果が一気に全て正しく反映されることもあれば、 急に反映されなくなることもある。100のうち10だけ反映されることもある。 というような不安定な状態です。 しかも数量が問題かと思って、多量に登録していたmyEvalAryのセルを1つだけにして動きを確認しようとしたらまた反映 されなかったりで、全然理由が分かりません。 どこか標準モジュール内に、考慮すべき構文が漏れたりしてるのでしょうか???? 正常稼働しない理由が分かると大変ありがたいです。win7、win8、excel2003、excel2013のいずれの環境でも同様です。 /////////////////////////////////////////////////////// Function myEvalAry(ParamArray ItemR()) As Variant Dim re As Variant Dim strTmp As String Dim varR As Variant Dim i As Variant, j As Variant strTmp = "" varR = ItemR() For Each i In varR If IsArray(i) Then '引数が配列の場合 For Each j In i If IsNumeric(j) Then re = CStr(j) Else re = j End If strTmp = strTmp & re Next Else '引数が配列以外 If IsNumeric(i) Then re = CStr(i) Else re = i End If strTmp = strTmp & re End If Next myEvalAry = Application.Evaluate(strTmp) End Function

  • (VBA) 配列の文字列を昇順で並べ替えたい

    タイトルの通り、配列に格納したファイル名を昇順に並べ替えたいのですが、期待通りに動作しません。 内部コード(ユニコード?)順には並んでいるようですが、エクスプローラの名前順と同等にはなりません。 どのようにしたら、配列のファイル名をエクスプローラと同じように並べ替えできますか? (テストに使用したコード) Public Sub Test1() Dim FileNames() As String Dim WSH As Object Dim MyPathName As String Dim MyFileName As String Dim i As Integer Dim j As Integer '処理対象フォルダを指定 Set WSH = CreateObject("WScript.Shell") MyPathName = WSH.SpecialFolders("MyDocuments") Set WSH = Nothing i = 0 MyFileName = Dir(MyPathName & "\" & "*.*") If MyFileName = "" Then MsgBox "対象ファイルが1つも見つかりません。", , "処理終了" Exit Sub End If 'ファイル一覧を配列に格納 Do Until MyFileName = "" i = i + 1 ReDim Preserve FileNames(1 To i) FileNames(i) = MyFileName MyFileName = Dir Loop '配列を並べ替える For i = 1 To UBound(FileNames) - 1 For j = i To UBound(FileNames) If FileNames(i) > FileNames(j) Then MyFileName = FileNames(i) FileNames(i) = FileNames(j) FileNames(j) = MyFileName End If Next j Next i End Sub ※以降の処理は、Excel で処理するか Access で処理するかまだ決めていません。  (投稿文字数の関係で詳細は省略)

  • VBA バイナリ―から文字列にする方法

    この度はお世話になります。 現在、バイナリ―ファイル(xxxx.bin)をVBAで読み込み、バイナリ―データを文字列化して、エクセルで解析できるようなシートを作っています。 バイナリ―ファイルの中身が31 39 32 31 ・・・・・となっていたら、31393231・・・と文字列化にしたいです。 そこで、自分でプログラムを考えてみたのですが、バイナリ―が 01 などの場合、など“1”として読み込まれて、“0”が入らず、ずれてしまいます。 Sub 電文解析プログラム() Dim Deciphering_file As Variant '読み込みファイル Dim buf As Byte '1バイト格納 Dim fLen As Long 'ファイルサイズ Dim TEMP(1) As String ' Dim S_JIS As String '文字コード(2バイト) Dim str As String '文字列データ Dim i As Long Deciphering_file = Application.GetOpenFilename("BINファイル(*.bin),*.bin") fLen = FileLen(Deciphering_file) Open Deciphering_file For Binary As #1 For i = 1 To fLen Get #1, i, buf S_JIS = Hex(buf) If buf = 0 Then S_JIS = "00" End If TEMP(0) = Mid(S_JIS, 1, 1) TEMP(1) = Mid(S_JIS, 2, 1) str = myChr & TEMP(0) & TEMP(1) Next i End Sub ホントは3行くらいで済みそうな気がするんですが、あまりプログラミングをやったことありません。なので、すみませんがご教授お願いいたします。

  • 文字列を配列に…。

    VBはまだ始めたばかりで本当に初歩的なことかもしれませんが分かる方がおられたら是非教えて下さい。 text1.textから取り込んだ文字列を”一文字ずつ”(Dim a(100) as stringで宣言した)配列に格納したいのですがどうしたらいいのでしょうか?? <例>text1.textに"abc"と入力しcommandbuttonを押すとa(0)に"a"がa(1)に"b"がa(2)に"c"が格納されるといったかんじです。 ちなみに今私がしたいのはtext1.textに、ある文字列を入れその文字列を文字コードに変換しそれを一文字分ずつ+1してまたそのコードを文字に直しtext2.textに出力するというものです(ようは簡単な暗号化ですね)。 私はAscとChrコマンドを利用して1文字ずつコードをずらしていこうと思っているのですが、他に良い方法などあるのでしょうか?? 本当に初心者でどのようにしらたよいのか分かりません…。 どなたか分かりやすく教えていただけませんでしょうか?? お願いします。

  • Excel 文字列を区切る VBA 質問

    A列にスペース区切りのデータがあります これをC列 D列 に分けて表示したいのですが A列のデータが不規則(個数がバラバラ 空白もある) と、なった場合 なかなか上手くいきません C列以降は使用可能です(空いてます) その道の方 お助けたください 元のVBAは Sub Sample3() Dim i As Long, tmp As Variant For i = 2 To 22 tmp = Split(Cells(i, 1), " ") Cells(i, 2) = tmp(0) Cells(i, 3) = tmp(1) Next i End Sub です お手数ですが宜しく お願いします

専門家に質問してみよう