Excel VBAで複数項目の集計方法を教えてください

このQ&Aのポイント
  • EXCEL2003 VBAにてマクロを作成しているのですが、作成日程が迫っているにも関わらず、すぐ行き詰ってしまいます。どうかご指導お願い致します。
  • あるSheetに特定のデータが登録されており、それを特定の条件で集計したいと考えています。数字を合計するのはA列とB列が一致したときのみです。しかし、ForNextで処理する場合、行数が増えると処理回数が増え、時間がかかる可能性があります。より効率的な方法があれば教えていただきたいです。
  • 集計したいデータがあるSheetには、りんご、なし、メロンのようなデータがあり、その色と数量も登録されています。このデータを集計して、りんご、なし、メロンの各項目ごとに、色と数量の合計を返したいと考えています。
回答を見る
  • ベストアンサー

excel vba 複数項目の集計

EXCEL2003 VBAにてマクロを作成しているのですが、作成日程が迫っているにも関わらず、 すぐ行き詰ってしまいます。どうかご指導お願い致します。 以下のような事をしたいのですが、できる限り高速で最も効率の良い方法を教えていただきたいと 思っております。よろしくお願い致します。 あるSheetに以下のようにデータが登録されていて、 A       B        C りんご    赤       200 なし     黄色      100 りんご    緑       100 メロン    緑       10 なし     黄色      200 りんご    緑       500 これを集計すると、 りんご  赤  200 りんご  緑  600 なし   黄色 300 メロン  緑  10 と、結果を返したいと考えています。 数字を合計するのはA列とB列がともに一致した時のみです。 最初は単純に何回もForNextで処理しようと思ったのですが、行数が 多くなると繰り返し回数も多くなり、時間もかかってしまうので、 別の方法でもっといい方法があればと思い、質問させていただきました。 宜しくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • redfox63
  • ベストアンサー率71% (1325/1856)
回答No.3

自前で検索するのをやめて Scripting.Dictionaryオブジェクトに任せるなら Sub Test()   Dim dicName As New Dictionary   Dim r As Range   Dim dicCor As Dictionary   Dim sName, sColor, obj   Dim nn As Integer   ' データの集計   For Each r In Range("A2", Range("A65536").End(xlUp))     ' りんご、なし、メロンなどを取得     sName = r.Value     ' 色を取得     sColor = r.Offset(, 1).Value     ' 値段を取得     nn = r.Offset(, 2).Value     ' dicNameに登録済みか検査     If dicName.Exists(sName) = False Then       ' 未登録なら 色、値段を登録       Set dicCor = New Dictionary       dicCor.Add sColor, nn       dicName.Add sName, dicCor     Else       ' 登録済みの場合 色情報を検査       Set dicCor = dicName(sName)       If dicCor.Exists(sColor) = False Then         ' 色情報が未登録なら 新規登録         dicCor.Add sColor, nn       Else         ' 色情報があるなら 値段を更新         nn = dicCor(sColor) + nn         dicCor(sColor) = nn       End If       ' 色情報を更新       Set dicName(sName) = dicCor     End If   Next   ' 出来上がったデータを表示   For Each sName In dicName     Set dicCor = dicName(sName)     For Each sColor In dicCor       n = dicCor(sColor)       ' セルに転記するなら Rangeなどに置き換えましょう       Debug.Print sName, sColor, nn     Next   Next End Sub といった具合で ・・・

butman11
質問者

お礼

ご回答有難う御座いました。 Scripting.Dictionaryオブジェクトの存在を初めて知りました! これは使い勝手が非常に良さそうです! 他の方の、関数を使用した方法と平行して検討したいと思います。 有難う御座いました。

その他の回答 (6)

  • layy
  • ベストアンサー率23% (292/1222)
回答No.7

