お世話になります。
エクセルVBAでのコード作成について質問です。
以下のデータから条件付きで件数をカウントしたいです。
A B C D
20171010 東京 佐藤 10000
20171012 大阪 鈴木 1500
20171017 東京 田中 20000
・
・
・
A列は日付データ、B列は都市名(全部で5種類程度)、C列は個人名(10名ほど)、D列は金額
以上のようなデータです。
これをA列から、その日付がその月の何週目にあたるのかを検出し、その週でC列の人名とB列の都市が一致する場合にその合計を計算し、その一致の件数をカウントしたいと考えています。
実際週検出から個人名、都市名での金額合計は出せるのですが、件数のカウントがうまくいきません。
このように複条件で、キーとなるものも複数あるような場合のカウントのコードはどのように作ればいいでしょうか?ご教授いただけると幸いです。
宜しくお願い致します。
No.5ベストアンサー
- 回答日時:
No3です。
同一シートに出力したいとのことですが、とりあえず、
Sheet1を入力シート、Sheet2を出力シートにしたマクロを提示します。
>複数条件、複数キーでのカウントのコードがわかれば全体の絵は描くことができる状態です。
ということなので、これを加工して使用してください。
Sheet1,Sheet2が存在しないとエラーになりますのでご注意ください。
以前のSheet2の内容は破棄されますのでご注意ください。
なお、
Set sh2 = Worksheets("Sheet2")
の箇所を
Set sh2 = Worksheets("Sheet1")
のようにすれば、Sheet1へ出力することも可能です。(以前のSheet1の内容は破棄されますのでご注意ください。)
以下のマクロを標準モジュールへ登録ください。
多分、集計の方法はあなたが想像していたものと、異なるかと思いますが、
このようなケースは、連想配列が有効です。
-----------------------------------------------------
Option Explicit
Public Sub 週単位集計()
Dim sh1 As Worksheet '入力シート
Dim sh2 As Worksheet '出力シート
Dim dicT As Object 'キー:週+都市名+氏名(10月1週|東京|佐藤) 値:合計金額
Dim dicC As Object 'キー:週+都市名+氏名(10月1週|東京|佐藤) 値:合計件数
Dim maxrow As Long
Dim key As Variant
Dim row As Long
Dim elm As Variant
Set sh1 = Worksheets("Sheet1")
Set sh2 = Worksheets("Sheet2")
Set dicT = CreateObject("Scripting.Dictionary") ' 連想配列の定義
Set dicC = CreateObject("Scripting.Dictionary") ' 連想配列の定義
'最終行取得
maxrow = sh1.Cells(Rows.Count, 1).End(xlUp).row
'最終行まで繰り返す
For row = 1 To maxrow
key = GetMonthWeek(sh1.Cells(row, "A").Value) & "|" & sh1.Cells(row, "B").Value & "|" & sh1.Cells(row, "C").Value
If dicT.exists(key) = False Then
dicT(key) = sh1.Cells(row, "D").Value
dicC(key) = 1
Else
dicT(key) = dicT(key) + sh1.Cells(row, "D").Value
dicC(key) = dicC(key) + 1
End If
Next
'集計分を出力する
sh2.Cells.Clear
row = 1
For Each key In dicT
elm = Split(key, "|")
sh2.Cells(row, "A").Value = elm(0)
sh2.Cells(row, "B").Value = elm(1)
sh2.Cells(row, "C").Value = elm(2)
sh2.Cells(row, "D").Value = dicT(key)
sh2.Cells(row, "E").Value = dicC(key)
row = row + 1
Next
MsgBox ("完了")
End Sub
'指定日に対する月と週を返す(例 10月1週)
Public Function GetMonthWeek(ByVal date0 As Date) As String
Dim mm As Long
mm = Month(date0)
GetMonthWeek = CStr(mm) & "月" & CStr(GetWeekNumber(date0)) & "週"
End Function
'指定日がその月の第何週かを返す
Private Function GetWeekNumber(ByVal date0 As Date) As Long
Dim yyyy As Long
Dim mm As Long
Dim dd As Long
Dim date1 As Date
'1日のシリアル値を取得
yyyy = Year(date0)
mm = Month(date0)
date1 = DateSerial(yyyy, mm, 1)
GetWeekNumber = WorksheetFunction.WeekNum(date0) - WorksheetFunction.WeekNum(date1) + 1
End Function
ありがとうございました。私が想像したものとは違う方向性で提示していただき、目から鱗が落ちるような思いです。VBAの奥深さを教えていただきました。
No.4
- 回答日時:
こんばんは。
この質問は、どうしてもVBAなのでしょうか。
私の回答は、VBAが主ですが、見ていると、全体として表にすることだとすると、関数でやってよいのではないかと思っています。
要求しているレイアウトとも違いますので、参考まででも構いません。
添付画像を御覧ください。
①
A列の日付データが、単に数値の場合は、
F列で「日付シリアル値」にして、
=TEXT(A1,"##!/##!/##")*1
G列で、第何週目としています。
=MONTH(F1)&"月"&WEEKNUM(F1)-WEEKNUM(F1-DAY(F1))&"週目"
黄色の部分は、任意で書き換えするなり、横に広げてください。
②
金額 B3から
=SUMIFS(Sheet1!$D$1:$D$10,Sheet1!$G$1:$G$10,$A3,Sheet1!$B$1:$B$10,$B$1,Sheet1!$C$1:$C$10,$C$1)
③
件数 C3から
=COUNTIFS(Sheet1!$G$1:$G$10,$A3,Sheet1!$B$1:$B$10,$B$1,Sheet1!$C$1:$C$10,$C$1)
ありがとうございます。今回の質問で作ったデータを二次利用するのが目的なので表という形がそぐわなかったのですが、このような表現の仕方もあるのだと勉強させていただきました。
No.3
- 回答日時:
No2です。
補足要求の追加です。日付は、同年のみですか。年が異なり、月が同じケースは考慮しなくてよいのですか。
例えば、
20161010 東京 佐藤 10000
20171010 東京 佐藤 10000
で、仮に両方とも10月の2週だとすると
10月2週 東京 佐藤 20000 2
のようになりますが、それで良いのでしょうか。
No.2
- 回答日時:
補足に対して全ての回答をいただいておりません。
1)入力データの1行は、見出しではなく、いきなりデータなのでしょうか。
2)同一シートに結果を書き出すとすると、
入力データの最後の行の次に、結果を書き出すのでしょうか。
通常、このような場合は、入力データの最後の行を事前に取得し、その最後の行まで1行単位の処理を
繰り返すことにより、処理結果を得ることができます。
ところが、入力データの最後の行の次に、結果を書き出してしまった場合、
再度、マクロをリラン(再実行)した時に、結果を書き出した行も、入力データとして扱ってしまします。
その為、同一シートに書き出すなら、列をすこし開けて、H列(10月1週)、I列(東京)、J列(佐藤)、のようにすべきです。
3)入力データが以下の場合
A B C D
20171010 東京 佐藤 10000
20171012 大阪 鈴木 1500
20171013 東京 佐藤 5000
20171014 東京 鈴木 1000
20171017 東京 田中 20000
結果は
H I J K L
10月2週 東京 佐藤 15000 2
10月2週 東京 鈴木 2500 2
10月3週 東京 田中 20000 1
であってますか。
週の始まりは日曜日とする。
2017/10/1が日曜日なので、
2017/10/1~2017/10/7 ・・1週
2017/10/8~2017/10/14 ・・2週
2017/10/15~2017/10/21 ・・3週
となります。
3)入力データの日付が、20171010と提示されていますが、
これは、書式設定でyyyymdと設定してあると解釈して宜しいでしょうか。
4)日付は昇順に並んでいる前提で良いですか。
No.1
- 回答日時:
カウントした結果はどのように表示したいのでしょうか。
同じシートへ表示ですか。それとも別シートですか。
入力データに対応した表示例を提示していただけますか。
又、入力データの1行目は見出しですか。それとも、いきなりデータですか。(見出しが無いように見えます)
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Excel(エクセル) Excelでの複数条件のカウントについて 1 2022/09/25 07:40
- Excel(エクセル) Countifよりも早く重複数をカウントする方法ありますか? 18 2022/07/04 13:39
- Excel(エクセル) Excel(エクセル)でフィルター抽出後、非表示の行を計算しないで、合計を算出する方法 【内容】 添 4 2023/01/30 17:17
- Excel(エクセル) エクセル・スプレッドシートで、一定数を超えたらゼロから再累計する方法 8 2022/05/28 03:52
- Excel(エクセル) 【困っています】VBA 追加処理の記述を教えてください。 1 2022/08/25 22:54
- Visual Basic(VBA) VBA シート間の転記で、条件の追加コードの書き方について教えて下さい。 13 2023/02/26 09:31
- その他(Microsoft Office) 【スプレッドシート】白色のセルをカウントしたい 2 2023/02/24 07:39
- Excel(エクセル) 【Excel質問】 「本日の日付」から指定条件を満たす営業日経過後の日数を表示させる関数式 3 2022/06/06 23:28
- Visual Basic(VBA) 3つの条件を指定してVBAで行を削除したい 条件1:分類1が重複 条件2:分類2が重複 条件3:個数 6 2022/06/24 11:07
- その他(コンピューター・テクノロジー) googleスプレッドシートでカッコ内の文字数をカウントしたい 1 2023/01/17 15:52
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
エクセルでの作業計算方法について
-
Microsoft1Officeの互換ソフト...
-
【マクロ】その時、その時で変...
-
はがきについて。
-
【マクロ】読取専用のファイル...
-
エクセル初心者です 関数の入れ...
-
【関数】適切な文字数の数字を...
-
LOOKUP関数を使えばいいのでし...
-
【関数】先頭だけにある、半角...
-
Excel ピボットテーブルで日付...
-
Excelのpivotについて質問です
-
時間によってファイル名が変わ...
-
エクセル 白黒印刷で白線を印刷...
-
Aというブックの1というシート...
-
エクセル関数を教えてください
-
WPS OFFICEでの縦書きについて
-
Excelのチェックボックスの使い...
-
エクセルの条件付き書式につい...
-
エクセルのセルに同じ大きさの...
-
エクセルの関数について教えて...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
Excel 2019 のピボットテーブル...
-
[関数得意な方]教えて下さい・...
-
Excelにてある膨大なデータを管...
-
[関数について]わかる方教えて...
-
Excel初心者です。 詳しい方、...
-
excelの不要な行の削除ができな...
-
エクセル関数に詳しい方教えて...
-
INDIRECTを使わず excelで複数...
-
[オートフィルタ]で抽出された...
-
エクセルの神よ、ご回答を! エ...
-
エクセル関数に詳しい方、教え...
-
各ページの1番上の表示について
-
Excelで写真のような表を作った...
-
エクセルで不等号記号(≠)が上に...
-
数学 Tan(θ)-1/Cos(θ)について...
-
Excel 2019 は、SPILL機能があ...
-
Excelで全角を半角にしたいので...
-
条件付き書式を教えてください
-
Excel フィルターを掛けた状態...
-
[オートフィルタ]の適用範囲の...
おすすめ情報
tatsu99さんからいただいた質問に対しての補足です。
最終的には同一シートに書き出すつもりです。
書き出しの絵は
A B C D E
10月1週 東京 佐藤 15000 1
のようにし、カウント数は最後のE列に容れたいと考えています。
宜しくお願い致します。
重ねての補足になります。
tatsu99さん、抜けと言葉足らずなことをお詫びします。
1)については、いきなり見出しになります。先の補足で記入を忘れていました。申し訳ありません。
2)について、特に新しい列に書き出すことを考えていません。というのもこのコードで書き出したデータを編集後CSVにしてほかのエクセルに注入すること想定していますので。
何週目かのコードに関しては
週= Int((日 - 2 + Weekday(DateSerial(年, 月, 1))) / 7) + 1という形と何月かで、変数を指定して割り振りをする対応しています。
例;
3)日付のデータは標準型ですが、日付から第何週までの流れは自分の中では解決しています。
4)日付データは昇順です。
複数条件、複数キーでのカウントのコードがわかれば全体の絵は描くことができる状態です。
宜しくお願い致します。
No.3についての回答です。
このデータは一年間の累積を見るために作っています。ですので、 tatsu99さんがおっしゃられているような異年同月同日については考慮しなくても大丈夫です。
宜しくお願い致します。