プロが教えるわが家の防犯対策術!

EXCEL VBA 超初心者です。
以下のマクロを作成しました。VLOOKUPを使って、SHEET2にあるデータから、同じ№であるなら、SHEET1のE列に売上を持ってくるようにしたはずなのですが、一部うまく作動できずに困っています。
E17の黄色く塗りつぶした箇所ですが、SHEET2に№1523のデータがないので、0になるはずが、何故か№1515の値を持ってきてしまいます。
以下のマクロを実行した後、F列にVLOOKUPの関数を当ててみたところ、発覚しました。
E15やE22の緑の箇所は、データがないので、0になっているのでOKなのに、何故一部おかしい数値をもってくるのかわかりません。300くらいのデータの内、10件くらいは、おかしい数値をもってきてしまっており、結局VLOOKUPの関数を後から使って、データを修正するという手間になってしまっています。
マクロのどこがおかしいのでしょうか?
On Error Resume Nextの使い方が間違っていますか?
VLOOKUPでFALSEにしてあるのに訳が分からずおて上げ状態です。

わかりにくくて申し訳ありませんが、どなたか教えてください。
どうぞ宜しくお願い致します。

Sub 売上マクロ()

Dim i As Long
Dim Uriage As Long: Uriage = 0
Dim MyNum As Long
Dim MyData As Range

Set MyData = Worksheets(2).Range("A1").CurrentRegion

For i = 2 To Worksheets(1).Range("A1").End(xlDown).Row

MyNum = Worksheets(1).Cells(i, 3).Value

On Error Resume Next
Uriage = Application.WorksheetFunction.VLookup(MyNum, MyData, 3, False)
On Error GoTo 0
Worksheets(1).Cells(i, 5).Value = Uriage

Next i

End Sub

「EXCEL VBAでVLOOKUPを実行」の質問画像

A 回答 (3件)

本マクロでの状態ではVLOOKUPでエラー発生時(#N/Aのケース)で、そのまま続行しています。


そうすると、エラー発生時、Uriageにはなにもセットされない為、前回の値が残ります。
VLOOKUPの直前でUriageをクリアしてください。
----------------------------------
On Error Resume Next
Uriage = 0 '・・・①
Uriage = Application.WorksheetFunction.VLookup(MyNum, MyData, 3, False)
On Error GoTo 0
----------------------------------
①を追加してください。
    • good
    • 0
この回答へのお礼

丁寧に教えてくださりありがとうございます。
間違いの理由がわかり、納得して先に進めます。
①を追加して上手くいくことを確認しました。
実際は、VLOOKUPを複数回使うので、この方法でマクロを修正しようと思います。
本当にありがとうございました。
業務が楽しくなりそうです。

お礼日時:2017/03/25 17:36

こんにちは!



通常のワークシート関数のようにIF関数を使ってエラー処理をすればよいと思います。

Sub 売上マクロ()

Dim i As Long
Dim Uriage As Long: Uriage = 0
Dim MyNum As Long
Dim MyData As Range

Set MyData = Worksheets(2).Range("A1").CurrentRegion
For i = 2 To Worksheets(1).Range("A1").End(xlDown).Row
MyNum = Worksheets(1).Cells(i, 3).Value
If WorksheetFunction.CountIf(Worksheets(2).Range("A:A"), MyNum) Then '★
Uriage = Application.WorksheetFunction.VLookup(MyNum, MyData, 3, False)
Worksheets(1).Cells(i, 5).Value = Uriage
End If
Next i
End Sub

といった感じでしょうか。

※ 他の方法としてFINDメソッドを使う方法もあります。

Sub Sample1()
Dim i As Long, c As Range, wS As Worksheet
Set wS = Worksheets(2)
With Worksheets(1)
For i = 2 To .Cells(Rows.Count, "A").End(xlUp).Row
Set c = wS.Range("A:A").Find(what:=.Cells(i, "C"), LookIn:=xlValues, lookat:=xlWhole)
If Not c Is Nothing Then
.Cells(i, "E") = wS.Cells(c.Row, "C")
End If
Next i
End With
End Sub

こんな感じでも大丈夫だと思います。m(_ _)m
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。
IF関数を使う方法もあるのですね。
VBAは奥が深いですね。この方法も試してみようと思います。
どうもありがとうございます。

お礼日時:2017/03/25 17:37

そりゃそうでしょう。


エラーが有っても
Worksheets(1).Cells(i, 5).Value = Uriage
を実行してるんですから。

1回前に実行した結果がUriageに残ってるから、それが左辺に代入される。

だから、毎回、Uriageをリセットして置く。

For i = 2 Toi =・・・・
Uriage=0 ←←←←← 追加する。
    • good
    • 0
この回答へのお礼

ありがとうございました!!
何故、エラーが出たのか理由がわかりました。
リセットを追加して、解決しました。
迅速にお返事頂き本当にありがとうございました。
もっと上達できるよう勉強します。

お礼日時:2017/03/25 17:31

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!