Excel2010VBAでの検索の高速化

このQ&Aのポイント
  • Excel2010VBAでシート1のデータから変数「日時」、「データ1」、「データ2」、「データ3」、「データ4」、「データ5」に格納し、変数「日時」とシート2の「日時」の行に一致するセルに変数「データ1」、「データ2」、「データ3」、「データ4」、「データ5」を入力するプログラムです。
  • 検索を高速化する方法はありますか?セルに関数は使用していません。
  • 質問文章の内容はExcel2010VBAでの検索の高速化方法についてです。ExcelのVBAを使用して、シート1のデータから変数に格納し、シート2のデータと比較して対応する行にデータを入力するプログラムです。検索を高速化する方法についてのアドバイスを頂きたいです。
回答を見る
  • ベストアンサー

Excel2010VBAの検索の高速化

Excel2010VBAで、シート1のデータから変数「日時(a)」、「 データ1(a)」、「データ2(a)」、「データ3(a)」、「データ4(a)」、「データ5(a)」に格納し、変数「日時(a)」とシート2の「日時」の行に一致するセルに変数「 データ1(a)」、「データ2(a)」、「データ3(a)」、「データ4(a)」、「データ5(a)」を入力するというプログラムです。 ここで、検索を高速化する方法はあるでしょうか?(セルに関数は使用していません。) A   B   C  D     E         F       年   月  日  時刻  日時       データ1   2011  1  2   23:01  2011.1.2 23:01 1       ~ ~ G     H      I     J データ2  データ3 データ4 データ5 2      3     4     24 ~ ~ Dim a As Long Dim 年(1 To 9999999) As Integer Dim 月(1 To 9999999) As Integer Dim 日(1 To 9999999) As Integer Dim 時刻(1 To 9999999) As Date Dim データ1(1 To 9999999) Dim データ2(1 To 9999999) Dim データ3(1 To 9999999) Dim データ4(1 To 9999999) Dim データ5(1 To 9999999) As Integer Dim 日時(1 To 999999) As String, 範囲 As Range, 範囲文字列 As String, 縦位置 As Long a = 1 With Workbooks("ブック.xlsm").Worksheets("シート1") Do 日時(a) = .Cells(a + 1, 5) データ1(a) = .Cells(a + 1, 6) データ2(a) = .Cells(a + 1, 7) データ3(a) = .Cells(a + 1, 8) データ4(a) = .Cells(a + 1, 9) If .Cells(a + 1, 10) <> "" Then データ5(a) = .Cells(a + 1, 10) End If a = a + 1 Loop Until .Cells(a + 1, 1) = "" End With a = 1 With Workbooks("ブック.xlsm").Worksheets("シート2") Do Set 範囲 = .Range(Cells(2, 5), Cells(Rows.Count, 5)).Find(What:=日時(a), LookIn:=xlValues, lookat:=xlWhole) If Not 範囲 Is Nothing Then 範囲文字列 = 範囲.Address(ReferenceStyle:=xlR1C1) 縦位置 = Mid(範囲文字列, 2, InStr(2, 範囲文字列, "C") - 2) .Cells(縦位置, 6) = データ1(a) .Cells(縦位置, 7) = データ2(a) .Cells(縦位置, 8) = データ3(a) .Cells(縦位置, 9) = データ4(a) If データ5(a) <> 0 Then .Cells(縦位置, 10) = データ5(a) End If End If a = a + 1 Loop Until 日時(a) = "" End With 回答よろしくお願いします。

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

  • ベストアンサー
  • ki-aaa
  • ベストアンサー率49% (105/213)
回答No.2

'シート1のデータの変数「日時(a)」は文字列であると仮定 'また、日時(a)は同じ物がないものとする Sub xxx3() Dim myDic As Object Dim S1_v, S2_v Dim i As Long, n As Long, j As Long 'With Workbooks("ブック.xlsm").Worksheets("シート1") With Sheets("Sheet1") j = .Range("E" & Rows.Count).End(xlUp).Row S1_v = .Range("E1").Resize(j, 6).Value '対象範囲を配列に End With 'With Workbooks("ブック.xlsm").Worksheets("シート2") With Sheets("Sheet2") j = .Range("E" & Rows.Count).End(xlUp).Row S2_v = .Range("E1").Resize(j, 6).Value '対象範囲を配列に End With Set myDic = CreateObject("Scripting.Dictionary") For i = 2 To UBound(S1_v) myDic.Add S1_v(i, 1), i 'keyに追加、itemにi Next i For i = 2 To UBound(S2_v) If myDic.exists(S2_v(i, 1)) Then j = myDic.Item(S2_v(i, 1)) S2_v(i, 2) = S1_v(j, 2) S2_v(i, 3) = S1_v(j, 3) S2_v(i, 4) = S1_v(j, 4) S2_v(i, 5) = S1_v(j, 5) S2_v(i, 6) = S1_v(j, 6) Else 'マッチしなかったときの処理 End If Next 'With Workbooks("ブック.xlsm").Worksheets("シート2") With Sheets("Sheet2") j = .Range("E" & Rows.Count).End(xlUp).Row .Range("E1").Resize(j, 6).Value = S2_v End With Set myDic = Nothing Erase S1_v, S2_v End Sub

