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

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

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

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

マクロ

定義された処理手続きに応じて、どのような一連の処理を行うのかを特定させるルールをマクロと呼びます。

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

Q&A

2回答

8642閲覧

Excel VBA 別シートの表を比較、2列で一意、差異の抽出

a8_07

総合スコア0

VBA

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

マクロ

定義された処理手続きに応じて、どのような一連の処理を行うのかを特定させるルールをマクロと呼びます。

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

0グッド

2クリップ

投稿2020/05/01 06:57

前提

Excel VBA初心者です。
業務の一環で、マクロを用いて帳票作成を行うのですが、
検索をしてもなかなかヒットせず、
どなたかお力添えを頂ければと思い質問致します。

・1シートに表が1つずつあり、2シートの表を比較
・2つの表の列数は変わらず行数は可変
・A列とD列(商品コードと納品先)で一意となる

・昨日シートと本日シートを比較して差異区分を新規シート(sheet3)にまとめたい。
※差異区分
1.新規(本日シートにあって昨日シートにない)
2.変更(金額1)
3.変更(金額2)
4.削除(昨日にあって本日にない)

・例
sheet1「昨日シート」
商品コード/商品名/産地/納品先/金額1/金額2
A100/ りんご/青森/ 東京 /100/150
A101/青リンゴ/青森/神奈川/120/170
B150/みかん/愛媛/東京/300/500


sheet2「本日シート」
商品コード/商品名/産地/納品先/金額1/金額2
A100/ りんご/青森/ 東京 /100/150
A101/青リンゴ/青森/神奈川/120/200
C200/マンゴー/宮崎/東京/300/500


### 目標の作成物
新規のシートに差異一覧を表示させる。

A列に差異区分、B列以降は本日シートと同じ項目の転記

差異区分/商品コード/商品名/産地/納品先/金額1/金額2

上記の例で言うと、

差異区分/商品コード/商品名/産地/納品先/金額1/金額2
2.変更(金額2)/A101/青リンゴ/青森/神奈川/120/200
4.削除/B150/みかん/愛媛/東京/300/500
1.新規/C200/マンゴー/宮崎/東京/300/500

こんな感じで表示させたいです。

同一の表での重複検索や重複削除のページは見つかるのですが
2列で一意になる表で表が2つ、というものが見つかりませんでした。

※タブ区切りのテキストファイルが表の元データになるのですが
タブ区切りのテキストファイルをExcelのワークシートに出力するマクロを組んでいます。
いずれはテキストファイルを出力せずに比較→差分のみ抽出、としたいのですが・・・。

参考になるページだけでも構いません。
不慣れで長文になってしまい申し訳ございませんが、
何卒宜しくお願い致します。

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

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

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

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

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

meg_

2020/05/01 09:13

VBAでの手順は頭に浮かんでいますか?全く浮かばないのであれば、VBAではなくVlookup関数とフィルタを使用した手作業の方が良いかもしれません。(関数使えばそれほど時間もかからないでしょう)
a8_07

2020/05/05 11:37

記載有難うございます。 ご指摘いただいた通り知識がほぼ無いことも相まって正直手順は浮かんでいないのが事実ではありますが、 VBAでの作成指示があったので質問致しました。 頂いた回答を元に勉強しながら作成できればと思っています。
guest

回答2

0

こんにちはこんばんは、よろしくおねがいいたします。
ちょっと自分なりに作ってみました。なかなか本格的なプログラムになってしまいましたが・・
”本日シートを検索元として昨日シートを検索する”のと”昨日シートを検索元として本日シートを検索する”の2部構成に、どうしてもなってしまいますね。

以下のプログラムで、私のほうで動作確認しました。
よかったらご参考になさってください。

VBA

