• ベストアンサー

数量を足すマクロ

A列に商品名があり、B列に数量があります。 A列はあいうえお順に並んでいます。 A列には重複した商品名があり、重複した商品名の数量を足すことはできないでしょうか。 例 A---------B みかん   8 みかん   9 りんご   10    ↓ 結果として、 A----------B みかん   17 りんご   10 にしたいのですが、ずっと考えていても答えが導け出せないので質問しました。 よろしくお願いします。

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

  • ベストアンサー
noname#31658
noname#31658
回答No.6

サンプルです。 シート1のA2~最終行を対象にD,E列に書き出します。 並べ替えは必要ありません。 Sub Test() Dim Dic As Object Dim i As Long Dim a As Long Dim b As Long Dim v As Variant Dim x As Variant With Worksheets("Sheet1")    v = .Range("A2", .Range("A65536").End(xlUp)) _           .Resize(, 2).Value End With Set Dic = CreateObject("Scripting.Dictionary") For a = 1 To UBound(v, 1)    If Not Dic.Exists(v(a, 1)) Then       i = i + 1       Dic(v(a, 1)) = i       v(i, 1) = v(a, 1)       v(i, 2) = v(a, 2)    Else       b = Dic(v(a, 1))       v(b, 2) = v(b, 2) + v(a, 2)    End If Next Worksheets("Sheet1").Range("D2:E2").Resize(i _               ).Value = v End Sub

caim
質問者

お礼

ご回答ありがとうございます。 早速、noname#31658様のサンプルを試してみます。 本当にありがとうございました。

その他の回答 (7)

  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.8

こんにちは。 少し、私の今回の#7 のマクロについて説明をさせていただきます。 このマクロは、某VBA専門掲示板で、数年前に、さまざまなアイデアが出たときに、私は、その時、出されたものを全て出して、時間計測して、これだと思ったものを提示しました。それを、今では「定番」と呼んでいますし、また、これは、ツール-マクロ-新しいマクロの記録 で作れるものです。 ご質問者さんが、タイトル行と範囲さえ決めてあれば、そのまま、何も考えなくてよいのです。 > Const flgTITLE As Boolean = False '1行目タイトル行False=ナシ,True=アリ > Const flgTITLE_REMAIN As Boolean = True 'タイトル行を残す=True, ナシ =False などと、持って回った書き方はしていますが、記録マクロは、どんなに頭をめぐらしても結果自体はそれほど変わりませんので、コマンド自体にお任せをしてしまってよいわけです。 しかし、これでは、本当は、記録マクロでは、VBAの練習にはなりませんね。練習用というのは、「For i = 1 to 行数終わり まで」で作っていきますが、こういう基礎練習もまた必要かと思います。その時に、記録マクロは、良い場合とそうではない=何もならない、ことがあります。 オートメーションの "Dictionary" オブジェクトを使ったもので、これは、だいたい、VBAを一通り卒業しないと、ちょっと厳しいわけで、それに比較すると、こちらのマクロは、初心者の方でも作れるということなのです。

caim
質問者

お礼

記録マクロで作成するよりもやはりVBAで構文などを一から考え、作成したほうが勉強になります。 ご回答ありがとうございました。

  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.7

こんばんは。#4 です。 一応、時間切れとして、実務用のものを出しておきます。 #2さんの書いたものを、そのままマクロにしました。実験してみると、この方法が一番速いはずです。しかし、データ1万件程度では、あまり差がありません。練習用は、あくまでも、ループで解決したほうがよいです。以下のようなものは、定番マクロで、考える必要はありません。 なお、Const のフラッグに関しては、あまり考えなくてよいです。特別なオプションにしたいときのみ必要になるだけです。 Sub SampleTotal()   Const flgTITLE As Boolean = False '1行目タイトル行False=ナシ,True=アリ   Const flgTITLE_REMAIN As Boolean = True 'タイトル行を残す=True, ナシ =False      Application.ScreenUpdating = False   With ActiveSheet     On Error Resume Next     .Range("A1").CurrentRegion.Columns("C:D").ClearContents     On Error GoTo 0     If flgTITLE = False And .Range("A1").Value Like "*項目*" = False Then       .Rows(1).Insert Shift:=xlDown       .Range("A1").Offset(0).Resize(, 2).Value = Array("項目", "個数")     End If     .Range("C1").Consolidate _     Sources:=.Range("A1").CurrentRegion.Address(1, 1, xlR1C1), _     Function:=xlSum, _     TopRow:=True, _     LeftColumn:=True, _     CreateLinks:=False     If flgTITLE = False And flgTITLE_REMAIN = False Then       .Rows(1).Delete     Else       .Range("A1").Resize(, 2).Copy .Range("C1")     End If   End With   Application.ScreenUpdating = True End Sub このほかに、配列のアルゴリズムで処理する方法やAdvancedFilter で、重複のない項目を出して、それで、SUMIF 関数を使う方法などがありますが、この方法が最も速いはずです。

