• 締切済み

エクセル VBAで2つのデータを比較して、一致するものを検索したい

以下のような事をしたいと思っています。 VBAは今まで使った事が殆どなく困っております。 仕事で作らなければならず、宜しくお願い致します。 エクセルVBAで、既存と新規という2つのシートから 2つの条件(A列とB列の完全一致)で行を検索して 一致したものを探し出します。 一致したら「新規シート」の該当した行の売上列のデータを 「既存シート」の該当月の列へコピーしたいと思っております。 また、「新規シート」には「既存シート」にないデータが 存在するので、一致から漏れた行は「既存シート」へ 新たに追加のデータとしてコピーしたいと思っています。 イメージ↓ 既存シート) 商品名 |製造地|6月(製造月の売上)|7月(製造月の売上) a     |あ   |¥150      | b     |い   |¥200      | (空白)  |(空白)|          | 新規シート) 商品名 |製造地 |7月(製造月の売上)| a     |あ   |¥300      | b     |い   |¥100      | c     |う   |¥250      | 上記の2シートで、商品名と製造地の2つが一致していれば 「新規シート」の7月の列のデータを「既存シート」の 7月の列にコピーし、「既存シート」に存在しない 「新規シート」の商品名”c”の行のデータを「既存シート」へ 新たに商品名”c”の行を作成しコピーしたいと思っています。 出来上がり後の(既存シート) 商品名 |製造地 |6月(製造月の売上)|7月(製造月の売上) a      |あ   |¥150      |¥300 b      |い   |¥200      |¥100 c      |う   |¥0        |¥250

みんなの回答

  • argument
  • ベストアンサー率63% (21/33)
回答No.8

回答です。暇つぶしに作ってみました。 Sub newdataset() '事前データ取得 Sheets("既存シート").Select tablestart = 2 'テーブルの開始位置Y軸 '商品カウント For i = tablestart To 65536 If Range("a" & i).Value <> "" Then oldmax = i Else Exit For Next '新規データ取得 Sheets("新規シート").Select newdatas = Array("", "", "") mymonth = Split(Cells(tablestart - 1, 3).Value, "月")(0) For i = tablestart To 65536 newdatas(0) = newdatas(0) & Range("a" & i) & vbCrLf newdatas(1) = newdatas(1) & Range("b" & i) & vbCrLf newdatas(2) = newdatas(2) & Range("c" & i) & vbCrLf If Range("a" & i).Value <> "" Then newmax = i Else Exit For Next For i = 0 To UBound(newdatas): newdatas(i) = Split(newdatas(i), vbCrLf): Next '比較と書き込み処理 Sheets("既存シート").Select For i = 0 To UBound(newdatas(0)) - 1 For j = tablestart To 65536 If oldmax < j Then 'oldのmaxlineを超えた場合新しいデータ If newdatas(0)(i) = "" Then Exit For If Cells(j, 1).Value = "" Then Cells(j, 1).Value = newdatas(0)(i) Cells(j, 2).Value = newdatas(1)(i) Cells(j, 3 + (mymonth - 6)).Value = newdatas(2)(i) For k = 3 To 3 + (mymonth - 6) - 1 Cells(j, k).Value = 0 '新規の場合過去分がないため0埋め Next Exit For End If Else If (Range("a" & j).Value = newdatas(0)(i)) And (Range("b" & j).Value = newdatas(1)(i)) Then Cells(j, 3 + (mymonth - 6)).Value = newdatas(2)(i) 'AとBは同じなため更新するのはC列のみ Exit For End If End If Next Next End Sub 既存シート  |A|B|C ―┼―┼―┼― 01|商|製|6月 ―┼―┼―┼― 02| a|あ|150 ―┼―┼―┼― 03| b|い|200 新規シート  |A|B|C ―┼―┼―┼― 01|商|製|7月 ―┼―┼―┼― 02| a|あ|300 ―┼―┼―┼― 03| b|い|100 ―┼―┼―┼― 04| c|う|250 この状態でマクロを動かしてください 既存シート  |A|B|C|D ―┼―┼―┼―┼ 01|商|製|6月| ―┼―┼―┼―┼― 02| a|あ|150|300 ―┼―┼―┼―┼ 03| b|い|200|100 ―┼―┼―┼―┼ 04| c|う| 0|250 ―┼―┼―┼―┼ と成ります。 中途半端に六月から始まるためmymonth - 6で右に一つずつ移動させています。また月処理分移動するため8・9…月などにすればちゃんと右にずれます。新しいデータは前月分より前はデータはないため全て0で埋めます。 現在見えてくる仕様から作ったため12以降どうすんの?とか1月から始まらなくていいの?とか有りますがまぁ知りません。ちなみに12月以降は単に-6なので1月とか入れればまぁ確実にばぐると思います。 現状で言われた状態と現状でこうあってほしい状態にはなっているはずです。 処理違いや補足・修正が欲しい場合言ってください。書き直します。

  • n-jun
  • ベストアンサー率33% (959/2873)
