- ベストアンサー
エクセルマクロ◇別シートで個人ごとに数値の集計
EXCEL2003です。 以下のように、名前・個数・商品名(名前と商品名は重複あり)が列記されている EXCELのデータを、別シートで商品名の個数を個人ごとに集計したいと思っています。 ◇元データ◇ 名前 個数 商品 A子 2 りんご A子 1 りんご A子 3 みかん A子 2 みかん A子 1 メロン B子 1 みかん B子 1 みかん B子 2 メロン B子 4 キウイ ◇集計データ◇ 名前 りんご みかん メロン キウイ A子 3 5 1 B子 2 2 4 最初ピボットテーブルを使えばいいかと思っていたのですが、 これ以外にも元データから取得する値が出てくる予定のため、 できればマクロを組んで別シートに集計したいです。 よろしくお願いいたします。
- みんなの回答 (6)
- 専門家の回答
質問者が選んだベストアンサー
こんばんは! VBAでないので的外れなら読み流してください。 ↓の画像で説明させていただきます。 Sheet1のデータをSheet2にまとめるようにしてみました。 Sheet1に名前用と商品用の作業列を使わせてもらっています。 Sheet1のE2セルに =IF(COUNTIF($A$2:A2,A2)=1,ROW(A1),"") F2セルに =IF(COUNTIF($C$2:C2,C2)=1,ROW(A1),"") として、E2・F2セルを範囲指定し、F2セルのフィルハンドルで 下へずぃ~~~!っとコピーします。 (Sheet2の数式が1000行まで対応できるようにしていますので、そのくらいまでコピーしても構いません) 次にSheet2の商品名セルB1に =IF(COUNT(Sheet1!$F$2:$F$1000)<COLUMN(A1),"",INDEX(Sheet1!$C$2:$C$1000,SMALL(Sheet1!$F$2:$F$1000,COLUMN(A1)))) として列方向にコピーします。 名前セルのA2に =IF(COUNT(Sheet1!$E$2:$E$1000)<ROW(A1),"",INDEX(Sheet1!$A$2:$A$1000,SMALL(Sheet1!$E$2:$E$1000,ROW(A1)))) 商品のB2セルに =IF(OR($A2="",B$1=""),"",SUMPRODUCT((Sheet1!$A$2:$A$1000=Sheet2!$A2)*(Sheet1!$C$2:$C$1000=Sheet2!B$1),Sheet1!$B$2:$B$1000)) とし、列方向(商品名が空白でも構いません)にコピー 最後にA2~商品の列方向に数式をコピーした列の最後を範囲指定し、 最後の列のフィルハンドルで下へコピーすると 画像のような感じになります。 これで今後データが増えてもSheet2に反映されます。 以上、長々と書きましたが 参考になれば幸いです。m(__)m
その他の回答 (5)
- imogasi
- ベストアンサー率27% (4737/17069)
(1)関数でも出来そうなこと 名前と商品は、データーフィルターフィルタオプションの設定ー重複するレコードは無視するで、重複のないリストを作る。 さらに商品は、コピーー形式を選択して貼り付けー行と列を入れ替えるで横方向にデータを流す。 あとはA列と商品列第1行目の値で、2条件でカウントする。 SUMPRODUCTかCOUNTIF(2007)で出せる。 データ量が多いと重くなる心配はある。 他シートになる場合は、合計カウントを出す他シート側でフィルタオプションの設定をやる。 フィルタオプションの設定の操作がデータが増えても連動しない欠点は在る。 作業列をつかっって重複のないリストを作れば連動させられるが。 (2)ピボットでもデータ増減に対処して、再実行が出来ること (3)VBAでも、(普通は)再実行はしないとならないコードだろうこと など認識して、質問をしてますか。
- Wendy02
- ベストアンサー率57% (3570/6232)
こんばんは。 データ量によっては、#4さんのような数式の方に軍配が上がるかもしれません。私の方は、数千~1万行のデータを前提にしています。そのぐらいなら、数秒で終わります。それを超える場合は、少し内容を変えないといけません。 なお、元データは、ActiveSheet にしてください。 '------------------------------------------- Sub TestMacro1() Dim v As Variant Dim i As Long Dim j As Long Dim n As Long Dim sh2 As Worksheet '------------------------------------------- Set sh2 = Worksheets("集計データ") '注意集計データは一旦全部削除されます。 sh2.Cells.ClearContents '------------------------------------------- Application.ScreenUpdating = False With ActiveSheet.Range("A1").CurrentRegion .Columns(1).AdvancedFilter Action:=xlFilterInPlace, Unique:=True For Each v In .Columns(1).SpecialCells(xlCellTypeVisible).Cells i = i + 1 sh2.Cells(i, 1).Value = v Next .Columns(3).AdvancedFilter Action:=xlFilterInPlace, Unique:=True For Each v In .Columns(3).SpecialCells(xlCellTypeVisible).Cells j = j + 1 If j > 1 Then sh2.Cells(1, j).Value = v End If Next ActiveSheet.ShowAllData 'データの出力(データ量が多い場合は、以下を変更) For n = 2 To .Rows.Count i = Application.Match(.Cells(n, 1).Value, sh2.Columns(1), 0) j = Application.Match(.Cells(n, 3).Value, sh2.Rows(1), 0) sh2.Cells(i, j).Value = sh2.Cells(i, j).Value + .Cells(n, 2).Value Next n End With Application.ScreenUpdating = True sh2.Select End Sub
お礼
大変ご丁寧にご説明いただきありがとうございました。
- 某HN クロメート(Chromate)(@CoalTar)
- ベストアンサー率40% (705/1742)
- n-jun
- ベストアンサー率33% (959/2873)
関係ないかも知れませんが。 >これ以外にも元データから取得する値が出てくる予定のため、 この”予定”によって対応が変化する可能性もあり得るかと。 的はずれでしたらごめんなさい。
- nattocurry
- ベストアンサー率31% (587/1853)
項目行とデータ行の間に空行が無いもの(データが2行目から始まる)とすると、 こんな感じのマクロで、いけます。 Sub test() Dim Sh0 As Worksheet, Sh1 As Worksheet Set Sh0 = Worksheets("元データ") Set Sh1 = Worksheets("集計データ") Dim CellFound As Range Dim r0 As Long, r1 As Long, c1 As Long r0 = 2 Do Until IsEmpty(Sh0.Cells(r0, 1).Value) Set CellFound = Sh1.Columns(1).Find(What:=Sh0.Cells(r0, 1).Value, LookAt:=xlWhole) If CellFound Is Nothing Then With Sh1.Cells(Sh1.Rows.Count, 1).End(xlUp).Offset(1) .Value = Sh0.Cells(r0, 1).Value r1 = .Row End With Else r1 = CellFound.Row End If Set CellFound = Sh1.Rows(1).Find(What:=Sh0.Cells(r0, 3).Value, LookAt:=xlWhole) If CellFound Is Nothing Then With Sh1.Cells(1, Sh1.Columns.Count).End(xlToLeft).Offset(, 1) .Value = Sh0.Cells(r0, 3).Value c1 = .Column End With Else c1 = CellFound.Column End If With Sh1.Cells(r1, c1) .Value = .Value + Sh0.Cells(r0, 2).Value End With r0 = r0 + 1 Loop End Sub
お礼
画像までつけて説明していただきありがとうございました。 大変参考になりました。マクロではなくこの方法でいきたいと思います。