1Option Explicit 2 3Sub ExamineCompareTwoSheets() 4'昨日シートと本日シートを比較検証して結果を出力するVBAです 5'2部構成になっています 6 7'パートAは、本日シートのA列(商品コード)を、上から最後までいっこずつ順に降りていき、 8'商品コードによって昨日シートのA列をサーチし、その結果によって以下の判定を行います 9'1.新規=本日シートにあって昨日シートにない 10'2.変更(金額1)=金額1に差異がある 11'3.変更(金額2)=金額2に差異がある 12'4.削除=昨日にあって本日にない 13 14'パートBは、昨日シートのA列(商品コード)を、上から最後までいっこずつ順に降りていき、 15'商品コードによって本日シートのA列をサーチし、その結果によって以下の判定を行います 16'4.削除=昨日にあって本日にない 17 18'シートの定義です 19 Dim YesterdaySheet As Worksheet 20 Dim TodaySheet As Worksheet 21 Dim ReportSheet As Worksheet 22 23 Set YesterdaySheet = ThisWorkbook.Worksheets("昨日シート") 24 Set TodaySheet = ThisWorkbook.Worksheets("本日シート") 25 Set ReportSheet = ThisWorkbook.Worksheets("差異シート") 26 27'出力先の差異シートの行番号です 28 Dim ReportRow As Long 29 ReportRow = 2 '2行目からスタートするとします 30 31'差異区分(A列)にセットする文字を定義しておきます 32 Dim SaiFlag1 As String 33 Dim SaiFlag2 As String 34 Dim SaiFlag3 As String 35 Dim SaiFlag4 As String 36 37 SaiFlag1 = "1.新規" 38 SaiFlag2 = "2.変更(金額1)" 39 SaiFlag3 = "3.変更(金額2)" 40 SaiFlag4 = "4.削除" 41 42'当日シート昨日シートの各列のデータセットを定義しておきます 43 Dim TodayShohinCode As String '当日シートの商品コード 44 Dim TodayShohinMei As String '当日シートの商品名 45 Dim TodaySanchi As String '当日シートの産地 46 Dim TodayNohinsaki As String '当日シートの納品先 47 Dim TodayKingaku1 As Long '当日シートの金額1 48 Dim TodayKingaku2 As Long '当日シートの金額2 49 50 Dim YesterdayShohinCode As String '昨日シートの商品コード 51 Dim YesterdayShohinMei As String '昨日シートの商品名 52 Dim YesterdaySanchi As String '昨日シートの産地 53 Dim YesterdayNohinsaki As String '昨日シートの納品先 54 Dim YesterdayKingaku1 As Long '昨日シートの金額1 55 Dim YesterdayKingaku2 As Long '昨日シートの金額2 56 57 58Dim r As Range 'foreachするためのレンジの定義です 59 60'昨日シートの商品コード列を定義しておきます 61YesterdaySheet.Select 62 Dim YesterdaySearchRange As Range 63 Set YesterdaySearchRange = YesterdaySheet.Range("A2", Range("A2").End(xlDown)) 64 65'本日シートの商品コード列を定義しておきます 66TodaySheet.Select 67 Dim TodaySearchRange As Range 68 Set TodaySearchRange = TodaySheet.Range("A2", Range("A1").End(xlDown)) 69 70'昨日シートをFINDした結果を格納するレンジです 71Dim YesterdayFoundRange As Range 72'本日シートをFINDした結果を格納するレンジです 73Dim TodayFoundRange As Range 74 75'***パートA:本日シートの商品コードを上から下までナメていきます 76For Each r In TodaySheet.Range("A2", Range("A1").End(xlDown)) 77 'この行の各カラムの情報を格納しておきます 78 TodayShohinCode = r.Value 79 TodayShohinMei = r.Offset(0, 1).Value 80 TodaySanchi = r.Offset(0, 2).Value 81 TodayNohinsaki = r.Offset(0, 3).Value 82 TodayKingaku1 = r.Offset(0, 4).Value 83 TodayKingaku2 = r.Offset(0, 5).Value 84 85 '本日シートの商品コードで、昨日シートの商品コード列をサーチします 86 Set YesterdayFoundRange = YesterdaySearchRange.Find(what:=TodayShohinCode, lookat:=xlWhole) 87 88 If YesterdayFoundRange Is Nothing Then 89 '該当する商品コードがなかったとき(=本日にあって昨日にない)=「新規」 90 '本日シートのレコード一式を差異シートに出力する 91 With ReportSheet 92 Debug.Print "「新規」..." 93 .Cells(ReportRow, 1) = SaiFlag1 '差異区分 94 .Cells(ReportRow, 2) = TodayShohinMei '商品コード 95 .Cells(ReportRow, 3) = r.Value '商品名 96 .Cells(ReportRow, 4) = TodaySanchi '産地 97 .Cells(ReportRow, 5) = TodayNohinsaki '納品先 98 .Cells(ReportRow, 6) = TodayKingaku1 '金額1 99 .Cells(ReportRow, 7) = TodayKingaku2 '金額2 100 End With 101 102 ReportRow = ReportRow + 1 '差異レポートシートを、1行送りしておきます 103 104 Else 105 '該当する商品コードがあったとき 106 '昨日シートのこの行の各カラムの情報を格納しておきます 107 With YesterdayFoundRange 108 YesterdayShohinCode = .Value '昨日シートの商品コード 109 YesterdayShohinMei = .Offset(0, 1).Value '昨日シートの商品名 110 YesterdaySanchi = .Offset(0, 2).Value '昨日シートの産地 111 YesterdayNohinsaki = .Offset(0, 3).Value ' '昨日シートの納品先 112 YesterdayKingaku1 = .Offset(0, 4).Value ' '昨日シートの金額1 113 YesterdayKingaku2 = .Offset(0, 5).Value ' '昨日シートの金額2 114 End With 115 116 If TodayKingaku1 <> YesterdayKingaku1 Then 117 '金額1に差異があったとき 118 '本日シートのレコード一式を差異シートに出力する 119 With ReportSheet 120 .Cells(ReportRow, 1) = SaiFlag2 '差異区分 121 .Cells(ReportRow, 2) = r.Value '商品コード 122 .Cells(ReportRow, 3) = TodayShohinMei '商品名 123 .Cells(ReportRow, 4) = TodaySanchi '産地 124 .Cells(ReportRow, 5) = TodayNohinsaki '納品先 125 .Cells(ReportRow, 6) = TodayKingaku1 '金額1 126 .Cells(ReportRow, 7) = TodayKingaku2 '金額2 127 End With 128 ReportRow = ReportRow + 1 '差異レポートシートを、1行送りしておきます 129 End If 130 131 '金額2に差異があったとき 132 If TodayKingaku2 <> YesterdayKingaku2 Then 133 '本日シートのレコード一式を差異シートに出力する 134 With ReportSheet 135 .Cells(ReportRow, 1) = SaiFlag3 '差異区分 136 .Cells(ReportRow, 2) = r.Value '商品コード 137 .Cells(ReportRow, 3) = TodayShohinMei '商品名 138 .Cells(ReportRow, 4) = TodaySanchi '産地 139 .Cells(ReportRow, 5) = TodayNohinsaki '納品先 140 .Cells(ReportRow, 6) = TodayKingaku1 '金額1 141 .Cells(ReportRow, 7) = TodayKingaku2 '金額2 142 End With 143 ReportRow = ReportRow + 1 '差異レポートシートを、1行送りしておきます 144 End If 145 End If 146 147Next r 148 149'***パートB:'昨日シートの商品コードを上から下までナメていきます 150YesterdaySheet.Select 151For Each r In YesterdaySheet.Range("A2", Range("A2").End(xlDown)) 152 'この行の各カラムの情報を格納しておきます 153 YesterdayShohinCode = r.Value 154 YesterdayShohinMei = r.Offset(0, 1).Value 155 YesterdaySanchi = r.Offset(0, 2).Value 156 YesterdayNohinsaki = r.Offset(0, 3).Value 157 YesterdayKingaku1 = r.Offset(0, 4).Value 158 YesterdayKingaku2 = r.Offset(0, 5).Value 159 160 '昨日シートの商品コードで、本日シートの商品コード列をサーチします 161 Set TodayFoundRange = TodaySearchRange.Find(what:=YesterdayShohinCode, lookat:=xlWhole) 162 163 '該当する商品コードがなかったとき(=昨日にあって本日にない)=「削除」 164 If TodayFoundRange Is Nothing Then 165 With ReportSheet 166 .Cells(ReportRow, 1) = SaiFlag4 '差異区分 167 .Cells(ReportRow, 2) = YesterdayShohinCode '商品コード 168 .Cells(ReportRow, 3) = YesterdayShohinMei '商品名 169 .Cells(ReportRow, 4) = YesterdaySanchi '産地 170 .Cells(ReportRow, 5) = YesterdayNohinsaki '納品先 171 .Cells(ReportRow, 6) = YesterdayKingaku1 '金額1 172 .Cells(ReportRow, 7) = YesterdayKingaku2 '金額2 173 End With 174 ReportRow = ReportRow + 1 '差異レポートシートを、1行送りしておきます 175 End If 176 177Next r 178 179End Sub 180