miya_HN
質問者

お礼

回答ありがとうございます。 すいませんが、このプログラムを見てもよく分からないのですが・・・。

miya_HN
質問者

補足

プログラムの内容はよく分からないのですが、そのままコピーさせてもらいました。 自分が作ったプログラムとは比べものにならないほど非常に高速で処理できました。 ありがとうございました。

その他の回答 (1)

  • CC_T
  • ベストアンサー率47% (1038/2201)
回答No.1

検索の判定を見るに、データ1の日時について同日時で重複する行はないのですね? データ2も同じく重複はない? であれば、両データとも日時順に並べれば過去分は検索する必要もなく、 後に行くほど処理時間が短縮されるでしょう。 配列に読み込む必要すらない。 もしデータの日時はバラバラのままで残したいのであれば、別シートにコピーすればいいし。 1)両シートとも日時順にデータを並べる 2)データ2の処理行で日時を取得する 3)データ1の日時セルを上から下に見て、2で取得した日時と比較する  2で取得した日時と一致すれば、データをシート2の各セルに記入する 4)データ記入終了、あるいはデータ1の日時が2で取得した日時を超えた場合は  データ2の処理行を次行にし、3で検索中断したデータ1の処理行から比較を再開する。

miya_HN
質問者

お礼

回答ありがとうございます。 日時を検索しており、その点で重複している部分は一切ありません。 <両データとも日時順に並べれば過去分は検索する必要もなく、 後に行くほど処理時間が短縮されるでしょう。 最初から日時順には並べられているのですが抜けている部分があって、それを抜けている部分はそのまま空白で、その日時のデータがある場合はそこにデータを入力するというプログラムです。 でも、日時順に並べるというのが高速化するポイントのようですね。 ありがとうございました。

