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

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

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

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

Q&A

解決済

1回答

1521閲覧

VBA if文 複数条件

退会済みユーザー

退会済みユーザー

総合スコア0

VBA

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

0グッド

0クリップ

投稿2020/04/27 08:38

編集2020/04/27 14:28
Sub Test() Dim ws1 As Worksheet, ws2 As Worksheet, myDate1 Dim List, cnt As Long, i As Long, j As Long Set ws1 = Worksheets("リストA") Set ws2 = Worksheets("リストB") myDate1 = ws2.Range("B2") If Not (IsDate(myDate1)) Then Exit Sub List = ws1.Range("A1").CurrentRegion cnt = UBound(List, 1) + 1 For i = 2 To ws2.Cells(ws2.Rows.Count, 2).End(xlUp).Row For j = UBound(List, 1) To 2 Step -1  ’リストの下から探すため(一番新しいデータ) ’リストBの品番で検索し、ヒットしたら If ws2.Cells(i, 2).Value = List(j, 2) Then ’ヒットした行をコピぺ※ここで、一番新しいデータだけでなく、過去分までコピペされている ws1.Rows(j).Copy Destination:=ws1.Rows(cnt) If ws1.Cells(j, 4).Value = "B" Then ws1.Cells(cnt, 4).Value = "A" End If ws1.Cells(cnt, 3).Value = myDate1 '☆箇所の条件を追加してみました ’リストBの品番がヒットしなければ、リストBの品番2で検索 ElseIf ws2.Cells(i, 3).Value = List(j, 2) Then ’ヒットした行をコピペ ws1.Rows(j).Copy Destination:=ws1.Rows(cnt) If ws1.Cells(j, 4).Value = "B" Then ws1.Cells(cnt, 4).Value = "A" End If cnt = cnt + 1 Exit For End If Next j Next i End Sub ```以前、質問した内容で、編集の必要が出てきました。 要件に応じて修正しているのですが、うまくいかない部分があり※☆箇所、ご教授頂けないでしょうか。 下記リストがあります。 リストBの品番をリストAの品番の下から検索しヒットした行をコピーして(つまり最新行)、リストAの最終行に貼りつける。このとき、貼りつけ先行の登録日はリストBセルB2の登録日(固定)に書き換え、貼りつけ先の区分がBであればAに更新する。 ☆上記に追加で、もしB列の品番でヒットしない場合は、C列の品番2で検索をかける。 この場合、貼付け先の登録日は何もしない。それ以外はB列品番で検索した時と同じ作業をする。 リストA 商品名/品番/登録日/区分 aaa/001/yyyymmdd/A iii/002/yyyymmdd/A uuu/003/yyyymmdd/C iii/002/yyyymmdd/A aaa/001/yyyymmdd/B uuu/003/yyyymmdd/A ・ ・ aaa/001/yyyymmdd/B リストB 商品名/品番/品番2/登録日 aaa/001/100/yyyymmdd iii/002/200/yyyymmdd uuu/003/300/yyyymmdd ・ ・ ・ うまくいかないこと マクロは動くのですが、対象外の行もコピぺされてしまいます。 B列で検索をかけ、ヒットしなければC列で検索をかける。 B列で検索をかけた場合と、C列で検索をかけた場合で異なる処理をする場合は どのように設定すればよいでしょうか。

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

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

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

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

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

meg_

2020/04/27 09:42

1行ずつデバッグすると何が原因か判明するかと思います。「対象外の行もコピぺされてしま」うときの変数の値を確認すると良いでしょう。
退会済みユーザー

退会済みユーザー

2020/04/27 13:45

アドバイスいただき、1行ずつ実行してみたのですが、If ws2.Cells(i, 2).Value = List(j, 2) Then ws1.Rows(j).Copy Destination:=ws1.Rows(cnt) この部分で、リストAの下から検索して最初にヒットした行のみをコピーしたいのですが、過去分も全てコピぺされています。 if文を組み込む場所が悪いようで何度もループされているようです。 いろいろ場所を変えたりしているのですが、うまくできません。 どこを修正すればよいか教えて頂けないでしょうか。
meg_

2020/04/27 14:06

今のままではコードがとても読みにくいので、「コードの挿入」で記入してください。
退会済みユーザー

退会済みユーザー

2020/04/27 14:29

