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

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

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

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

Q&A

解決済

1回答

553閲覧

VBA データ抽出コピペ

退会済みユーザー

退会済みユーザー

総合スコア0

VBA

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

0グッド

0クリップ

投稿2020/03/20 14:56

編集2020/03/21 00:27

前提・実現したいこと

下記リストがあります。
リストBの品番をリストAの品番の下から検索しヒットした行をコピーして(つまり最新行)、リストAの最終行に貼りつける。
このとき、貼りつけ先行の登録日はリストBセルB2の登録日に書き換え、貼りつけ先の区分がBであればAに更新する。
リスト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
商品名/品番/登録日
aaa/001/yyyymmdd
iii/002/yyyymmdd
uuu/003/yyyymmdd


発生している問題・エラーメッセージ

もともとあるマクロを修正して使っていたのですが、「貼付け元行の区分がAならば、貼付け先行の区分をBと書き換える」
部分がうまくいかないです。
マクロ勉強中で、ソースの意味も理解できていないので、ソースの説明を頂けないでしょうか。

該当のソースコード

Sub Test()
Dim ws1 As Worksheet, ws2 As Worksheet, myDate1
Dim List, cnt As Long, i As Long, j As Long

’リストA,Bを変数にセットする
Set ws1 = Worksheets("リストA")
Set ws2 = Worksheets("リストB")

'リストBのセルB2にある日付をmydate1にセット
myDate1 = ws2.Range("B2")
’もし、リストBのセルB2が空白ならば、何もせず終了する
If Not (IsDate(myDate1)) Then Exit Sub
’リストA1を始点にする?
List = ws1.Range("A1").CurrentRegion
’ここは調べたのですが、理解できていません。リストの最終行をcntにセットしている??
cnt = UBound(List, 1) + 1

’iにリストBの品番先頭から最後をセット
For i = 2 To ws2.Cells(ws2.Rows.Count, 2).End(xlUp).Row
’jにリスト1行目から最終行をセット?
For j = UBound(List, 1) To 2 Step -1

’もし、リストBの品番とリストAの品番が一致したら(このソースで下から検索しているのか理解できていません)
If ws2.Cells(i, 2).Value = List(j, 2) Then
’行をコピーして、最終行に張り付ける
ws1.Rows(j).Copy Destination:=ws1.Rows(cnt)
’貼付け先行の日付をmydate1の値にセット
ws1.Cells(cnt, 3).Value = myDate1

cnt = cnt + 1
Exit For
End If
Next j
Next i

End Sub

試したこと

「貼付け元行の区分がAならば、貼付け先行の区分をBと書き換える」は、IF分を使って
if ws1.cells(j,4).value = "B" then
ws1.cells(cnt,4).value ="A"
というソースでよいのかと思ったのですが、これをどこに追加すればよいのかわかりません。

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

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

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

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

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

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

yureighost

2020/03/20 20:55

Excelのデータがないとどうなっているかはよくわかりませんが、 少なくともそのIF文はBだったら、Aに書き換えるになってますよ。
退会済みユーザー

退会済みユーザー

2020/03/20 22:04

ご連絡ありがとうございます。 エクセルのデータとは、スクショが必要ということでしょうか。 宜しくお願いします。
Akashic

2020/03/20 23:51

該当のソースコードって抜粋でしょうか? myDate1に何も設定していないので > If Not (IsDate(myDate1)) Then Exit Sub で、抜けるように見えるのですが。
yureighost

2020/03/21 00:07 編集

数行でもシートの状況がわかって、かつ質問者さんがやりたいことの 条件を満たしているものとそうでないものを抜粋できてるパターンがあれば。 ざっと見てもB列でも判定してるのでデータがないとソースだけだと何とも言えません。 それにmyDate1は確かにおかしいですね。
退会済みユーザー

退会済みユーザー

2020/03/21 00:28

Akashic様 有難うございます。大変失礼しました。myDate1に値を設定してソースを更新しました。 このソースで実行できる内容です。 自分なりにですがソースに実行している内容をコメントをつけてみました。 (理解できていない部分が多く、めちゃくちゃかもしれませんが) 勉強不足で申し訳ございませんが、ご教授頂けると助かります。
Akashic

2020/03/21 01:14

>'リストBのセルB2にある日付をmydate1にセット >myDate1 = ws2.Range("B2") B2って品番じゃないです??C2ですかね?
Akashic

