- ベストアンサー
VBAのマクロで、複数行を1行に集計
お世話になります。VBA初心者です。 下記のような表があった場合、請求書番号が同じものをVBAで1行に集計するにはどうしたらよろしいのでしょうか? 請求書No.|顧客名|摘要|金額 111111 |鈴木 | A |100 111111 |鈴木 | S |160 222222 |佐藤 | F |500 555555 |山田 | A |150 555555 |山田 | D |200 888888 |鈴木 | S |160 ↓下記のように集計 請求書No.|顧客名|摘要|金額 111111 |鈴木 | A |260 222222 |佐藤 | F |500 555555 |山田 | A |350 888888 |鈴木 | S |160 摘要は各請求書番号の最初の行を使います。重複は2行とは限りません。また、最終的に何枚の請求書があるのかも計算させたいのです。ただしこれはどこかに関数"=counta()"を使えばVBAでなくても出来るのですが。 よろしくお願いいたします。
- TENSAW
- お礼率79% (61/77)
- オフィス系ソフト
- 回答数5
- ありがとう数4
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
#4の回答者です。 >請求書No.はA列には無くまだ確定では何いのですがH列以降になる予定です。 それは、 Set myData = sh1.Range("A1").CurrentRegion ここで決めていきます。CurrentRegion ですと、地続きの範囲ということになって、A列から含まれてしまいますので、 Set myData = sh1.Range("H1", sh1.Range("H65536").End(xlUp).Offset( ,4)) というスタイルになります。 Offset( ,4) というのは、H列を含めて右へ4列 という範囲を示します。 sh1.Range("H65536").End(xlUp) というのは、H列の一番下のデータという意味です。 しかし、統合することは可能でも、出力のレイアウト自体が決まっていかないと、今のコードから、そんなに簡単に直せるとは言いにくいですね。 >金額はH列より後の列に入ります(予定ではI列)。 H列を基準に統合すると、現在のマクロですと、その隣の列に、集計の金額が出てきてしまいます。 また、数式は、以下の部分を直せばよいのですが……。 > sh2.Range(.Cells(2, 2), .Cells(.Rows.Count, 3)).FormulaLocal = _ > "=VLOOKUP($A2," & sh1.Name & "!" & myData.Address(1, 1) & ",COLUMN(B1),0)" > .Value = .Value =VLOOKUP($A2,Sheet1!$H$1:$K$7,COLUMN(C1),0) 例えば、こんな風にするには、 sh2.Range(.Cells(2, 3), .Cells(.Rows.Count, 4)).FormulaLocal = _ "=VLOOKUP($A2," & sh1.Name & "!" & myData.Address(1, 1) & ",COLUMN(C1),0)" .Value = .Value となります。 それを自由に出力列を変更できるようにするには、全面的にマクロコードを変更しなくてはならないような気がします。 今の段階では、例えば、こういうスタイルなら、 請求書No. 金額 顧客名 摘要 こういうスタイルで出てきてしまうことになってしまいます。
その他の回答 (4)
- Wendy02
- ベストアンサー率57% (3570/6232)
こんばんは。 例えば、集計をSheet2 に出すように作ってみました。 これは、フィルタオプションと統合を組み合わせれば簡単に出来ます。 他の方法もありますが、記録マクロの延長の方法です。ただ、空白部分の補完の方法などは、多少の技術は必要になってきます。 '標準モジュール Sub Test1() Dim sh1 As Worksheet Dim sh2 As Worksheet Dim myData As Range Dim tmpData As Range Set sh1 = Worksheets("Sheet1") Set sh2 = Worksheets("Sheet2") Set myData = sh1.Range("A1").CurrentRegion '出力する場所を削除しておく sh2.Range("A1").CurrentRegion.ClearContents 'フィルタオプションで、1列目のユニーク番号を取り出す myData.Columns(1).AdvancedFilter _ Action:=xlFilterCopy, _ CopyToRange:=sh1.Range("AA1"), _ Unique:=True '出力場所 Set tmpData = sh1.Range("AA1").CurrentRegion '統合 sh2.Range("A1").Consolidate _ Array(sh1.Name & "!" & myData.Address(1, 1, xlR1C1), _ sh1.Name & "!" & tmpData.Address(1, 1, xlR1C1)), _ xlSum, False, True, False 'VLOOKUPで、データの補完 myData.Rows(1).Copy sh2.Range("A1") With sh2.Range("A2").CurrentRegion sh2.Range(.Cells(2, 2), .Cells(.Rows.Count, 3)).FormulaLocal = _ "=VLOOKUP($A2," & sh1.Name & "!" & myData.Address(1, 1) & ",COLUMN(B1),0)" .Value = .Value '件数の出力 .Cells(1, .Columns.Count + 1).Value = "=""件数:""&COUNT(" & .Columns(4).Address(0, 0) & ")" End With tmpData.ClearContents Set myData = Nothing Set tmpData = Nothing Set sh1 = Nothing Set sh2 = Nothing End Sub
補足
実は例としてあげたものと実際のものとでは少し違いがありまして、請求書No.はA列には無くまだ確定では何いのですがH列以降になる予定です。A~Gまでにはその他の数値・記述(日付やメモ書き)が入り、集計したい金額はH列より後の列に入ります(予定ではI列)。 このような場合はどこをどう変えればよろしいのでしょうか? 毎回すみませんが、よろしくお願いいたします。
- imogasi
- ベストアンサー率27% (4737/17068)
VBAで (1)WorkSheetFunction.SUMIFを使う (2)総なめで11111(など)を探して足しこむ (3)請求書NOでソートして、並びがブレークするまで足しこむ (4)Find、FindNextで111111(など)を探して足しこむ。 人間が電卓で目で見て足す場合はこれでしょう。 などあるが(1)、(2)、(4)は請求書Noのユニークな(重複の無い)一覧がシート上に無いと、出てきた都度集計していると複数回同じこと(111111を集計)をしてしまう。 結局(2)が優れていると思う。ただデータ順序を崩すたくない場合は、作業シートにコピーしてそちらでやるか、初めに連番を振っておき、当初の並ぶ順にソートで戻す必要があるが。 (3)のロジックは、前行の請求書番号を変数に記録し、常に前行と現在行を比較し、 ・変わらない同じとき、合計変数に足しこみーー>次行へ ・変わったとき、前の行のA-C列を書き出しセルに代入(A) 合計の書き出し(B) 書き出し行を+1(下行を指す) 合計に現在行の計数足しこみ(0にして現在行の計数足しこみ) 前行変数に現在行データを書く -->次行へ 終わり行の後だけ、特別に(A)(B)を行う。 上記の意味が読んでわかったらすごいが。
お礼
早速のご回答に感謝いたします。 おっしゃるとおり私にはもう少し勉強が必要なようです。 現在の私には難しすぎますので、知識がつきましたら再度読み返させていただきます。 ありがとうございました。
- Golmore
- ベストアンサー率33% (1/3)
「ツール」→「統合」機能を使う方法もあります。 例)元データがA列~D列に記述されていると過程して、VBAで書くとこんな感じになります。 Range("F1").Consolidate Sources:="C1:C4", Function:=xlSum, LeftColumn:=True の1行を実行しただけで、請求番号ごとに集計された結果が、F列~I列 に出力されます。 ※顧客名・摘要列は無視されるので、G~H列は空白列になります。 あとは、CountIfで個数・VLookupで顧客名引っ張ってくればおおよそ 完成ですね。マクロでセル内に関数を書くのでもいいですし。
お礼
まず、びっくりしております。 まさにやりたいことが、こんなにシンプルに出来るとは思っても降りませんでした。サンプルデータで試してみましたが、本当にびっくりしました。 ただし、コラムが上記のサンプルと違い必要なデータがA列から4つ綺麗に並んでおりません。また、これ以外のマクロも色々と組んでおり、すこしフォーマットも考え直さないといけません。 現状ではこのまま使わせていただくことは出来ないのですが、このシンプルさはとても魅力に思っております。私はド素人なのでゴチャゴチャとくっつけては切捨ての繰り返しのためとても複雑なものを作りがちです。とっても参考になりました。本当にありがとうございました。
- kuma3f
- ベストアンサー率63% (28/44)
思われていることと違っていましたらすみませんが参考までに試してみてください。 Altキー押しながらF8キーを押します。 ↓ マクロのダイアログが表示されたらマクロ名に自由に名前を入力してください。(例:集計) ↓ 名前を入力しましたら、「作成」をクリック ↓ Microsoft Visual Basicの画面が開きますのでSub 集計()の下に次のコードをコピーして貼り付けてください。 Dim シート1カウント, 集計シートカウント, シート1件数, 金額, スイッチ As Long Dim シート名, 請求NO, 顧客名, 摘要 As String シート名 = ActiveSheet.Name スイッチ = 0 On Error GoTo skip1 Sheets("集計シート").Select スイッチ = 1 skip1: If スイッチ = 0 Then '集計シートが無かったら作成する Sheets.Add ActiveWorkbook.ActiveSheet.Name = "集計シート" End If Sheets("集計シート").Cells.ClearContents '集計 Sheets(シート名).Select シート1件数 = Application.WorksheetFunction.CountA(Worksheets(シート名).Range("A1:A65536")) シート1カウント = 1 集計シートカウント = 1 請求NO = Sheets(シート名).Cells(シート1カウント, 1) 顧客名 = Sheets(シート名).Cells(シート1カウント, 2) 摘要 = Sheets(シート名).Cells(シート1カウント, 3) 金額 = Sheets(シート名).Cells(シート1カウント, 4) シート1カウント = シート1カウント + 1 Do If 請求NO = Sheets(シート名).Cells(シート1カウント, 1) Then 金額 = 金額 + Sheets(シート名).Cells(シート1カウント, 4) Else Sheets("集計シート").Cells(集計シートカウント, 1) = 請求NO Sheets("集計シート").Cells(集計シートカウント, 2) = 顧客名 Sheets("集計シート").Cells(集計シートカウント, 3) = 摘要 Sheets("集計シート").Cells(集計シートカウント, 4) = 金額 集計シートカウント = 集計シートカウント + 1 請求NO = Sheets(シート名).Cells(シート1カウント, 1) 顧客名 = Sheets(シート名).Cells(シート1カウント, 2) 摘要 = Sheets(シート名).Cells(シート1カウント, 3) 金額 = Sheets(シート名).Cells(シート1カウント, 4) End If シート1カウント = シート1カウント + 1 Loop Until シート1カウント > シート1件数 Sheets("集計シート").Cells(集計シートカウント, 1) = 請求NO Sheets("集計シート").Cells(集計シートカウント, 2) = 顧客名 Sheets("集計シート").Cells(集計シートカウント, 3) = 摘要 Sheets("集計シート").Cells(集計シートカウント, 4) = 金額 集計シートカウント = 集計シートカウント + 1 Sheets("集計シート").Cells(集計シートカウント, 2) = "請求書枚数 = " & 集計シートカウント - 2 & "枚" Sheets("集計シート").Select MsgBox "集計しました。 請求書枚数 = " & 集計シートカウント - 2 & "枚です。" '****コピー貼り付けはここまで **** Microsoft Visual Basicの画面を×で閉じます。 使い方は、Altキー押しながらF8キーを押します。 マクロのダイアログが表示されるので先ほど名前を付けたマクロを選択して「実行」をクリック。 (選択されている状態でしたら、そのままEnterキーで実行されます。) 集計シートに結果が集計されていると思います。
お礼
>思われていることと違っていましたら… まさにこれがやりたかったことです。ありがとうございました。 色々な方法があるのですね、丁寧な補足説明付ですので色々とアレンジが出来そうです。 また、それぞれのマクロも他で流用できそうなものがございますので、ぜひ使わせていただきます。 本当にありがとうございました。
関連するQ&A
- 集計マクロ
こんにちは。 早速ですが、例えばこんなカンジです。 [元データ(Sheet1)] [1] 鈴木| 佐藤| 山田|・・・ [2] 茶 | 水 | | [3] 魚 | | 酒 | [4] | 肉 | 茶 | [5] 肉 | 茶 | 魚 | 上記のようなデータから↓↓↓ 1.行ごとに種類別に並べ替え 2.'=count(A2:D2)のような種類別の行集計列([数])を追加 3.[数]を基準に降順に並べ替え ↓↓↓ [集計データ(Sheet2)] [1] 鈴木| 佐藤| 山田|・・・| 数 [2] 茶 | 茶 | 茶 |・・・| 3 [3] 肉 | 肉 | |・・・| 2 [4] 魚 | | 魚 |・・・| 2 [5] | 水 | |・・・| 1 [6] | | 酒 |・・・| 1 お解かりいただけますでしょうか(・_・;)? 今までは作業列(商品名)を挿入し、[VLOOKUP]→[COUNT]→値貼付→並べ替え→不要な商品名(行・列)を削除していましたが、度々では面倒に思い、マクロを組もうと試みました。 ですが、まだまだマクロ勉強中の私自身の頭が整理しきれず、行き詰ってしまいました。 アドバイスでも結構です。お力をお貸しください。 よろしくお願いいたします。
- ベストアンサー
- オフィス系ソフト
- エクセル・マクロで、請求書番号ごとに集計する方法
請求書毎に集計した表をマクロで作りたいと思っています。 例えば、 取引先 請求書No 商品 売上 山田 0001 りんご 100 山田 0001 なし 200 山田 0001 みかん 300 鈴木 0002 りんご 100 鈴木 0002 バナナ 200 山田 0003 みかん 100 というデータがあるとします。 その場合 取引先 請求書No 売上 山田 0001 600 鈴木 0002 300 山田 0003 100 というように、請求書毎に、売上の合計と取引先名などが分かるように集計した表を作成したいと思っています。 請求書番号は、基本的には連番ですが、すこし飛ぶ可能性がありますし、 毎月、どのくらいの番号まで付番するのかははっきりしません。 また、請求書毎に、どれだけの種類の製品を出荷するのか(請求書毎に、何行になるのか)も不確定です。 ピポットですと、取引先名が表示されません。 また、所定の表を作って自動集計するというよりは、マクロで請求書毎に集計したほうが良いかと思っています。 基本的なコードや考え方を教えて頂けないでしょうか。 宜しくお願い致します。
- 締切済み
- Excel(エクセル)
- エクセル アンケート集計について
回答者 問 回答 鈴木 Q1 F 鈴木 Q2 50 鈴木 Q3 東北 山田 Q1 M 山田 Q2 30 山田 Q3 関東 佐藤 Q1 F 佐藤 Q2 40 佐藤 Q3 中国 ↓ Q1 Q2 Q3 鈴木 F 50 東北 山田 M 30 関東 佐藤 F 40 中国 このように集計したいです。 どのようにしたら簡単にできるのでしょうか?? お分かりの方おしえてください~~
- ベストアンサー
- オフィス系ソフト
- データの集計についてVBAマクロを組んでください。
下記のようにA列に金額 B列に欄No.があります。VBAマクロで集計した結果を出すマクロの記述の仕方を教えてください。 金額 欄No. 232 1 1005 1 812 2 425 2 193 1
- 締切済み
- Visual Basic
- 桐の集計(集計行設定のこと)について教えて下さい
こんにちは。 Winで桐8を使ってます。 集計(集計行)のことを教えて下さい。 データを、小計・中計・大計と行集計をかけました。 このときの中計の集計行に、小計の行数を入れることは可能でしょうか? 例)顧客番号、顧客種別、月、金額・・・・ のように同じ顧客が月別に、複数回入金します。 (入金されたデータは月別で複数行になります。) 小計は「顧客毎」に集計。 中計は「顧客種別毎」に集計。 このときに、中計の欄に、顧客種別毎の顧客数の実数(小計の行数)を入れたいのです。 今の私の知恵では、データ行の個数が出てしまい、同一の顧客番号が複数行あると複数でカウントしてしまうのです。 上手く説明できず恐縮ですが、ご教授くださると有り難いです。 よろしくお願いします。
- ベストアンサー
- その他(データベース)
- エクセルで自動入力をマクロで・・・(No.1798323の応用編)
応用が効かなくて申し訳ありません。 1798323で素敵なご回答をいただいたのですが、 状況が進展して変わってくるとVBAの書き換えがわからなくなりました。もう一度教えてください。 ※変更点は、入力元がAI列、『入力先をQ~V列に限定』したい点です。 Q R S T U V・・ AI 1 田中 鈴木 佐藤 山田 2 鈴木 山田 海岡 3 田中 佐藤 佐藤 というような表があり、T1に「山田」、S2「海岡」と、その行に関してAI列に新規の名前が入力されたときに自動入力することをVBAでどのように書けばよいのか、ご教授お願いいたします。 尚、3行目には「佐藤」さんがすでいるので入力不要です。 よろしくお願いします。
- ベストアンサー
- オフィス系ソフト
- 重複するidをデータごとにまとめるvbaのコード
excel vbaで次のようなコードを作りたいです。 シート1に元データが4000件ほどあります。 シート2に、シート1のidが同じものを、3行ずつ横に表示したいです。 idと名前は1度のみ、それ以降は都道府県名と数字のみ表示します。 同じidを持つものが3行に満たないのであれば、改行します。 同じidを持つものが3行以上ある場合は、3行ごとに改行します。 1 佐藤 東京 1000 1 佐藤 千葉 2100 1 佐藤 青森 1300 2 鈴木 東京 5600 2 鈴木 千葉 3500 3 山田 三重 2910 3 山田 長野 3820 3 山田 山口 8760 3 山田 沖縄 6560 4 : ↓ 1 佐藤 東京 1000 千葉 2100 青森 1300 2 鈴木 東京 5600 千葉 3500 3 山田 三重 2910 長野 3820 山口 8760 3 山田 沖縄 6560 4 : どなたかこのような動作を行うvbaのコードを教えてください。 よろしくお願いします。
- ベストアンサー
- Visual Basic
- 複数のシートのセル内容をひとつにまとめたい
複数のシートのセル内容をひとつにまとめたいと思っています。 Sheet1 Sheet2 Sheet3 1 山田 ¥100 1 山田 ¥80 3 鈴木 ¥80 2 佐藤 ¥130 2 佐藤 ¥55 4 田中 ¥150 3 鈴木 ¥110 4 田中 ¥60 こんなデータを Sheet4 1 山田 2 佐藤 3 鈴木 4 田中 とまとめたいんです。 金額は必要ないので、番号と名前だけをまとめたいんです。 どうすれば良いか、教えてください。 よろしくお願いします。
- 締切済み
- オフィス系ソフト
- エクセルの表の集計について
エクセルの『集計』や『ピボットテーブル』を使わずに、関数でやる方法があれば教えてください。 1 名前 住所 りんご みかん 2 山田 東京 1 3 3 鈴木 神奈川 3 8 4 佐藤 埼玉 4 10 5 山田 東京 5 5 6 佐藤 埼玉 6 5 とエクセルに表があるとします。 (7行目以降はデータが追加されるとします。) 別シートに下記のように名前ごとにりんご・みかんの数の合計を表に反映するようにしたいのです。 1 名前 住所 りんご みかん 2 山田 東京 6 8 3 鈴木 神奈川 3 8 4 佐藤 埼玉 10 15 説明不足のところがありましたら補足いたしますので、お願いいたします。
- 締切済み
- オフィス系ソフト
- エクセル 複数行にまたがっているデーターを一つの行
以前に似たようなVBAの質問を元にさらにやりたいVBAがあるのですが、 (前の質問者のURL:http://okwave.jp/qa/q4955096.html) A列 B列 C列 D列 E列 ~ R列 1行目 佐藤 北海道 りんご S 100 105 2行目 佐藤 北海道 ばなな M 100 105 3行目 伊藤 東京 いちご S 100 105 4行目 伊藤 東京 ばなな M 100 105 上記のようなデーターがあります。これを2行目と4行目を削除し下記のようにしたいのですが A列 B列 C列 C列 1行目 佐藤 北海道 りんご,ばなな S,M 2行目 伊藤 東京 いちご,ばなな S,M A列とB列とE列~R列のデーターが同じでC列,D列,のデータが異なる場合、上記のように一行にまとめたいのです。関数やVBAで上記の処理を出来る方法がありますでしょうか。
- ベストアンサー
- オフィス系ソフト
お礼
いつも本当にありがとうございます。 細かい丁寧な説明なので本当に助かっております。 結局、請求書番号をA列に持ってきて、集計をした後に前回教わったマクロを使い、さらに新しいシートに並べ替えることにしました。 今後ともよろしくお願いいたします。