[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]
『表を細かく分類抽出していくつもの表を作成』(たま)
いつもエクセルの学校と皆様の書き込みで勉強させていただいています
大がかりな内容になってしまいますが、以下のようなVBAコードは作成できるのでしょうか?
内容
表を細かく分類抽出していくつもの表を作成しています
列項目は以下の通り
A列 B列 C列 D列
コード 部所名 売上項目 金額
抽出に関係ない列は10列以上ありますが割愛)
コードは本来36コードありますがとりあえず100、110、H01の三つとし
部所名も50項目ほどありますがとりあえず営業所、A工場、B工場、製造部の4つとします
売上項目は、売価、原価 2項目です
コードと部署名には組み合わせがあり
営業所 100、110、H01
A工場 100、H01
B工場 110、H01
製造部 100、110、H01
となります
各コードには売上項目に 売価、原価 がそれぞれあります
上記を踏まえ以下の表があります
A列 B列 C列 D列
コード 部所名 売上項目 金額
100 A工場 原価 500
H01 A工場 原価 500
110 B工場 原価 750
H01 製造部 原価 900
100 営業所 売価 5000
110 製造部 原価 5050
110 営業所 売価 5060
100 営業所 原価 7000
100 B工場 売価 8060
H01 B工場 売価 8060
100 A工場 売価 15000
H01 営業所 売価 15800
110 営業所 売価 25000
110 製造部 売価 35600
100 営業所 売価 80000
100 製造部 売価 150000
これを以下の様に集計します
コード 部所名 売上項目 金額
100 営業所 売価 5000
100 営業所 売価 80000
100売価計 85000
100 営業所 原価 7000
100原価計 7000
110 営業所 売価 5060
110 営業所 売価 25000
110売価計 30060
H01 営業所 売価 15800
H01売価計 15800
売上高 130860
売上原価 7000
粗利 123860
コード 部所名 売上項目 金額
100 A工場 売価 15000
100 B工場 売価 8060
100売価計 23060
100 A工場 原価 500
100原価計 500
110 B工場 原価 750
110原価計 750
H01 B工場 売価 8060
H01売価計 8060
H01 A工場 原価 500
H01原価計 500
売上高 31120
売上原価 1750
粗利 29370
コード 部所名 売上項目 金額
100 製造部 売価 150000
100売価計 150000
売上高 150000
売上原価 0
粗利 150000
コード 部所名 売上項目 金額
110 製造部 売価 35600
110売価計 35600
110 製造部 原価 5050
110原価計 5050
H01 製造部 原価 900
H01原価計 900
売上高 35600
売上原価 5950
粗利 29650
総売上高 347580
総売上原価 14700
総粗利 332880
小計、合計値は関数で表示されています
粗利は売上高-売上原価で表示させます
集計表を見てお分かりの通り、営業所、A工場とB工場、製造部でコードが100のもの、製造部でコードが110とH01のもの
で、コード単位でかつ売上項目単位で集計し、小計が入っています
また、集計表下部に売上高、売上原価をそれそれの小計を足して算出し、粗利は売上高−原価で算出しています
各コードごとに売価、原価があると書きましたが中にはないときもあり、コードそのものもない場合がありますが
その場合は集計小計を都度スキップします
長くなりましたがこんな集計をVBAで作成できるのでしょうか?
せめて集計が一つの表か、小計がなければいいのですが部署単位で表を作成し一つのシート内に作成
(縦に並べ、表と表の間を2行あけて作成します)しなければならないため困っています
現在は手作業で行うため工数がばかになりません
今回はデータを端折って書いていますが先にも述べた通り参照コードも部署も山ほどあり、件数も5千件を超えています
宜しくお願いいたします
< 使用 Excel:Excel2016、使用 OS:Windows7 >
>VBAで作成できるのでしょうか?
できるできないで言えばできるんじゃなないでしょうか。
ただ、マクロを作る作業の手間と手作業の手間を考えて釣り合うかは不明です。
ピポットテーブルの結果をコピーしてちょっと加工するくらいで、それほど手間とも思えないのですが
作業で行うため工数というか、一連の作業時間どのくらいかかってるんですか?
(もこな2) 2018/09/14(金) 15:28
※回答ではありませんすみません
>コードと部署名には組み合わせがあり >営業所 100、110、H01 >A工場 100、H01 >B工場 110、H01 >製造部 100、110、H01 >となります
ご提示のサンプルには「B工場」でコードが「100」のパターンが含まれてますね。 一応、サンプル上だけの誤りと解釈して進めます。
例えばなんですけど
__| ___A____ ___B____ ___C____ ___D____ ___E____ ____F_____ ____G____ ___H____ ___I____ 1| コード 部所名 売上項目 金額 Sort集計 Sortコード Sort売/原 Sort部所 小計区分 2| 100 A工場 原価 500 2 1 2 1 212原価 3| H01 A工場 原価 500 2 3 2 1 232原価 4| 110 B工場 原価 750 2 2 2 2 222原価 5| H01 製造部 原価 900 4 3 2 4 432原価 6| 100 営業所 売価 5,000 1 1 1 3 111売価 7| 110 製造部 原価 5,050 4 2 2 4 422原価 8| 110 営業所 売価 5,060 1 2 1 3 121売価 9| 100 営業所 原価 7,000 1 1 2 3 112原価 10| 100 B工場 売価 8,060 2 1 1 2 211売価 11| H01 B工場 売価 8,060 2 3 1 2 231売価 12| 100 A工場 売価 15,000 2 1 1 1 211売価 13| H01 営業所 売価 15,800 1 3 1 3 131売価 14| 110 営業所 売価 25,000 1 2 1 3 121売価 15| 110 製造部 売価 35,600 4 2 1 4 421売価 16| 100 営業所 売価 80,000 1 1 1 3 111売価 17| 100 製造部 売価 150,000 3 1 1 4 311売価
[Sort集計] ----集計表単位に番号を付番 「営業所」なら「1」 「A工場、B工場」なら「2」 「製造部でコードが100」なら「3」 「製造部でコードが110とH01」なら「4」 [Sortコード] --「コード」列の並び順を付番([コード]列そのまま使っても良いのかも。コードの内容によっては) [Sort売/原] ---「売上項目」列の並び順を付番(「売価」が「1」、「原価」が「2」) [Sort部所] ----「部所名」列の並び順を付番 (集計表で「部所名」が整列してなくて良いのならこれは不要)
[小計区分] ---- =[Sort集計]&[Sortコード]&[Sort売/原]&[売上項目]
として、 [Sort部所]を昇順並べ替えしてから [小計区分]を昇順並べ替え。その後、 [小計]機能で[小計区分]をグループの基準にして[金額]を集計し、 E列〜H列を非表示にしたら下表の様な感じになります。
__| ___A____ ___B____ ___C____ ___D____ _____I______ 1| コード 部所名 売上項目 金額 小計区分 2| 100 営業所 売価 5,000 111売価 3| 100 営業所 売価 80,000 111売価 4| 85,000 111売価 集計 5| 100 営業所 原価 7,000 112原価 6| 7,000 112原価 集計 7| 110 営業所 売価 5,060 121売価 8| 110 営業所 売価 25,000 121売価 9| 30,060 121売価 集計 10| H01 営業所 売価 15,800 131売価 11| 15,800 131売価 集計
12| 100 A工場 売価 15,000 211売価 13| 100 B工場 売価 8,060 211売価 14| 23,060 211売価 集計 15| 100 A工場 原価 500 212原価 16| 500 212原価 集計 17| 110 B工場 原価 750 222原価 18| 750 222原価 集計 19| H01 B工場 売価 8,060 231売価 20| 8,060 231売価 集計 21| H01 A工場 原価 500 232原価 22| 500 232原価 集計
23| 100 製造部 売価 150,000 311売価 24| 150,000 311売価 集計
25| 110 製造部 売価 35,600 421売価 26| 35,600 421売価 集計 27| 110 製造部 原価 5,050 422原価 28| 5,050 422原価 集計 29| H01 製造部 原価 900 432原価 30| 900 432原価 集計
31| 362,280 総計
これだけでも(VBA使わなくとも)、 完成イメージに近い所までは持って来れてるんじゃないのかな? と勝手に思ってるんですけど、 もっとサクッと「ボタン一つで完成!」みたいなのをお望みなのでしょうかね?
VBAでやるにしても 上記例の様に「集計表」を区分けする為の項目は単独で持たせておいた方が 組み立てが楽になるんじゃないかと思います。(結局言いたかったのはそれだけです^^;)
(白茶) 2018/09/15(土) 13:25
VBAにこだわる必要はないですが、
現在5時間ほどかけています
件数とコード数、部所が半端ないので
関数によるフラグ立てでもう少し効率よくできるかを
考えてみます
ありがとうございました
(たま) 2018/09/18(火) 16:37
'アクティブシートが対象(バックアップを忘れずに) '1行目は見出し(A1=コード 〜 D1=金額) '2行目以下がデータ Dim c As Range, r As Range, dic1 As Object, dic2 As Object, k For Each c In Range("A:A").SpecialCells(2) If InStr(c.Offset(, 1).Value, "営業所") > 0 Then c.Offset(, 4).Value = 1000 If InStr(c.Offset(, 1).Value, "工場") > 0 Then c.Offset(, 4).Value = 2000 If InStr(c.Offset(, 1).Value, "製造部") > 0 Then c.Offset(, 4).Value = 3000 If InStr(c.Value, "100") = 0 Then c.Offset(, 4).Value = 4000 End If If InStr(c.Value, "110") > 0 Then c.Offset(, 4).Value = c.Offset(, 4).Value + 100 If InStr(c.Value, "H01") > 0 Then c.Offset(, 4).Value = c.Offset(, 4).Value + 200 If InStr(c.Offset(, 2).Value, "原価") > 0 Then c.Offset(, 4).Value = c.Offset(, 4).Value + 10 Next c With ActiveSheet.Sort .SortFields.Add Key:=Range("B2:B" & Rows.Count) .SetRange Range("A1:E" & Rows.Count) .Header = xlYes .Apply End With Set dic1 = CreateObject("Scripting.Dictionary") Set dic2 = CreateObject("Scripting.Dictionary") dic2(5000) = "総売上高" dic2(5001) = "総売上原価" dic2(5002) = "総粗利" For Each c In Range("A2:A" & Rows.Count).SpecialCells(2) dic1(Val(c.Offset(, 4)) + 1) = dic1(Val(c.Offset(, 4)) + 1) + c.Offset(, 3).Value dic2(Val(c.Offset(, 4)) + 1) = c.Value & c.Offset(, 2).Value & "計" dic2(Left(c.Offset(, 4), 1) * 1000 + 990) = "売上高" dic2(Left(c.Offset(, 4), 1) * 1000 + 991) = "売上原価" If c.Offset(, 2).Value = "売価" Then dic1(Left(c.Offset(, 4), 1) * 1000 + 990) = dic1(Left(c.Offset(, 4), 1) * 1000 + 990) + c.Offset(, 3).Value dic1(5000) = dic1(5000) + c.Offset(, 3).Value Else dic1(Left(c.Offset(, 4), 1) * 1000 + 991) = dic1(Left(c.Offset(, 4), 1) * 1000 + 991) + c.Offset(, 3).Value dic1(5001) = dic1(5001) + c.Offset(, 3).Value End If dic1(Left(c.Offset(, 4), 1) * 1000 + 992) = dic1(Left(c.Offset(, 4), 1) * 1000 + 990) - dic1(Left(c.Offset(, 4), 1) * 1000 + 991) dic2(Left(c.Offset(, 4), 1) * 1000 + 992) = "粗利" dic1(Left(c.Offset(, 4), 1) * 1000 + 998) = "" dic1(Left(c.Offset(, 4), 1) * 1000 + 999) = "" Next c dic1(5002) = dic1(5000) - dic1(5001) Set r = Range("A" & Rows.Count).End(xlUp).Offset(1) For Each k In dic1 If InStr(k, "999") = 0 Then r.Resize(, 5).Value = Array("", "", dic2(k), IIf(InStr(k, "998") = 0, Val(dic1(k)), dic1(k)), k) ElseIf k <> 4999 Then r.Resize(, 5).Value = Array("コード", "部所名", "売上項目", "金額", k) Else r.Resize(, 5).Value = Array("", "", "", "", "") End If Set r = r.Offset(1) Next k With ActiveSheet.Sort .SortFields.Add Key:=Range("E2:E" & Rows.Count) .SetRange Range("A1:E" & Rows.Count) .Header = xlYes .Apply End With Columns(5).ClearContents End Sub (mm) 2018/09/19(水) 15:36
一か所
最後のソート部分を以下の様に直しましたところ完璧にこちらの希望通りになりました
.SortFields.Add Key:=Range("E2")
本来36コード
部所名50項目
は個別にソースを追加していけばいいですね
ただ数が多すぎてコードが大変なことになりそうです
ありがとうございました
(たま) 2018/09/20(木) 11:51
[ 一覧(最新更新順) ]
YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki.
Modified by kazu.