いつもお世話になっております。
下記のコードは何年か前にこのサイトで
頂いたコードですが、実行すると
うまく抽出できていないように思います。
わかる方おしえてくれませんでしょうか
画像添付しました。
よろしくお願いいたします。
Sub 商品検索()
Dim dicT As Object
Dim maxrow1 As Long
Dim maxrow2 As Long
Dim sh1 As Worksheet
Dim sh2 As Worksheet
Dim row1 As Long
Dim row2 As Long
Dim key As Variant
Dim t1 As Variant
Dim t2 As Variant
Dim i As Long
Dim sh3 As Worksheet
Set sh3 = Worksheets("Sheet5")
Dim sname() As Variant '
Dim sdate() As Variant '
Dim price() As Variant '
Dim ctr As Long '
Set dicT = CreateObject("Scripting.Dictionary") '
Set sh1 = Worksheets("Sheet1")
Set sh2 = Worksheets("Sheet5")
maxrow1 = sh1.Cells(Rows.Count, 1).End(xlUp).Row '
maxrow2 = sh2.Cells(Rows.Count, 1).End(xlUp).Row '
t1 = Timer
For row1 = 2 To maxrow1
key = sh1.Cells(row1, "A").Value
If key <> "" Then
dicT(key) = row1 '
End If
Next
ctr = 0
For row2 = 2 To maxrow2
key = sh2.Cells(row2, "A").Value
ReDim Preserve sname(ctr)
ReDim Preserve sdate(ctr)
ReDim Preserve price(ctr)
If dicT.exists(key) = True Then
row1 = dicT(key)
sname(ctr) = sh1.Cells(row1, "B").Value '
sdate(ctr) = sh1.Cells(row1, "C").Value '
price(ctr) = sh1.Cells(row1, "D").Value '
Else
sname(ctr) = ""
sdate(ctr) = ""
price(ctr) = ""
End If
ctr = ctr + 1
Next
For i = 0 To ctr - 1
sh3.Cells(i + 1, 5).Value = i
sh3.Cells(i + 1, 2).Value = sname(i)
sh3.Cells(i + 1, 3).Value = sdate(i)
sh3.Cells(i + 1, 4).Value = price(i)
Next
End Sub
No.1ベストアンサー
- 回答日時:
こんばんは
なんだかわざわざ複雑になるように作成されている様なので、よくわかりませんけれど・・・
Sheet1のA列の値は重複することがないと保証されているのでしょうか?
(ご提示のコードは、その仮定のもとに作成されているようなので…)
であるなら、Dictionaryも配列も不要だと思われます。
以下は、その前提での回答です。
ご提示のコードの内容は、Sheet5のA列の各行について、
・A列の値を、Sheet1のA列から検索
・ヒットした行のデータをコピペ
(ヒットしなければ空白に)
という、単純なループ処理だけで足りるものと思われます。
>うまく抽出できていないように思います。
原因は、ご提示のコードで、
配列に(一旦)記録する際の添え字(=ctr)が、行数(=row2)とはずれていますが、出力する際に、それをきちんと調整・反映していないので、Sheet5で行の位置がずれてしまっているだけだと思われます。
同じ行のデータを書き写すだけなので、わざわざ値を配列に記憶しなくても、直接記入してしまえば配列は不要になります。
また、元データの総数は事前にmaxrow2で分かっているので、ループの中で毎回ReDim Preserveを行うのも無駄と言えます。
Dictionaryは検索値に合致する行を求めるのに利用していますが、keyに当たる値はSheet1のA列に並んでいるので、直接そこからFindなどで探してしまえば、Dictionaryそのものも不要になります。
処理速度を上げるために、メモリ上で処理したいような場合は、最初に
data = Worksheets("Sheet1").Range("A1:D" & maxrow1).Value
としてメモリに取り込んでしまい、後はメモリ上で全て処理してしまうという方法も考えられます。
まったく別の発想で処理しても良いのなら・・・
ご提示のコードの内容は、通常のシートでのVLOOKUP関数利用の処理と全く同じ内容ですので、
・Sheet5の範囲に関数をセット
・値をペーストで固定値に変換
というロジックにしてしまえば、同じ処理を10行程度の記述で済ますことも可能であろうと想像します。
(実質的な計算を、ほとんどエクセルに行ってもらう方法とも言えます)
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) VBA 別ブックからの転記の高速化について VBA 別ブックからの転記の高速化についてご教授下さい。 19 2022/07/26 13:07
- Visual Basic(VBA) VBAコードが作動せず、どこに問題があるのか教えて下さい。 3 2023/06/13 13:20
- Visual Basic(VBA) 【VBA】特定のワードが入っている行全体を塗りつぶしたい 4 2022/04/20 15:22
- Visual Basic(VBA) ExcelVBAで、index、match関数を使用して、指定範囲に出力したい 3 2022/10/18 21:53
- Visual Basic(VBA) フォルダの場所を可変にしたいです(マクロ) 4 2023/05/11 10:00
- Excel(エクセル) VBAの指示の内容 昨日こちらでご教示頂いたのですが初心者な為、一つ一つの指示が何をやっているのかわ 2 2022/10/25 18:08
- Visual Basic(VBA) VBAで質問ですが、皆さんはどの様に導き出しているのでしょうか? 6 2022/05/03 21:53
- Visual Basic(VBA) vba 重複データ合算 5 2023/07/05 18:55
- Visual Basic(VBA) VBA処理追加 こちらでご教示頂いたのですが回答完了させてしまいましたのでこちらからまた質問させてく 2 2022/10/27 09:57
- Visual Basic(VBA) マクロで最終行を取得したい 4 2023/05/28 12:14
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
VBA 変数名に変数を使用したい。
-
DBから取得した値を配列へ代入する
-
C#でbyte配列から画像を表示さ...
-
構造体配列の一部初期化!!!
-
エクセルでXY座標に並べられた...
-
VB6で、一次元配列と二次元配列...
-
定数配列の書き方
-
配列の中の最大値とそのインデ...
-
オブジェクト名を変数で参照で...
-
配列の要素がすべてカラかどう...
-
vba フィルター 複数条件 3つ以...
-
Dir関数で読み取り順を操作でき...
-
ActiveReports(アクティブレポ...
-
VB.NETの配列にExcelから読み込...
-
VBで配列に格納されているデー...
-
8bitインデックス画像の入出力方法
-
Redim とEraseの違いは?
-
VBでの配列をEXCELに出力する方法
-
EXCEL VBA 配列デー...
-
Excel2010のinputboxで複数デー...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
VBA 変数名に変数を使用したい。
-
vba フィルター 複数条件 3つ以...
-
C#でbyte配列から画像を表示さ...
-
Excel2010のinputboxで複数デー...
-
エクセルでXY座標に並べられた...
-
構造体配列の特定のメンバーをF...
-
定数配列の書き方
-
コンボボックスのインデックス...
-
OutOfMemoryExceptionの回避策...
-
Dir関数で読み取り順を操作でき...
-
CheckBoxの配列化
-
構造体配列内の文字列検索のよ...
-
COBOLの基本的な事なので...
-
Redim とEraseの違いは?
-
VBAで配列引数を値渡しできない...
-
2次元配列の初期値
-
配列の中の最大値とそのインデ...
-
大量の変数を定義するにはどう...
-
VB6からの移行したいけど、VB.N...
-
VB6のメモリ解放に関して
おすすめ情報