caim
質問者

お礼

ご回答ありがとうございます。 マクロでの回答をお待ちしていましたので、とても助かります。 早速、Wendy02様の回答を使ってみたいと思います。 ありがとうございました。

noname#31658
noname#31658
回答No.5

定番ならDictionaryかAdvancedFilterでしょう。 大量データの場合はAdvancedFilterのほうが早いと思います。

caim
質問者

お礼

もう少し噛み砕いて回答してくださると嬉しいです。 何しろ知識がないもので……。 ご回答ありがとうございました。

  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.4

こんばんは。 それは、マクロの練習問題なのでしょうか? もしそうだとするなら、問題としては「暫定的にアリ」のような気がしますね。 この種の問題というのは、入門編として好んで出されるような気がします。(私は、こういうようなものは出しません。これが出来るぐらいなら、プログラムの経験がある人で、それほど苦労なく出来ます。) 問題の条件としては、 並べ替えられている、関数は使わない、記録マクロを使わない、ループを使う、結果は別のシートに出す、というところでしょうか? 入門編としては、もし、私が入門レベルの頃を思い出すと、正直言って、たぶん出来ないかもしれませんね。使うものは、単に、For ~ to のループを使うだけです。 しかし、マクロの勉強としては、10分考えて、頭の中で何もアイデアが生まれないようだったら、解答をみて、それを参考にしたほうがよいです。 実務的には、「統合」を使ってしまうように思います。ただし、「統合」は、同じ場所に貼り付けることは出来ません。 ずっと考えているなら、考えた途中まで出したほうがよいと思います。 そうでないなら、こちらは、そのままにしておきます。

caim
質問者

お礼

マクロの練習問題というか、仕事上でこういった処理をすることが多く、自動化を図れないものか、と考えていたのです。 しかしVBAについての知識が乏しく、いくら考えても構文エラーなどが出てしまい、さらにデバックなどの知識も不足しているため、質問した次第です。 ご回答ありがとうございました。

  • Nayuta_X
  • ベストアンサー率46% (240/511)
回答No.3

SUMIF の使用方法 例; データ配置が下記の場合 A B みかん  8 みかん  9 りんご  10 ・・・・・・・・・・・・・・ 追加した後 A B 1みかん  8 2みかん  9 3りんご  10 11みかん  12りんご  ・・・・・・・・・・・・・・・・・ 式を入れた後 11みかん  =SUMIF(A2:A4,A11,B2:B4) 12りんご  =SUMIF(A3:A5,A12,B3:B5) 注意; 左端の番号は、行番号です。 解説 11 みかん は、A11 で、式(=SUMIF(A2:A4,A11,B2:B4)は、B12です。 参考まで。

caim
質問者

お礼

例では記載できていなかった事項があり、SUMIF関数では回答が導き出せませんでした。 ですが、再度そのような関数があることを知り、とても役に立ちました。ご回答ありがとうございました。

  • ka_na_de
  • ベストアンサー率56% (162/286)
回答No.2

マクロを使わない方法を紹介します。  1) 1行目を挿入し、A1・C1セルに「項目」、B1・D1セルに「個数」と見出しをつける。  2) C1・D1セルを選択し、上部メニューから「データ」→「統合」を選択  3) 「集計の方法」は「合計」を選択     「統合元範囲」をA1B1以下のデータを選択し「追加」     「統合の基準」で「上端行」「左端列」にそれぞれチェックして「OK」 マクロの方法が知りたければ、質問を締め切らないで下さい。 すぐに誰かが回答してくれると思います。

caim
質問者

お礼

統合という使い方があるのを始めて知りました。 これはこの場面だけではなく、知っていると便利ですね。 ありがとうございます。 マクロの勉強中でもありますので、なんとかマクロでできないものか、と考えてしまいエクセルの機能自体について考えていませんでした。 ご回答ありがとうございます。

回答No.1

マクロまでつかわなくともsumif()で事足りるんじゃ?

参考URL:
http://kokoro.kir.jp/excel/sumif.html
caim
質問者

お礼

お礼が遅くなりすみません。 行数が1000行近くあり、品名も長く種類が多いのでSUMIF関数では無理だと思います。質問内容の不足で適切に質問できていませんでした。すみません。

関連するQ&A