回答No.7

ANo.5です。 ピボットテーブルを実際に試されていなければ、一度試してみては如何でしょう。 求めたい結果と相違が殆どなければ、その方が楽なのかも知れません。 私は全くわからないので、結果がどうなるのかはわかりませんが。 VBAで後々のメンテで悩むより楽なのかも知れないですよ。

  • mitarashi
  • ベストアンサー率59% (574/965)
回答No.6

A No.2です。 >VBAは今まで使った事が殆どなく困っております。 この状態で、既存の表にこだわる事が、takemeさんの業務にとって有意義な事か疑問ですが(なにしろピボットテーブルならコードを1行も書く必要がないのですから)、どうしても既存の表にこだわられるなら、次のワークフローを提案します。 ・新規シート)にある月のデータを入力する ・A No.2で提案した,データベースのレコード形式のシートにデータを転記する。 ・既存シート)に配置した、ピボットテーブルのデータの更新を行う。 (注)レコード形式のシートのデータの範囲には動的な名前(データを追加すると、名前の範囲が自動的に拡張される)をつけておき、ピボットテーブルもその「名前」をデータ範囲に指定しておく。 VBAで行うのは、フローの2番目だけで良いので、至極簡単になるでしょう。

  • n-jun
  • ベストアンサー率33% (959/2873)
回答No.5

ANo.4です。 無理ではないと思いますが。 まず既存シートは、新規シートが作成されデータの打ち込み後に既存シートへデータを転送し、 新規シートはデータをクリアするようなイメージがあるのですが。 その際に月が増えてきた場合の全体のデータ数によっては、手間のかかる場合もあります。(回避策もあるでしょうけどね) 私的には7月のデータを収集する時には、既存シートに7月以降の項目行がなかった方が楽かと思いました。 単に既存シートの項目行から該当する列を探せば良いだけですが、 項目行がなければ6月までが使用されている列数とわかりましたので。 (項目行の一番右がデータのある最終列になりますから) 人それぞれでも作り方は違うでしょうから、一概には言えませんけど。 ただちょっとはやっかいな部分もありますので、後々のメンテをご自身でやる場合に、 ちょっと大変かなって感じがあるかもです。 Excel(エクセル) VBA入門:Dictionaryオブジェクトを利用する http://www.eurus.dti.ne.jp/~yoneyama/Excel/vba/vba_dictionary.html 重複データ絡みの時によく用いている方法です。

  • n-jun
  • ベストアンサー率33% (959/2873)
回答No.4

ANo.1です。 ピボットテーブル案も出ているようですので一度試されてみては如何でしょうか。 私はピボットテーブルは全くわからないのでお力にはなれませんが。

takeme
質問者

お礼

やはり、私の出したような表にするのは無理なんでしょうか?

  • mitarashi
  • ベストアンサー率59% (574/965)
回答No.3

#2です。おまけで小計欄の消し方を参考URLに添付します。これでほぼ、お望みの体裁になると思います。

参考URL:
http://www.relief.jp/itnote/archives/002618.php,http://office.microsoft.com/ja-jp/excel/HP100963171041.aspx
  • mitarashi
  • ベストアンサー率59% (574/965)
回答No.2

>VBAは今まで使った事が殆どなく困っております。 今回の課題は厳しいのではないでしょうか。コードを丸ごと教えてもらっても、応用できないように思います。 データの管理の仕方を変えて、ピボットテーブルを使うことをお勧めします。 下記の様な毎月のデータを蓄積する形式にして、 ...............A................B............C..............................D ..1.....商品名.... 製造地..........月....製造月の売上げ ..2.............a............ あ......6月.........................\150 ..3.............b............ い......6月........................\200 ..4.............a............ あ......7月........................\300 ..5.............b............ い......7月.........................\100 ..6.............c............ う......7月........................\250 ピボットテーブルの、行フィールドに商品名と、製造地を、列フィールドに月を、データアイテムに売上げをD&Dすると、お望みの表に近い形のものができます。

参考URL:
http://sweety.jp/honobono/faq/pibo/index.htm
takeme
質問者

補足

申し訳ありません。 このような状態ではなく、 質問に出したような表にしたいのです。 ありがとうございました。

  • n-jun
  • ベストアンサー率33% (959/2873)
回答No.1

・既存シートで仮に”8月”以降は項目行に既に代入されているのでしょうか? ・"¥0"は必要なのでしょうか?

takeme
質問者

補足

すみません、 既存シートには8月以降の項目行は作成済みです。 ¥0は無くても大丈夫です。 宜しくお願いします。

関連するQ&A