前述の、具体的に、と言われると、 まずは「コントロールブレイク」 余裕があればこれをマスターしておく。 今回のは、 A,B,C,A,D,C,Eとあって 4件目のAが既にあったキーか見る場合、 INSTR(1,"ABC","A")=1とさせるか、Aと1件ループ検索して有り判明するか、 6件目のCが既にあったキーか見る場合、 INSTR(1,"ABCD","C")=3とさせるか、A,B,Cと3件ループ検索して有りと判明するか、 7件目のEが既にあったキーか見る場合、 INSTR(1,"ABCD","E")=0とさせるか、A,B,C,A,D,Cと6件ループ検索して無いと判明するか、 やっていたのは後者じゃないのか?と解釈しましたが・・・・。 どういうことすれば楽になるか、そんなこと考えながら組立てができればいいのですが・・・。 VBAプログラミングまで含めるとアプローチは人それぞれ、いろいろあります。 最初は使いこなせるもので行えばいいでしょう。 アプローチ策(引出し)をたくさん知っていれば、今後の対応も楽になります。

butman11
質問者

お礼

返事遅れて申し訳ありませんでした!! なぜだか、ログインする時に「既にそのユーザーはログイン中です」 みたいな返答が返ってきて、ログインできませんでした。 確かに、方法もいろいろあって、アプローチの仕方もみなさんそれぞれ違うと いうことがよく分かりました。本当にありがとうございました。 みなさんの意見を参考に今回はDictionaryオブジェクトを使ってマクロを組むことにしました。 また何かありましたら宜しくお願いします!

  • yuu_x
  • ベストアンサー率52% (106/202)
回答No.6

Microsoft Query が使えるなら データ → 外部データ → ファイル選択(保存してあれば同一ファイルでも可) → クエリ編集 コマンドに以下入力 SELECT `名前` ,`色` ,SUM(`値段`) AS `小計` FROM `Sheet1$` GROUP BY `名前`, `色` セル選択 編集する場合は選択したセルで、データ → 外部データ → クエリ編集

butman11
質問者

お礼

ご回答有難う御座いました。 Microsoft Query といものを初めて知りました。 SQL文で抽出するのですね! 皆さんの回答のおかげで、様々なアプローチの仕方が あることに気づきました。 有難う御座いました!

  • layy
  • ベストアンサー率23% (292/1222)
回答No.5

コントロールブレイク知らずして関数で、という人もいるでしょうが、これは基本的ロジックで、マスターすべきテクニック。時間の許す限りVBAで、ですね。 並べ替えしないでやると「なし」のデータをする時「なし」があるかないかはループ2回とか3回、「メロン」のときは3回、この存在チェックの繰り返しで無駄なループが起きているという意味でしょうか。 出現したものが変数1エリアなら存在チェックは楽です。 1件目の後「りんご」 2件目の後「りんごなし」3件目の後「りんごなし」INSTR関数使ってやると「りんごなし」から「りんご」があるかないか、「りんごなし」から「なし」があるかないか、容易にわかります。 また 事前に1度全部読み込みして何種類になるか、例では4つ、を明確にさせておいても違うのでは?、先頭から集計させるときに「なし」なら3番目、とできます。 やろうとしている考えも基本的ロジックで頻繁に使います。ほかの、と途中で放棄しないことですね。

butman11
質問者

お礼

ご回答有難う御座いました。 すみません、もう少し具体的に書いていただけると非常に 助かるのですが・・・ 理解力不足で申し訳ありません!

  • imogasi
  • ベストアンサー率27% (4737/17068)
回答No.4