投稿2020/05/01 17:13

AkiSaito

総合スコア110

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

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

a8_07

2020/05/05 11:40

AkiSaito様、回答有難うございます! コメントも詳細に記載いただきとても助かります。 木曜以降に時間が取れそうなので、こちらのコードを元にいじってみようと思います。 2部構成になるとのこと、お時間をかけて頂きとても恐縮です。 誠に有難うございます!
guest

0

こんばんは。コードが長くなるため、金額1、金額2の変更があった場合の例)のみ

提示させていただきます(あえて泥臭いコードとなっています)。

コードが新規の場合、コードが削除された場合は検証してみてください。

昨日シート
本日シート
管理シート
があります。昨日シートと本日シートで商品コードが同じで金額1,金額2が変わった場合
管理シートに記載していくというコードになります。
管理シートの1行目にはタイトルが入力されています。
A1   B1     C1   D1  E1    F1   G1
差異区分 商品コード 商品名 産地 納品先 金額1 金額2

これをベースに考えるきっかけとなればいいのですが・・。

VBA

1Sub test() 2Dim data1 As Long 3Dim data2 As Long 4'※他の変数の宣言は省略(定義してください) 5 6data1 = Sheets("昨日").Range("A1").CurrentRegion.Rows.Count '最終行を数える 7data2 = Sheets("本日").Range("A1").CurrentRegion.Rows.Count'最終行を数える 8 9転記 = 1 10 11For cnt1 = 2 To data1 12 13 With Sheets("昨日") 14 昨日_商品コード = .Range("A" & cnt1).Value 15 昨日_商品名 = .Range("B" & cnt1).Value 16 昨日_産地 = .Range("C" & cnt1).Value 17 昨日_納品先 = .Range("D" & cnt1).Value 18 昨日_金額1 = .Range("E" & cnt1).Value 19 昨日_金額2 = .Range("F" & cnt1).Value 20 21 End With 22 23 24 25 For cnt2 = 2 To data2 26 27 With Sheets("本日") 28 本日_商品コード = .Range("A" & cnt2).Value 29 本日_商品名 = .Range("B" & cnt2).Value 30 本日_産地 = .Range("C" & cnt2).Value 31 本日_納品先 = .Range("D" & cnt2).Value 32 本日_金額1 = .Range("E" & cnt2).Value 33 本日_金額2 = .Range("F" & cnt2).Value 34 35 End With 36 37 38 '■金額1の変更があった場合 39 If 昨日_商品コード = 本日_商品コード Then 40 41 If 昨日_金額1 <> 本日_金額1 Then 42 43 転記 = 転記 + 1 44 45 With Sheets("管理") 46 .Range("A" & 転記).Value = "2.変更(金額1)" 47 .Range("B" & 転記).Value = 本日_商品コード 48 .Range("C" & 転記).Value = 本日_商品名 49 .Range("D" & 転記).Value = 本日_産地 50 .Range("E" & 転記).Value = 本日_納品先 51 .Range("F" & 転記).Value = 本日_金額1 52 .Range("G" & 転記).Value = 本日_金額2 53 End With 54 55 End If 56 End If 57 58 '■金額2の変更があった場合 59 60 If 昨日_商品コード = 本日_商品コード Then 61 62 If 昨日_金額2 <> 本日_金額2 Then 63 64 65 転記 = 転記 + 1 66 67 With Sheets("管理") 68 .Range("A" & 転記).Value = "2.変更(金額2)" 69 .Range("B" & 転記).Value = 本日_商品コード 70 .Range("C" & 転記).Value = 本日_商品名 71 .Range("D" & 転記).Value = 本日_産地 72 .Range("E" & 転記).Value = 本日_納品先 73 .Range("F" & 転記).Value = 本日_金額1 74 .Range("G" & 転記).Value = 本日_金額2 75 End With 76 77 End If 78 End If 79 80 Next 81 82Next 83 84End Sub