関連するQ&A

  • Excel VBAで検索(Win2000 Excel2000)

    現在、下記のようなコードを書いています。データテーブルの縦と横の検索値を探してその列数と行数を返したいのですが、下記の Sub検索1 と Sub検索2 を1つのSubで実行させるにはどうしたらよいのでしょうか?よろしくお願い致します。 ----------------------------------------- Sub 検索1() Worksheets("Data").Activate Dim x As Integer For x = 3 To 22 If Cells(2, x).Value >= 12 Then MsgBox x Exit Sub End If Next MsgBox "見つかりません" End Sub --------------------------------------------- Sub 検索2() Worksheets("Data").Activate Dim i As Integer For i = 4 To 42 If Cells(i, 2).Value = "A" Then MsgBox i Exit Sub End If Next MsgBox "見つかりません" End Sub

  • VBAでの質問

    お世話になります。 下記の記述で、「←」の矢印の記述で、 Cells.(5,2)がブランクでなければ、 「→」から進めたいのですが、 どの様に記述すれば宜しいでしょうか ご教示お願いします。 Sub 表記入() Dim Data As Range Dim i As Integer Dim j As Integer Dim k As Integer Set Data = Sheets("集計").Range("A2").CurrentRegion j = 16 k = 0 With Sheets("表") For i = 3 To Data.Rows.Count If Data.Cells(i, 51) <> "" Then .Cells(5, 2) = Data.Cells(i, 3)  ← .Cells(5, 7) = Data.Cells(i, 4) → .Cells(j, 2) = Data.Cells(i, 10) .Cells(j, 6) = Data.Cells(i, 11) & Data.Cells(i, 12) .Cells(j, 14) = Data.Cells(i, 51) Else End If k = k + 1 If k = 10 Then j = j + 18 k = 0 Else j = j + 1 End If End If Next i End With End Sub

  • データ検索ネスト Excel VBA

    excel2003でデータ検索の処理をするというマクロをVBAで作成したいのですが、うまく動作しません。自作のVBAを記載してみましたので何が原因なのか教えてください。初心者です、よろしくお願いします。 Sub データ検索() Dim i As Integer, j As Integer, k As Integer, l As Integer Dim myRange As Range Dim IngLastrow As Long IngLastrow = Range("A65536").End(xlUp).Row For i = 3 To IngLastrow For j = 3 To 25 For k = 8 To 53 For l = 3 To 9 Set myRange = Worksheets("データベース").Cells(i, "o").Find(what:=Worksheets("コード").Cells(j, "o").Value, _ LookIn:=xlValues) If Not myRange Is Nothing Then Worksheets("予定").Cells(k, l).Value = myRange.Offset(, -12).Value End If Next l Next k Next j Next i End Sub

  • VBAで行列を作る方法

    次のようなプログラミングで1,0,-1の要素で作られる3×3行列を全通り調べています。 この場合3の9乗通り調べることができます。 これを4×4や5×5行列など数を大きくして調べたいのですが、このプログラムを配列を使うなどして 簡単にできる方法を教えてください。 よろしくおねがいします。 Sub test() Dim a As Integer '行 Dim b As Integer '列 Dim c As Integer, i As Integer, j As Integer, d As Integer, e As Integer Dim 内積 As Integer, step As Integer Dim f As Integer, g As Integer, h As Integer, l As Integer, m As Integer, n As Integer, k As Integer, x As Integer Dim sum As Integer, total As Integer Dim aa As Integer, aaa As Integer, aaaa As Integer, bb As Integer, bbb As Integer, bbbb As Integer a = 3 '行 b = 3 '列 c = 0 内積 = 0 con = 0 sum = 0 tatal = 0 aa = 0 aaa = 0 aaaa = 0 bb = 0 bbb = 0 bbbb = 0 x = 0 For n = 0 To 2 For m = 0 To 2 For l = 0 To 2 For k = 0 To 2 For h = 0 To 2 For g = 0 To 2 For f = 0 To 2 For e = 0 To 2 For d = 0 To 2 '要素がすべて1 For i = 1 To a For j = 1 To b Cells(i, j) = 1 Next j Next i If bbbb = 1 Then Cells(a - 2, b - 2) = 0 ElseIf bbbb = 2 Then Cells(a - 2, b - 2) = -1 End If If bbb = 1 Then Cells(a - 1, b - 2) = 0 ElseIf bbb = 2 Then Cells(a - 1, b - 2) = -1 End If If bb = 1 Then Cells(a, b - 2) = 0 ElseIf bb = 2 Then Cells(a, b - 2) = -1 End If If aaaa = 1 Then Cells(a - 2, b - 1) = 0 ElseIf aaaa = 2 Then Cells(a - 2, b - 1) = -1 End If If aaa = 1 Then Cells(a - 1, b - 1) = 0 ElseIf aaa = 2 Then Cells(a - 1, b - 1) = -1 End If If aa = 1 Then Cells(a, b - 1) = 0 ElseIf aa = 2 Then Cells(a, b - 1) = -1 End If If total = 1 Then Cells(a - 2, b) = 0 ElseIf total = 2 Then Cells(a - 2, b) = -1 End If If sum = 1 Then Cells(a - 1, b) = 0 ElseIf sum = 2 Then Cells(a - 1, b) = -1 End If If con = 1 Then Cells(a, b) = 0 ElseIf con = 2 Then Cells(a, b) = -1 End If con = con + 1 Next d con = 0 sum = sum + 1 Next e sum = 0 total = total + 1 Next f total = 0 aa = aa + 1 Next g aa= 0 aaa = aaa + 1 Next h aaa = 0 aaaa = aaaa + 1 Next k aaaa = 0 bb = bb + 1 Next l bb = 0 bbb = bbb + 1 Next m bbb = 0 bbbb = bbbb + 1 Next n End Sub

  • VBAの検索について

    Excelシートに表の一覧があり、項目(5行目)のところでウィンドウの固定をしています。 検索したいNo.をセル(G2)に入力し、コマンドボタンをクリックします。 セル(G2)に入力されたNo.とA列に入力されているNo.が一致する行を検索し、一致した行(複数はない)を項目の下までスクロールさせた状態で表示したいと思っています。 検索までは下記プログラムでできているのですが、一致した行を項目の下までスクロールさせた状態で表示するのはどうしたらよいのでしょうか。 ************************************************************* Private Sub CommandButton1_Click()   Dim myClm As Integer, myFind As Integer, myRow As Integer   myClm = 1 'A列   If Sheet1.Range("G2") = "" Then Exit Sub   myFind = Sheet1.Range("G2")   For myRow = Cells(Rows.Count, myClm).End(xlUp).Row To 1 Step -1    With Cells(myRow, myClm)     If .Value Like myFind Then       .Activate       Exit For     End If    End With    Next End Sub ************************************************************

  • VBAのシートイベントで教えてください

    シートのN4以下で、既に同じ番号があれば「既に同じ番号があります」 と表示するようにしたく、下のように書きましたが、肝心な部分 の、どのように同じ番号をみつけるようにすのかわかりませんでした。 教えていただけないでしょうか。宜しくお願いします。 Private Sub worksheet_change(ByVal target As Range) Dim 範囲左 As Integer Dim 範囲右 As Integer Dim 範囲上 As Integer 範囲左 = 1 範囲右 = 16 範囲上 = 4 With target 'if '指定した範囲の列Nに既に同じ番号や文字列があれば MsgBox "既に同じ番号があります。" End If End With End Sub

  • ■Excel VBA グローバルな書き方■

    Sub 跳ね返る() Dim time1 As Integer, time As Integer Dim X As Integer, Y As Integer Dim hyouji As String, yoko As String, tate As String hyouji = "●" X = 1 Y = 1 yoko = "右" tate = "上" Do Cells(X, Y).Value = hyouji '★ For time1 = 0 To 1000 For time2 = 0 To 1000 Next Next Cells(X, Y).Value = hyouji For time1 = 0 To 1000 For time2 = 0 To 1000 Next Next          '★ If yoko = "右" Then Y = Y + 1 Else Y = Y - 1 End If If Y = 30 Then yoko = "左" ElseIf Y = 1 Then yoko = "右" End If If tate = "上" Then X = X + 1 Else X = X - 1 End If If X = 20 Then tate = "下" ElseIf X = 1 Then tate = "上" End If Loop End Sub ************************************ 上記のプログラムを Dim a() EndSub Dim b() EndSub Dim c() endSub Sub main() a b c EndSub のような、mainを動かせばabcも動く グローバルな(ローカルでもいいのですが) プログラムにするにはどうしたらいいですか? ★印から★印までの間の動作が同じような動作で 二つあるので、それを一つにまとめ 尚且つ、表示と時間稼ぎと表示削除の 3つの動作を分けた形にしたいです。 質問が下手で申し訳ありません…;;

  • Excel2010VBA:Find、日付形式の一致

    Excel2010VBAでワークシートのE列 (関数:=IF(AND(A2<>"",B2<>"",C2<>"",D2<>""),DATE(A2,B2,C2)+D2,"")) とマクロの変数「日時1(a)」が一致すると処理を行うプログラムを作りました。(この場合一致するのは「2011/1/2 23:01」です。) E列とマクロの変数「日時1(a)」は両方とも日付形式で、「2011/1/2 23:01」で一致するはずなのですが変数「範囲」が「Nothing」で一致しません。 ■ワークシート ------------------------------------------------------------------------- A    B C D    E 2011  1 2 23:01  =IF(AND(A2<>"",B2<>"",C2<>"",D2<>""),DATE(A2,B2,C2)+D2,"") ------------------------------------------------------------------------- ■コード ------------------------------------------------------------------------- Dim 日時1(1 To 999999) As Date, 範囲 As Range With Workbooks("ブック.xlsm").Worksheets("シート") Do Set 範囲 = .Range(Cells(2, 5), Cells(527041, 5)).Find(What:=日時1(a)) If Not 範囲 Is Nothing Then ~ End If ~ ------------------------------------------------------------------------- これを一致させるためにはどうしたらいいのでしょうか? 回答よろしくお願いします。

  • VBA 値、セル操作

    お世話になります [現状] 実行させると 1列目を残して2列づつ処理をさせています Sub Macro1() Dim idxR, idxC, ptr As Integer Dim ws As Worksheet Set ws = ActiveSheet Worksheets.Add after:=ws ptr = 2 With ws .Rows(1).Copy Destination:=Range("A1") For idxR = 2 To .Range("A65536").End(xlUp).Row Cells(ptr, "A").Value = .Cells(idxR, "A").Value For idxC = 2 To 255 Step 2 If .Cells(idxR, idxC) = "" Then Exit For Else .Cells(idxR, idxC).Resize(1, 2).Copy Destination:=Cells(ptr, "B") ptr = ptr + 1 End If Next idxC Next idxR End With End Sub [判らないこと] 前7列を残して(A:G) 8列目から(H列)より9列づつ処理をさせたいのですが判らなく大変困っております。 どなたかご教授よろしくお願いします。

  • VBA 時間の足し算

    windowsは7、Excelは2013を使用しています。 下記のマクロで、Q列のキーワードを基に、 Q列=H列の時に、C列の時間(表記は、1:00:00)をnに格納していき、 時間の合計を、S列に入る様にしていますが、 C列の値が、0:30:00や0:15:00などの場合、 S列に入る値が 0.291666666666667 とかに小数点以下の値になってしまいます。 例えば、1:00:00+0:30:00+0:45:00=2:15という値が帰ってくるようにするにはどうしらいいのか教えて下さい。 あと、もし合計が24以上になった場合、25や26などの値になる様にもしたいです。 よろしくお願い致します。 -------------------------------------- Sub test() Dim h As Integer Dim q As Integer Dim n As Variant Dim maxRow As Integer maxRow = Range("A65536").End(xlUp).Row For q = 2 To 10 n = 0 For h = 2 To maxRow If Cells(q, 17) = Cells(h, 8) Then n = n + Cells(h, 3).Value End If Next h Cells(q, 19).Value = n Next q

専門家に質問してみよう