VBAの勉強をしたいためにVBAを使うのか? それなら気長に広く経験して、力を蓄えるほか無いよ。 >作成日程が迫っているにも関わらず、・・ の時に仕事で使用するものじゃない。 ーー ピボットテ-ブルやSUMPRODUCT関数があるのに、何でVBAを使うのか? 複数条件の集計は、2007ならSUMIFS、それ以前ならSUMPRODUCTを使うのは定石。 ーー VBAを使うなら一番速いロジックは、A+B列でソートして、A+B列(A1&B1)の値が変化するところをとらえて集計することだ。 ソートの良いところは、キーの同類がレコード的に(行的に)近隣行に集ることだ。そこを活用する。 コントロールブレークのロジックだ。 こういうことも経験せずに、急いで、自由にVBAを使うと言うのは無理だと思う。 ーーーー SUMPRODUCTなど使うために必要な、A+B列に出てくる項目で重複無く、漏れの無い組み合わせは 出し方に工夫が要る。 例データ A:D列 キー1 キー2 合成 計数 x a xa 1 x g xg 2 y c yc 3 z c zc 1 y a ya 2 z c zc 3 x a xa 1 x b xb 2 z a za 3 C列は=A1&B1 第1行目に見出しはつけておくこと データーフィルターフィルタオプション設定 指定した範囲を指定。その第1行目に見出しを入れておくこと。 「重複するレコードは無視する」にチェック で実行。 結果 E:G列 キー1 キー2 合成 x a xa x g xg y c yc z c zc y a ya x b xb z a za このA列とB列の値を使ってSUMPRODUCT関数の第1比較()内、第2比較の()内に使う。 キー1 キー2 合成 計数合計 x a xa 2 x g xg 2 y c yc 3 z c zc 4 y a ya 2 x b xb 2 z a za 3 式はH列のH2 =SUMPRODUCT(($A$2:$A$10=E2)*($B$2:$B$10=F2)*($D$2:$D$10)) 式を下方向に複写。

butman11
質問者

お礼

ご回答有難う御座いました。 みなさんの回答にもありますが、ピボットテ-ブルやSUMPRODUCT関数を使うのが やはりポピュラーなのですね。 自分は使用したことがないので、調べてみたいと思います。 有難う御座いました。

  • yuu_x
  • ベストアンサー率52% (106/202)
回答No.2

・ピボットテーブル ・集計機能 ・D 関数群 等

butman11
質問者

お礼

ご回答有難う御座いました。 ピボットテーブル 集計機能D 関数群  は普段使用したことがないので、VBAをせずにSheet上で集計できる方法も検討したいと思います。 有難う御座いました。

  • kmetu
  • ベストアンサー率41% (562/1346)
回答No.1

VBAではありませんが オートフィルターを使いA列とB列の重複を除去したデータをたとえばF列とG列に出します。 フィルタオプションの設定で(例示のデータの場合) 指定した範囲にチェック  リスト範囲   $A$1:$B$6 (品名と色の範囲のセルを選択します)  抽出範囲   $F$1:$G$1 (重複を除いたデータを出力したいセルの先頭を指定します) 重複するレコードは無視するにチェック として集計を出したいセルに以下の式を入力します =SUMPRODUCT(($A$1:$A$6=F1)*($B$1:$B$6=G1)*($C$1:$C$6)) VBAで行いたい場合にはこの動作を記録しておけばいかがでしょう。

butman11
質問者

お礼

ご回答有難う御座いました。 自分はあまりSheet上で関数を使用したことがないので、 何でもマクロ上で処理しようとしていました。 回答してくださったアプローチも検討したいと思います。 有難う御座いました。