読みにくく申し訳ございません。コードの挿入に記入してみました。
meg_

2020/04/27 14:42

コードを掲載するときはインデントをつけてください。インデントがなくても動作する言語もあるかと思いますが人がコードを読む際には必須です。今後ご注意ください。
mattuwan

2020/04/28 12:12

登録日の列の値(表示されている文字ではない)は、ちゃんと日付なんでしょうか? 例示だと、文字列と読めます。 文字列なら、過去かどうかの判定に間違いがでるかも? というか、最新の登録日だけを得られればいいのでしょうか? それとも、リストBにないリストAのデータをコピーしたいのでしょうか? 伏字で例を書かれても、ルールを読み取れません。 こうなっているときに、こうなって欲しいという、ビフォー&アフターを 提示してみてはいかがでしょうか?
guest

回答1

0

ベストアンサー

机上デバッグしてみました。Excelでの動作確認はしていませんのでバグがありましたら修正してください。
ポイントはヒットしたかどうかをチェックするフラグを追加したことと、リストBの品番でリストAを全部検索してから品番2で検索することです。

VBA

1Sub Test() 2 Dim ws1 As Worksheet, ws2 As Worksheet, myDate1 3 Dim List, cnt As Long, i As Long, j As Long 4 Dim copyCheck As Boolean 5 6 Set ws1 = Worksheets("リストA") 7 Set ws2 = Worksheets("リストB") 8 myDate1 = ws2.Range("B2") 9 10 If Not (IsDate(myDate1)) Then Exit Sub 11 List = ws1.Range("A1").CurrentRegion 12 cnt = UBound(List, 1) + 1 13 14 For i = 2 To ws2.Cells(ws2.Rows.Count, 2).End(xlUp).Row 15 copyCheck = False 16 For j = UBound(List, 1) To 2 Step -1 'リストの下から探すため(一番新しいデータ) 17 If copyCheck = False Then 18 'リストBの品番で検索し、ヒットしたら 19 If ws2.Cells(i, 2).Value = List(j, 2) Then 20 'ヒットした行をコピぺ※ここで、一番新しいデータだけでなく、過去分までコピペされている 21 ws1.Rows(j).Copy Destination:=ws1.Rows(cnt) 22 copyCheck = True 23 24 If ws1.Cells(j, 4).Value = "B" Then 25 ws1.Cells(cnt, 4).Value = "A" 26 End If 27 28 ws1.Cells(cnt, 3).Value = myDate1 29 cnt = cnt + 1 30 End If 31 End If 32 Next j 33 34 If copyCheck = False Then 35 For j = UBound(List, 1) To 2 Step -1 'リストの下から探すため(一番新しいデータ) 36 If copyCheck = False Then 37 'リストBの品番がヒットしなければ、リストBの品番2で検索 38 If ws2.Cells(i, 3).Value = List(j, 2) Then 39 'ヒットした行をコピペ 40 ws1.Rows(j).Copy Destination:=ws1.Rows(cnt) 41 42 If ws1.Cells(j, 4).Value = "B" Then 43 ws1.Cells(cnt, 4).Value = "A" 44 End If 45 copyCheck = True 46 cnt = cnt + 1 47 End If 48 End If 49 Next j 50 End If 51 52 Next i 53End Sub

投稿2020/04/27 14:40

編集2020/04/27 16:18
meg_

総合スコア10580

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

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

退会済みユーザー

退会済みユーザー

2020/04/27 14:53

有難うございます。実行したところ、Nextに対応するForがありませんと出てしまいます。 私には難しく、Exit Forを(cnt=cnt+1の後ろ?)どこに入れたらよいのか...大変恐縮なのですが宜しくお願いします。
meg_

2020/04/27 15:10

修正しました。とりあえずコンパイルエラーは出ないはずです。
退会済みユーザー

退会済みユーザー

2020/04/27 15:21

ありがとうございます。うまく動かないので、いろいろ試してみます。ご教授いただいたポイントと一緒にコードを解読してみようと思います。できましたらコメントいたします。 宜しくお願いします。
meg_

2020/04/27 16:19

動作確認しました。いくつかおかしなところがあったので修正しました。
退会済みユーザー

退会済みユーザー

2020/04/28 12:42

やりたいことができました。 ご教授頂いたポイントをコードで照らし合わせて勉強しました。有難うございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問