投稿2020/05/01 09:32

編集2020/05/01 09:36
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

退会済みユーザー

退会済みユーザー

2020/05/01 10:02

追加のロジックです。例えば・・・・。 新規・削除を判定する(例)ですがExcel関数を組み合わせることでVBAのコードを簡略化できます。 一例)を示します。 例1)本日シートに昨日シートのコード(A列)があるか(削除)を判定する場合:エクセル関数ですと。。 =COUNTIF(昨日!A:A,"B150") 'みかんで0件となります(もちろんこの場合セル番号を指定します)。。。。 これをVBAに置き換えると 件数=worksheetfunction.COUNTIF(昨日!A:A,"B150") で、0件となります。 これをVBAらしくセルを指定する形式に置き換えると。。 for cnt = 2 to XX 件数=worksheetfunction.COUNTIF(sheets("昨日").range("A:A"),sheets("本日").range("A" & cnt).value) next となります。。。。このコードを基本とすれば、いったんVBAですべての行をチェックをしなくても 本日シートの値が昨日シートに含まれているか・コードがあるか(削除)されたか判定できます。。。 あくまでも泥臭くなのですが。伝わるとうれしいのですが・・。 理解できるまでは、エクセル関数のcountif関数を呼び出して対象のコードが0件なら 削除された、新規で追加されたという条件判定に利用しましょう。。。。 一見簡単なのですが、少し複雑なためです。
a8_07

2020/05/05 11:45

記載いただき有難うございます。 エクセル関数を呼び出す、と言う方法があるのですね。 お時間かけていただき誠に有難うございます。 木曜日以降時間が取れるので、こちらの回答を参考にしながらコードを作成してみます。 お忙しい中有難うございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.46%

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

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

質問する

関連した質問