関連するQ&A

  • エクセルのシート名を、シート1に作成した新旧一覧表に対応させる形で、複数シート一括で変更するには?

    エクセルのシート名の変更について教えてください。 シート1のA列に、現在のブックのシート名が、 シート1のB列には、変更したいシート名が 対応するように入力されています。 シート数は50~200程度で、つど変わります。 例     A列    B列 1行目:りんご   赤色  2行目:ばなな   黄色 3行目:メロン   緑色     ・     ・     ・     ・     ・     ・ ※この場合、「りんご」は「赤色」に、「ばなな」は「黄色」に、 「メロン」は「緑色」に、それぞれシート名を変換したい。 今は、手作業でひとつずつシート名を変換しており、 かなりの手間で困っています。 一覧表を作成するまでは手作業でいいのですが、 何とかして、シート名の変更を、この一覧表を参照して できないでしょうか? 過去の質問をいろいろと見たのですが、 該当するものが見つけられず、VBAも初心者のため、 途方にくれています。 ぜひともご教授ください。

  • エクセルのグラフで可能でしょうか?

    エクセルのグラフを利用して以下のことは可能でしょうか? 簡単な例で説明させていただきます。 エクセルA列には商品名     B列にはすべて【1】を入力。 たとえば A     B りんご  1 みかん  1 メロン  1 すいか  1 を基本に円グラフを作成すると グラフは90度で4分割したものができると思います。 その角度は固定をしたままで C列に それぞれの在庫の有無を入力したとします。 たとえば A     B   C りんご  1   有 みかん  1   無 メロン  1   無 すいか  1   有 すると、りんごとすいかのグラフが色づき みかんとめろんは色がつかない それにより、グラフの色づきで在庫の有無を確認する そういったような使い方をしたいのですが、 このようなことは可能でしょうか? よろしくお願いいたします。

  • エクセルVBA 条件にあうときセルを塗りつぶすには?

    エクセルVBA 条件にあうときセルを塗りつぶすには? エクセルVBAについて教えてください。 _________A 列 _________B 列_________C列_________D列 -------------------------------------------- 1行| 基準値_________ 5_____________1____________8 2行| りんご____________1_____________9____________0 3行| みかん___________12___________5____________3 4行| ぶどう____________15___________7____________8 5行| バナナ____________3_____________1____________4 上図のようにデータがあります。 (実物は列行共に膨大です。また条件を4つ以上つける予定なので条件付書式は使えません) 各列の基準値に対して、セルの増減が、0以下のときに黄色に、5から8のとき大きくなるときに赤、9以上のときに青にセルの色を塗りつぶしたいです。 どのようにすればよいでしょうか? B列の場合、基準値が5です。 B2のセルの場合、基準値5と1(B2セル)の増減は-4です。 増減が0以下のときは黄色に、増減が5から8のときは赤に、増減が9以上のときに青にするので、このときは黄色に塗りつぶします。 B3のセルの場合、基準値5と12(B3セル)の増減は7です。 増減が5から8のとき赤に塗りつぶすので、このセルは赤に塗りつぶします。 B4のセルの場合、基準値5と15(B4セル)の増減は10です。 増減が9以上のとき青色に塗りつぶすので、このセルは青色に塗りつぶします。 C2のセルの場合は、C列の基準値は1(C1セル)です。 基準値1と9(C2のセル)の増減は8です。 増減が5から8のとき赤に塗りつぶすので、このセルは赤に塗りつぶします。 よろしくお願いいたします。

  • エクセルVBA 集計

    事情がありピボットテーブルを使用しないで実現したいです シート1のドロップダウンリストで集計したい項目を2つ選択(15項目中) 例えば、項目1が色、項目2が形と選択 シート2に500件程(数が増える)のデータがあり、シート3へ集計 (シート3)  A | B | C | D |・・・・・・ 1|色|数|形|数|・・・・・・ 2|赤|30|○|10| 3|青|20|△|20| 4|白|40|□|30| 5|黄|40| ・ ・ シート1で設定した項目1でシート3の1行目を参照し、合致したデータをシート4のA列、B列に貼り付け シート1で設定した項目2でシート3の1行目を参照し、合致したデータをシート4の1行目、2行目に貼り付け 数値は例えばC3なら赤で○のものを表示 (シート4)  A | B | C | D |・・・・・・ 1| |   形  |・・・・・ 2| | |○|△|□| 3| |赤|20|10|16| 4|色|青|10|15|23| 5| |白|14|15|35| 6| |黄|17|15|35| ・ ・ このような感じでシート4を作るVBAをご伝授ください。 シート1、シート2、シート3は出来ているので大丈夫です。 稚拙な説明ですいません。 よろしくお願いいたします。

  • エクセルVBA 繰返し処理

    下記のようにA、B列があって、B列の”くさっている”をB列の一番下のセルから順番に調べていき、最後に”くさっている”ものとしてA列の”いちご””りんご”をメッセージボックスに出力するような方法を教えて下さい。 ちなみに列の指定は列全体です。 また、コマンドボックスをクリックした時にこのメッセージがでるようにしたいです。 A列   B列 みかん りんご くさっている いちご くさっている めろん

  • 【Excel】ユニークでないキーを元に照合

    A列にユニークでないキーが複数あり、B列には5つの種類があります。 (例)     A  B 1 りんご 赤 2 りんご 青 3 りんご 黄 4 みかん 橙 5 ばなな 黄 6 ばなな 青 7 キウイ 緑 これを、C列のユニークキーで、D列(EやFを使っても可)にB列にある種類を表示させたいのです。 (例)    C   D E  F 1 りんご 赤 青 黄 2 みかん 橙 3 ばなな 黄 青 4 キウイ 緑 なにか良い方法はありますでしょうか? If関数とVlookup関数の組合せで試してみたのですが、3つ以上ある場合もあり、うまくいきませんでした。 ご教示いただけますと幸いです。よろしくお願い致します。

  • エクセル2003のVBAで困っています。

    エクセル2003のVBAで困っています。 D3~D50の中で○のセルが合った場合にその行のA列~C列までのセル背景を青く塗るようにしたいです。 ちなみに△の場合は黄色で×の場合は赤色でそれ以外の場合は塗色なしにしたいです。 上記の説明が分かにくいかもしれないので、もう少し具体例を言います。 D3~D50の中でD5が○だったらA5~C5の背景を青色 D10が△だったらA10~C10の背景を黄色 D15が×だったらA15~C15の背景を赤色 D20がそれ以外だったらA20~C20の背景を塗色なし を各行(D3~D50)になるようにしたいです。 以上ですが、急ぎですので誰かお願い致します。

  • エクセル 複数条件 VBA

    VBAと関数の両方を教えていただきたいです。 シート”DATA”に以下の入力フォームがあります。 A列には日付 B1には”りんご”、B2以降には数量 C1には”みかん”、C2以降には数量 D1には”なし”、D2以降には数量 シート”照会”に以下の照会画面があります。 B1には開始日、D1には終了日 A2には”りんご” A3には”みかん” A4には”なし” B2以降はそれぞれの開始日から終了日までの個数が入るようにしたいのです。 例えば、シート”DATA”に毎日10が入力されていて、シート”照会”のB1に1/1、D1に1/3と入力されたら30、B1はそのままでD1が1/10なら100と果物ごとに表示されるようにしたいのですが、どうすればよいでしょうか。 よろしくお願い致します。

  • フィルタオプション、複数行のデータを抽出したい

    こんばんは n数色から、表と裏にランダムに色を割り当てたデータが入力されているとします。 下記のような場合です。 A列 B列 表  裏  赤  白 赤  黄 赤  緑 黄  赤 黄  白 黄  緑 ・ ・ ・ (以下略) このとき、「表が赤」もしくは「裏が赤」という条件で抽出したいのです。 複数行の場合におけるデータ抽出法がわからず、どのように操作すればよいか教えて頂きたいです。 excel 2003です

  • エクセル2010で 項目の抜き出しをしたい

    エクセル2010で 項目の抜き出しをしたいです。 たとえば、A列に りんご りんご バナナ トマト りんご バナナ みかん トマト メロン バナナ リンゴ みかん ぶどう とデータが入っているとき、これらのデータには、 トマト バナナ りんご リンゴ みかん メロン ぶどう という種類のデータが入っているということを簡単に表示する方法が知りたいです。 どうぞよろしくお願いします。