質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

Q&A

解決済

1回答

4016閲覧

VBA Dictionaryオブジェクトの質問

cd987456

総合スコア33

VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

0グッド

0クリップ

投稿2017/05/01 06:04

Dictionaryオブジェクトを使って割り付けをしています。
2つのシートがあります。
『抽出結果』シートと『条件』シートです。
『条件』シートのA列、B列、c列にデータが入っています。
『抽出結果』シートのA列、B列にデータが入っています。

やりたいことは、
『抽出結果』シートのA列とB列のデータと『条件』シートのA列とB列のデータが一致したら
『条件』シートのC列のデータを『抽出結果』シートのC列に記載する。

先日このサイトで教えてもらったコードを自分なりに変更して書いてみました。

Public Sub dic_04_2() Dim mydic As Object Dim i As Long Dim ary1 Dim ary2(2 To 180000, 0) As Long Dim maxrow As Long Application.ScreenUpdating = False Application.EnableEvents = False Set mydic = CreateObject("Scripting.Dictionary") With Sheets("条件") maxrow = .Cells(Rows.Count, 1).End(xlUp).Row ary1 = .Range(.Cells(2, 1), .Cells(maxrow, 3)) For i = maxrow To 2 Step -1 mydic(ary1(i - 1, 1) & "," & ary1(i - 1, 2)) = ary1(i - 1, 3) Next i End With With Sheets("抽出結果") maxrow = .Cells(Rows.Count, 1).End(xlUp).Row For i = 2 To maxrow ary2(i, 0) = mydic.Item(.Cells(i, 1).Value & "," & .Cells(i, 2).Value) Next .Range(.Cells(2, 3), .Cells(maxrow, 3)) = ary2 End With Set mydic = Nothing Application.EnableEvents = True Application.ScreenUpdating = True End Sub

エラーにはならないですが、2つの条件に一致するように上手く処理されません。
修正点を教えて下さい。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

当方のサンプルでは、提示のコードで問題なく結果が書き込まれました。

具体的に、どのようにうまくいかないのでしょうか。
エラーがでるなら、そのエラー内容、
結果が想定と違うなら、サンプルのデータとその結果を提示してもらえませんか。

ちなみに、
Dim ary2(2 To 180000, 0) As Long
は、私のサンプルが参照するセルが数値だったので、Long にしましたが、
文字列だったら、String にするなどそちらのデータ型にあわせてくださいね。

動作検証

質問のコード、さらに下記のチューンナップコード、
どちらでも下図のように想定の結果となりました。

イメージ説明

ダミーのデータでなく、実際に想定外の結果になるデータを提示できませんか。

さらにチューンナップ

コードを見直してみたら、"抽出結果"シートでセル毎に読み込みしていたので、それも 配列 に一気に読み込むようにしてみました。これで、前回よりさらに倍以上高速化できました。

あと、参照結果の書き込み用の配列も動的配列にして、配列のサイズをデータ数に合わせて、無駄にメモリを使用しないようにしました。

Public Sub dic_04_4() Dim mydic As Object Dim i As Long Dim ary1() Dim ary2() '動的配列として宣言 Dim maxrow As Long Application.ScreenUpdating = False Application.EnableEvents = False Set mydic = CreateObject("Scripting.Dictionary") With Sheets("条件") maxrow = .Cells(Rows.Count, 1).End(xlUp).Row ary1 = .Range(.Cells(2, 1), .Cells(maxrow, 3)).Value For i = UBound(ary1) To LBound(ary1) Step -1 mydic(ary1(i, 1) & "," & ary1(i, 2)) = ary1(i, 3) Next i End With With Sheets("抽出結果") maxrow = .Cells(Rows.Count, 1).End(xlUp).Row ReDim ary2(2 To maxrow, 0) '動的配列のサイズを宣言 Erase ary1 '配列の初期化 ary1 = .Range(.Cells(2, 1), .Cells(maxrow, 2)).Value For i = LBound(ary1) To UBound(ary1) ary2(i + 1, 0) = mydic.Item(ary1(i, 1) & "," & ary1(i, 2)) Next .Range(.Cells(2, 3), .Cells(maxrow, 3)).Value = ary2 End With Set mydic = Nothing Application.EnableEvents = True Application.ScreenUpdating = True End Sub

投稿2017/05/01 07:58

編集2017/05/01 23:08
hatena19

総合スコア33715

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

cd987456

2017/05/01 09:12

回答ありがとうございます。 条件シートの内容が A列が取引先、B列が商品名、C列が納期 となっています。 A列とB列のデータが重複していることはありません。 例えば、条件シートに以下のデータがあったとします。  取引先A社  テレビ  2017/5/1  取引先B社  テレビ  2017/4/3 抽出結果シートには  取引先A社  テレビ  2017/4/3  取引先B社  テレビ  2017/4/3 と表示されます。※エラーは出ません。 ★抽出結果シートは  取引先A社  テレビ  2017/5/1  取引先B社  テレビ  2017/4/3 となってほしいのですが、上手くいきません。 条件シート、抽出結果シート共に2列の条件が一致した時のデータを返してほしいです。
cd987456

2017/05/02 01:44

回答ありがとうございます。 上手く処理できていました。 検証データに余分なデータが混じっていました。 データの重複を監視するプログラムも入れた方がよかったです。 すいませんでした。 チューンナップして頂いたコードでさらに早く処理出来ました。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問