2020/03/21 01:45

長くてわかりづらいかもしれませんが、回答のほうに処理のコメント書きました。
退会済みユーザー

退会済みユーザー

2020/03/21 03:13

ご指摘の通り、C3でした。申し訳ございません。 回答にコメントをご丁寧に説明頂き、大変助かりました。コメントを確認しながらデバックを実行して、勉強したいと思います。 区分の書き換えについては、End ifの位置を間違えておりました。 やりたい事が実行できました。ありがとうございます。
guest

回答1

0

ベストアンサー

質問への追記に書いた通り、今のままでは関数自体はすぐ抜けそうなのは置いておいて。

コピーは出来ているようなので、区分=Bの時にAにする場所については、
登録日を上書きしている辺りで、"試したこと"のコードをやればよいかと思います。(End Ifも必要です)

抜粋)

Excel

1For i = 2 To ws2.Cells(ws2.Rows.Count, 2).End(xlUp).Row 2 For j = UBound(List, 1) To 2 Step -1 3 If ws2.Cells(i, 2).Value = List(j, 2) Then 4 ws1.Rows(j).Copy Destination:=ws1.Rows(cnt) 5 ws1.Cells(cnt, 3).Value = myDate1 6 If ws1.Cells(j, 4).Value = "B" Then 7 ws1.Cells(cnt, 4).Value = "A" 8 End If 9 10 cnt = cnt + 1 11 Exit For 12 End If 13 Next j 14Next i

投稿2020/03/21 00:06

Akashic

総合スコア298

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

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

Akashic

2020/03/21 01:47 編集

デバッグ実行して、自分で動かしながら確認していたっ方がわかりやすいと思いますが、各処理のコメントです。 >’リストA1を始点にする? >List = ws1.Range("A1").CurrentRegion "リストA"シートのデータが2次元配列でListに格納されるイメージです >’ここは調べたのですが、理解できていません。リストの最終行をcntにセットしている?? >cnt = UBound(List, 1) + 1 Uboundは、配列の添字の最大値を返すので、要素数+1をcntに入れています。 例えば、"リストA"シートにタイトル含めて全7行あったら8が入ります。 >’iにリストBの品番先頭から最後をセット >For i = 2 To ws2.Cells(ws2.Rows.Count, 2).End(xlUp).Row セットというか、iを2から順に増やしてNext iまでのコードをを繰り返しですね。 イメージとしては、"リストB"シートの2行目から最終行までを1行ずつ繰り返している感じです。 >’jにリスト1行目から最終行をセット? >For j = UBound(List, 1) To 2 Step -1 Listに"リストA"シートのデータが入っているので、jを減らしながらNext jまでのコードを繰り返しです。 Step -1(1ずつ減らしながら)、To 2(で2番目の要素まで)繰り返し。 イメージとしては、"リストA"シートのデータを最下行から2行目まで下から1行ずつ繰り返している感じです。 1番目はタイトル行(商品名、品番、登録日、区分)なので、2行目までになっていると思います。 >’もし、リストBの品番とリストAの品番が一致したら(このソースで下から検索しているのか理解できていません) >If ws2.Cells(i, 2).Value = List(j, 2) Then >’行をコピーして、最終行に張り付ける >ws1.Rows(j).Copy Destination:=ws1.Rows(cnt) >’貼付け先行の日付をmydate1の値にセット >ws1.Cells(cnt, 3).Value = myDate1 ここが、品番が一致した場合の処理です。下から検索しているのは、For j = UBound(List, 1) To 2 Step -1 の部分です。 やっていることは、コメントに書かれているとおりです。 コピーして、日付を上書きしています。 回答した通り、区分を変えるならここに区分を書き換える処理を入れれば良いかと思います。 ちょっと気になったのは、"リストB"シートには複数データがあるみたいですが、毎回2行目のデータをいれているように見えるので、全データに対応するなら修正必要にみえます。 >myDate1 = ws2.Range("B2") を固定的にやっているので。 >cnt = cnt + 1 最終行(データを追記する行位置)を1行下にする。 >Exit For 内側(j)のループから抜ける
退会済みユーザー

退会済みユーザー

2020/03/21 03:16

やりたい事ができました。 コメントもご丁寧にありがとうございます。教えて頂いた内容を確認しながら勉強したいと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問