[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]
『VBA で集計』(m-o-mo)
Wd Xp エクセル2000です。 seiya さん
ありがとうございます。レスの続きをよろしくお願いします。
Sub test() Dim a, b, i As Long, ii As Long, iii As Long, myInd As Long Set wsData = Workbooks("dt.xls").Sheets("担当別") Set wsSummary = Workbooks("集計.xls").Sheets("予算") a = wsData.Range("a1", wsData.Range("a" & Rows.Count).End(xlUp)).Resize(, 6).Value2 With wsSummary.Range("a40", wsSummary.Range("a" & Rows.Count).End(xlUp)).Resize(, 9) On Error Resume Next .Offset(, 1).SpecialCells(2, 1).ClearContents 'On Error GoTo 0 b = .Value2 End With For i = 3 To UBound(b, 1) Step 9 For ii = 2 To UBound(a, 1) If (Year(a(ii, 1)) = Year(b(i, 1))) * (Month(a(ii, 1)) = Month(b(i, 1))) Then myInd = 0 For iii = 5 To 7 Step 2 If a(ii, iii) = b(i, 3) Then myInd = iii : Exit For End If Next If myInd > 0 Then For iii = i To i + 6 If (b(iii, 2) = "") + (b(iii, 2) = a(ii, 2)) Then b(iii, 2) = a(ii, 2) : b(iii, myInd + 1) = b(iii, myInd + 1) + a(i, 6) If a(i, 4) = "GK" Then b(iii, 9) = b(iii, 9) + a(i, 5) '月計の式が不明 End If Exit For '<- 追加 End If Next End If End If Next Next wsSummary.Range("a40").Resize(UBound(b, 1), 9).Value = b Set wsData = Nothing : Set wsSummary = Nothing End Sub
>他に抜き出すべき値はどのような値でしょう? >私自身まだ質問内容をはっきり理解していないような気がします。 http://kamicha1.web.fc2.com/Excel/m-o-mo20090818.html 大変恐縮ですが、かみちゃんさんのシートを使わせていただきます。 集計元データ&集計前のフォーム&集計結果が記載しています。
>マクロ実行結果と、希望結果の違いがわかるようにアップしていただけませんか?
↓こんなふうになっています。
↑見ていただくと日付の欄に数式を入れていますが、マクロ実行後それが消えてしまいます。
なぜでしょか??よろしくお願いします。
(m-o-mo)
2009/8/19 10:59
こんにちは。かみちゃん です。
元スレッドは、こちら。 [[20090813165539]]『Dictionary について』(m-o-mo)
予算シートのシートイメージがずれていて、見づらいです。
> 集計元データ&集計前のフォーム&集計結果が記載しています。
アップさせていただいたファイルの説明をされたほうがいいと思います。 どのシートが集計元データで、どのシートが集計結果なのか・・・
> 見ていただくと日付の欄に数式を入れていますが、マクロ実行後それが消えてしまいます
seiyaさんのコードは、配列処理していますので、配列データを出力する際に上書きしているからです。
(かみちゃん) 2009/08/19 11:07
こんにちは。かみちゃん です。
シートレイアウトを修正していただいたようでありがとうございます。
ただ、シートイメージを提示しなおされているのはどのような意味があるのでしょうか? もし、添付ファイルを見ていただけない場合のことを想定してならば、 前回と同様、マクロ実行前のシートとサンプルデータ、 サンプルデータを使ったマクロ実行後の期待している結果 現在のコードと、そのコードで実行すると、どのような結果になるのかを 載せられたほうがいいと思います。
また、提示しなおしされるのであれば、行番号と列番号を明示しないと・・・
あと、12月に数値が入っているのはなぜですか?
4ヶ月に1回、"月別内訳"という行があることもきちんと説明されたほうがいいです。
(かみちゃん) 2009/08/19 11:14
> ただ、シートイメージを提示しなおされているのはどのような意味があるのでしょうか? 私がお願いしたのです。
m-o-moさん 少々訂正してMsgBoxを追加しましたので、試してください。
Sub test() Dim a, b, i As Long, ii As Long, iii As Long, myInd As Long Dim wsData As Worksheet, wsSummary As Worksheet, myYear As Long, myMonth As Long Set wsData = Workbooks("dt.xls").Sheets("担当別") Set wsSummary = Workbooks("集計.xls").Sheets("予算") a = wsData.Range("a1", wsData.Range("a" & Rows.Count).End(xlUp)).Resize(, 6).Value2 With wsSummary.Range("a39", wsSummary.Range("a" & Rows.Count).End(xlUp)).Resize(, 9) On Error Resume Next .Offset(, 1).SpecialCells(2, 1).ClearContents 'On Error GoTo 0 b = .Value2 End With For i = 3 To UBound(b, 1) If (b(i, 1) <> "") * IsDate(b(i, 1)) Then myYear = Year(b(i, 1)) : myMonth = Month(b(i, 1)) MsgBox CDate(b(i, 1)) & " found on row " & i + 38 & " in 予算" & vbLf "Loop in 担当別 to summarize " & myYear & "." & myMonth & " data starts" For ii = 2 To UBound(a, 1) If (Year(a(ii, 1)) = myYear) * (Month(a(ii, 1)) = myMonth) Then MsgBox CDate(a(ii, 1)) & " found on the row " & i myInd = 0 For iii = 5 To 7 Step 2 If a(ii, 3) = b(i - 1, iii) Then myInd = iii : Exit For End If Next If myInd > 0 Then MsgBox "Person matched with " & b(i - 1, 3) & vbLf _ "Check if the item is already listed, if not, put new item in a first blank" & _ " within next 7 rows from the date in 予算." For iii = i To i + 6 If (b(iii, 2) = "") + (b(iii, 2) = a(ii, 2)) Then b(iii, 2) = a(ii, 2) : b(iii, myInd + 1) = b(iii, myInd + 1) + a(i, 6) If a(i, 4) = "GK" Then MsgBox "GK data found, put the amount" b(iii, 9) = b(iii, 9) + a(i, 5) '月計の式が不明 End If Exit For End If Next End If End If Next End If Next wsSummary.Range("a40").Resize(UBound(b, 1), 9).Value = b Set wsData = Nothing : Set wsSummary = Nothing End Sub (seiya)
ありがとうございます。
>> 見ていただくと日付の欄に数式を入れていますが、マクロ実行後それが消えてしまいます >seiyaさんのコードは、配列で処理していますので、配列データを出力する際に上書きしているからです。 そうなんですか?A列を上書きしない方法できますか? ない場合はそのままでいいです。
>> 人数は、担当別のD列の"GK"だけでなく"GG"や"GM"など、すべてのデータについてE列とF列の項目別に集計し、 >> 金額は、担当別のD列のうち"GK"のみ集計する 人数=担当別のD列のうち"GK"さんのデータのみE列とF列の項目別に集計する 金額=担当別のD列のうち"GK"のみ集計する でお願いします。
>12月に数値が入っているのはなぜですか? マクロで実行後にそうなっていました。
seiya さん シートのほう見ていただけましたか? もう一度レイアウトを掲載したほうがよろしいでしょか?
新しいコード検証した結果 前月の項目名が表示されました。ただ一行ずつずれています。 その辺どうも私の説明不足のようです。
ただ、これから外出しないといけないので、><15時ごろに返事させてください。
(m-o-mo)
2009/8/19 12:1
m-o-moさん 1) > 月 支店 伝表発行 GS (人) KS (人 ) 金額 (円) の行の内訳を説明してください。 私の理解は A - 月 B - 支店 C - 空白 D - 伝票発行 E - GS F - (人) G - KS H - (人) I - 金額(円) です。
2) 数式は日付セルのみですか? (seiya)
こんにちは。かみちゃん です。
> 15時ごろに返事させてください
ということなので、質問者のm-o-moさんの立場で、それまでのつなぎで・・・
> 行の内訳を説明してください。 > 私の理解は
私が、m-o-moさんからファイルを送ってもらって、 http://kamicha1.web.fc2.com/Excel/m-o-mo20090818.html に掲載している、集計.xls の予算シートには、
月 地名 伝表発行 GS (人) KS (人) 金額 (円)
となっているのですが、40行目の実際の値は、
A40 - 月 B40 - 地名 C40 - D40 - 伝票発行 E40 - GS F40 - KS G40 - 金額 H40 -
となっています。
B40:C40、G40:H40 は、結合されています。 また、E40、F40は、セルの書式設定で @" (人)" となっています。 G40は、セルの書式設定で、@" (円)" となっています。
また、上記の行は、40行目のあと、49行、58行、67行、77行、86行、95行、104行、114行、123行、132行、141行 あります。
>> 4ヶ月に1回、"月別内訳"という行がある
については、39行目にA39:H39を結合し、"月別内訳" という値になっています。 同様に、76行、113行にあります。
> 2) 数式は日付セルのみですか?
そうです。 I1セルに 2008 と入力してあり、 A41セルに =DATE($I$1,4,1) A50セルに =DATE(YEAR(A41),MONTH(A41)+1,1) A59セルに =DATE(YEAR(A50),MONTH(A50)+1,1) A68セルに =DATE(YEAR(A59),MONTH(A59)+1,1) A78セルに =DATE(YEAR(A68),MONTH(A68)+1,1) ←"月別内訳"の行1行分ずれる 以下同様 となっています。
seiyaさんの参考になればいいのですが・・・ 質問者のm-o-moさんからいただいたシートを見て説明させていただましたが、 質問者ご本人からの説明ではないので、混乱されるようであれば、スルーしてください。
(かみちゃん) 2009/08/19 12:55
ご協力感謝しますが、m-o-moさんからの説明を待ちます。 (seiya)
こんにちは。かみちゃん です。
> ご協力感謝しますが、m-o-moさんからの説明を待ちます。
了解しました。
>> シートのほう見ていただけましたか?
に対して、見ればわかっていただけるのですが、 何の反応もなく、おそらく、見るつもりはないのだろうなと思い、
>> 15時ごろに返事させてください
ということでしたので、コメントする立場にないことを承知の上で、コメントさせていただきました。 あとは、よろしくお願いします。
私は、seiyaさんのコードは、「なるほど〜」と感心していましたので、勉強に徹したいと思います。 お邪魔しました。一旦、退散いたします。
(かみちゃん) 2009/08/19 13:22
seiya さん
ありがとうございます。 少し時間ができましたので、すこしだけ。
>の行の内訳を説明してください。 >私の理解は 1) 月 支店 伝表発行 GS KS 金額 A - 月 B - 支店 C - 空白 D - 伝票発行 E - GS F - KS G&H - 金額 になります。 行のほうはよろしいのでしょうか?
2) 数式は日付セルのみですか? A列と月計(各月の金額の合計)のみです。
(m-o-mo)
かみちゃんさん
フォローありがとうございます。 画面通して理解していただけるようがんばります。
(m-o-mo)
これで試してください。
Sub test() Dim a, b, i As Long, c, ii As Long, iii As Long, myInd As Long Dim wsData As Worksheet, wsSummary As Worksheet, myYear As Long, myMonth As Long Set wsData = Workbooks("dt.xls").Sheets("担当別") Set wsSummary = Workbooks("集計.xls").Sheets("予算") a = wsData.Range("a1", wsData.Range("a" & Rows.Count).End(xlUp)).Resize(, 6).Value2 With wsSummary.Range("a39", wsSummary.Range("a" & Rows.Count).End(xlUp)) b = .Value2 On Error Resume Next With .Offset(, 1).Resize(, 7) .SpecialCells(2, 1).ClearContents 'On Error GoTo 0 c = .Value2 End With End With For i = 3 To UBound(b, 1) If (b(i, 1) <> "") * IsDate(b(i, 1)) Then myYear = Year(b(i, 1)) : myMonth = Month(b(i, 1)) MsgBox CDate(b(i, 1)) & " found on row " & i + 38 & " in 予算" & vbLf "Loop in 担当別 to summarize " & myYear & "." & myMonth & " data starts" c(i + 7, 5) = "=sum(e" & i & ":f" & i + 6 & ")" For ii = 2 To UBound(a, 1) If (Year(a(ii, 1)) = myYear) * (Month(a(ii, 1)) = myMonth) Then MsgBox CDate(a(ii, 1)) & " found on the row " & i myInd = 0 For iii = 5 To 6 If a(ii, 3) = c(i - 1, iii) Then myInd = iii : Exit For End If Next If myInd > 0 Then MsgBox "Person matched with " & b(i - 1, 3) & vbLf _ "Check if the item is already listed, if not, put new item in a first blank" & _ " within next 7 rows from the date in 予算." For iii = i To i + 6 If (c(iii, 2) = "") + (c(iii, 2) = a(ii, 2)) Then c(iii, 2) = a(ii, 2) : c(iii, myInd) = c(iii, myInd) + a(i, 6) If a(i, 4) = "GK" Then MsgBox "GK data found, put the amount" c(iii, 7) = c(iii, 7) + a(i, 5) End If Exit For End If Next End If End If Next End If Next wsSummary.Range("b39").Resize(UBound(c, 1), 7).Value = c '<-修正 Set wsData = Nothing : Set wsSummary = Nothing End Sub (seiya)
度々済みません>< チャレンジした結果が、元のレイアウトが 項目名 月 地名 伝表発行 GS KS 金額 2008/4/1 (m-o-mo)
結果が、↓項目名の欄が一行ずれただけで何も反応せずですね^^;;;; 何が違うだろう、結構難しいですね。 日付の数式は解決です。 コードの中身を検証してみます。 月 2008/4/1 地名 伝表発行 GS KS 金額 (m-o-mo) (m-o-mo) (m-o-mo) (m-o-mo) (m-o-mo) (m-o-mo) 月計 (m-o-mo)
> 結果が、↓項目名の欄が一行ずれただけで何も反応せずですね^^;;;;
wsSummary.Range("b40").Resize(UBound(c, 1), 7).Value = c は wsSummary.Range("b39").Resize(UBound(c, 1), 7).Value = c ですね。
>E - GS >F - KS は(人)は入っていませんね? (seiya)
Step debug してみてください。 1) コードのどの部分でもよいのでクリック 2) 以後F8を押す度に一行実行されます
それぞれの If節を通るか確認してください。 (seiya)
>は(人)は入っていませんね? 入っていません
wsSummary.Range("b40").Resize(UBound(c, 1), 7).Value = c
は wsSummary.Range("b40").Resize(UBound(c, 1), 7).Value = c でした。直したら行はずれませんが、何も集計されずです。 seyaさんのシート状はどのような結果になっていますか? もし集計されているなら私の書式がおかしていうことですね。
>Step debug してみてください。 >1) コードのどの部分でもよいのでクリック >2) 以後F8を押す度に一行実行されます >それぞれの If節を通るか確認してください。 ↑実行したところ If (b(i, 1) <> "") * IsDate(b(i, 1)) Then の次は End If ←に飛びます 間のIFは黄色にならなかったですね。 Next wsSummary.Range("b39").Resize(UBound(c, 1), 7).Value = c '<-修正 Set wsData = Nothing : Set wsSummary = Nothing End Sub
IFと End IFの数はあっていますね。(関係ないですか。。。) なぜでしょ??
(m-o-mo)
では If (b(i, 1) <> "") * IsDate(b(i, 1)) Then を If (b(i, 1) <> "") * IsNumeric(b(i, 1)) Then に変更してみてください。
というよりも、上記変更無しで b = .Value2 を b = .Value に変更するだけでOKだと思います。 (seiya)
m-o-moさん
経緯をずっと見守りながら勉強していますが、m-o-moさんがいらっしゃらない間に、かみちゃんさんがseiyaさんに対して、 2009/08/19 12:55 に、シートレイアウトの詳細を説明されていますよね? それは合っているのではないでしょうか?それに対して、反応がひつともありません。
ファイルをダウンロードしてみてみましたが、月計も数式で求めるようになっていること以外は、 かみちゃんさんの説明は合っているように感じます。
それに、Dictionaryによるコードとseiyaさんのコード、どちらで解決されるつもりなのでしょうか? 勉強したいだけですか?
それとも、Dictionaryのコードは、動くようになったけど、結局理解できなかったので、seiyaさんの コードで理解できるようになったら、そっちを使おうというお考えですか? どちらを採用するかは、自由ですが、せっかく先に解決させたかみちゃんさんに対して、配慮はされたほうがいいと思いますよ。
なお、勉強したいなら、二次元配列の基本をわかっていないと難しいと思います。
(VBA勉強中)
VBA勉強中さん 下記中の私とm-o-moさんのやりとりをよく読んでください。 [[20090813165539]] (seiya)
検証してみました。
ほしい結果はこれですが。
[A] [B] [C] [D] [E] [F] [G&H] 月 地名 伝表発行 GS KS 金額 2008/4/1 EK (m-o-mo) 1,055.00 136,253 DJ (m-o-mo) 215.00 504.00 86,130 SB (m-o-mo) 492 117.00 77,089 DJ(西) (m-o-mo) 81.00 20.00 12,777 TH (m-o-mo) 407.00 111.00 65,417 NH(大根) (m-o-mo) 370.00 67.00 55,544 NH(鶴巻) (m-o-mo) 378.00 192.00 71,052 月計 504,262
1.表示はこちらになります。項目名一列ずれますね。?? 2.GSは計算されませんでした(ToT) 3.集計するた度に毎回押し続けなければならないのでしょか?計算する行の数だけENTERを押し続けた気がします。(汗;;; [A] [B] [C] [D] [E] [F] [G&H] 月 地名 伝表発行 GS KS 金額 2008/4/1 DJ (m-o-mo) 540.00 SB (m-o-mo) 162.00 DJ(西) (m-o-mo) 108.00 TH (m-o-mo) 162.00 NH(大根) (m-o-mo) 108.00 NH(鶴巻) (m-o-mo) 324.00 ???? (m-o-mo) 一個足りないです。
(m-o-mo)
こんにちは。かみちゃん です。
VBA勉強中さん お気遣い?ありがとうございます。
まぁ、私が一生懸命考えたDictionaryを使ったコードは、最初のm-o-moさんのご要望にできるだけ沿ったつもりですが、 その後にseiyaさんが、Mac環境等、Dictionaryを使わなくてもできる案を提示され、しかもスマート なので、m-o-moさんは、勉強されているのだと思います。 ただ、たしかに、私がシートレイアウトをseiyaさんに説明したのは、何の役にも立たなかったようですが・・・ 2009/08/19 12:55 でかみちゃんが説明したとおりですとい言っておけば、 seiyaさんがm-o-moさんに再度同じことを聞かなくてもいいわけですから。
二次元配列を使えばこのうよな処理でできる、しかもロジック自体は、そんなに難しいものではない、 ただし、シートのセル位置などがうまく伝わっていないなぁと私は思っています。 たぶん、VBA勉強中さんもそのようにお感じになったのだと思います。
あと、35分で解決すればいいですが、ここは、静かに見守りたいと思います。 seiyaさんのコードで多少コンパイルエラーになるところがありますが、そこは、許してあげてください。
(かみちゃん) 2009/08/19 16:40
m-o-moさん、お疲れさま... If が通れば一気に実行してかまいません。
EK が漏れていますね... それと、配列変数 c の Column Index をひとつづつずらすのを忘れていました。 これで試してください。
Sub test() Dim a, b, i As Long, c, ii As Long, iii As Long, myInd As Long Dim wsData As Worksheet, wsSummary As Worksheet, myYear As Long, myMonth As Long Set wsData = Workbooks("dt.xls").Sheets("担当別") Set wsSummary = Workbooks("集計.xls").Sheets("予算") a = wsData.Range("a1", wsData.Range("a" & Rows.Count).End(xlUp)).Resize(, 6).Value2 With wsSummary.Range("a39", wsSummary.Range("a" & Rows.Count).End(xlUp)) b = .Value On Error Resume Next With .Offset(, 1).Resize(, 7) .SpecialCells(2, 1).ClearContents 'On Error GoTo 0 c = .Value2 End With End With For i = 3 To UBound(b, 1) If (b(i, 1) <> "") * IsDate(b(i, 1)) Then myYear = Year(b(i, 1)) : myMonth = Month(b(i, 1)) c(i + 7, 4) = "=sum(e" & i & ":f" & i + 6 & ")" For ii = 2 To UBound(a, 1) If (Year(a(ii, 1)) = myYear) * (Month(a(ii, 1)) = myMonth) Then myInd = 0 For iii = 4 To 5 If a(ii, 3) = c(i - 1, iii) Then myInd = iii : Exit For End If Next If myInd > 0 Then For iii = i To i + 6 If (c(iii, 1) = "") + (c(iii, 1) = a(ii, 2)) Then c(iii, 1) = a(ii, 2) : c(iii, myInd) = c(iii, myInd) + a(i, 6) If a(i, 4) = "GK" Then c(iii, 6) = c(iii, 6) + a(i, 5) End If Exit For End If Next End If End If Next End If Next wsSummary.Range("b39").Resize(UBound(c, 1), 7).Value = c '<-修正 Set wsData = Nothing : Set wsSummary = Nothing End Sub (seiya) 追伸: > seiyaさんのコードで多少コンパイルエラーになるところがありますが、そこは、許してあげてください。 誰に許してもらうのでしょう?
こんにちは。かみちゃん です。
>> seiyaさんのコードで多少コンパイルエラーになるところがありますが、そこは、許してあげてください。 > 誰に許してもらうのでしょう?
それを知って何になるのですか? こちらでテストしている限り、コンパイルエラーになりましたからね。 (しかも以前指摘したところが直っていません)
ただ、16:45くらいに提示されたコードでは、コンパイルエラーになる部分は、削除されていますので、 解消されているみたいですが、 私がm-o-moさんからいただいているシートで検証すると、全然違う結果が出ます。
たぶんシートのレイアウトが途中で変わってしまっているのだとは思いますが、そうでないならば、 seiyaさんとm-o-moさんの間で、通じていないように思います。 私は、もう関係ないので、黙っておいたほうがいいのですが、seiyaさんが気の毒でなりません。
(かみちゃん) 2009/08/19 16:58
ご指摘ありがとうございます。 かみちゃんさんは私のわがままを聞いていただき 最後までDictionaryを最後までお付き合いしていただきました。 正直1/3しか理解していません。ただ私の求めるものはできています。 それにたいしたコメントのファイルも送付で確認していただいています。 本物のデータで確認したところ確かに上手く集計できていません(エラーもでていません) この場合VBA勉強中ならどうしますか? 1.そっく質問する 2.まずはある程度コードの意味云々を調べてから質問する。 (今の私の力量では一日二日で解決できないでしょ)
>それは合っているのではないでしょうか?それに対して、反応がひつともありません。 >>フォローありがとうございます。 >> 画面通して理解していただけるようがんばります。 と書きました。 フォローしていただいたものはまさにその通りです。 多分かみちゃんさん自身私の説明不足のため苦しんだ箇所でしょ。 そしてseiyaさんへのはいりょうで書いたものと思っています。 ただ、その部分seiyaさんどう理解されているかは私はわかりません。 なぜなら、それに対しての質問がないからです。
P.S 画面上の文面のみですが、それなりにその方の性格を見えてきます。
m-o-moさん 気にしないでください。 私は、最初から今までm-o-moさんとのやり取りのみでコードを書いていますし 今後もそのつもりです。 詳細は質問者さんに直接質問して、その回答を待ってからにしています。 (seiya)
こんにちは。かみちゃんです。
To,m-o-moさん
m-o-moさんに教えていただきたいのですが、 seiyaさんが16:45ごろに、再度提示されたコードを実行すると、以下のような結果になりませんか? アップロードしてある 集計.xls で試すと、以下のようになるのですが、違いますでしょうか? コードは確認しなくていいです。 アップロードしてある 集計.xls で試すと、以下のようになるかならないかだけ教えてください。
[A] [B] [C] [D] [E] [F] [G]&[H] [40] 月 地名 伝表発行 GS KS 金額 [41] 2008/4/1 EK (m-o-mo) 215 27767 [42] DJ (m-o-mo) 215 215 55534 [43] SB (m-o-mo) 215 215 55534 [44] DJ(西) (m-o-mo) 215 215 55534 [45] TH (m-o-mo) 215 215 55534 [46] NH(大根) (m-o-mo) 215 215 55534 [47] NH(鶴巻) (m-o-mo) 215 215 55534
お手数おかけしますが、よろしくお願いします。
(かみちゃん) 2009/08/19 17:10
こんにちは。かみちゃん です。
今日もお仕事終わりでしょうか?
> 本物のデータで確認したところ確かに上手く集計できていません(エラーもでていません)
これが見てみたいです。 いただいたメールアドレスに即返信しましたが、アドレスが違うのかPCもしくはドメイン拒否されているのか、エラーになりました。 なお、明日以降は、頻繁に書き込みはできませんので、あしからずご容赦ください。
(かみちゃん) 2009/08/19 17:14
ここは既にDictionaryから離れてるのだから、 混乱を避ける意味でもDictionaryを使用したコードに関しては元スレに戻った方がよいと思います。 (seiya)
検証結果以下になります。
月別内訳
[A] [B] [C] [D] [E] [F] [G]&[H] 月 地名 伝表発行 GS KS 金額 2008/4/1 EK (m-o-mo) 540.00 DJ (m-o-mo) 216.00 540.00 SB (m-o-mo) 108 162.00 DJ(西) (m-o-mo) 108.00 108.00 TH (m-o-mo) 108.00 162.00 NH(大根) (m-o-mo) 162.00 108.00 NH(鶴巻) (m-o-mo) 162.00 324.00 月計 160,518
ほぼイメージどおりですが、金額の合計は7月のみです。 細かく見ていませんが、合計値が少し違うように思います。
このレスの続きは明日にお願いします。 m(_ _)m 退社命令が・・・。
(m-o-mo)
m-o-moさん
>ほぼイメージどおりですが、金額の合計は7月のみです。 金額の合計は7月のみです。の意味が不明です。 詳しく説明してください。
>細かく見ていませんが、合計値が少し違うように思います 月計行のE列に数式を埋め込みました。 その数式が違うのだとも思います。 本来の数式をアップしてください。 それでは、今日はここまでということで... (seiya)
こんにちは。かみちゃん です。
質問者のm-o-moさんも退社されたようなので、明日以降になるようですが、
To,seiyaさん
> ここは既にDictionaryから離れてるのだから、 > 混乱を避ける意味でもDictionaryを使用したコードに関しては元スレに戻った方がよいと思います。
混乱させるようなことして申し訳ありません。 私もこちらでは、Dictionaryを離れて、二次元配列のコードを勉強させていただいています。 そのため、立場としては、m-o-moさんと同じ目線です。
別に新規スレッドにしたほうがよければそうしますが・・・
一応以下のようなデータで試しています。
Sheets("担当別")
[A] [B] [C] [D] [E] [F] [1] 年月日 支店名 項目 人名 金額 人数 [2] H20.4 EK GS GK 136253 1055 [3] H20.4 DJ GS GK 27767 215 [4] H20.4 DJ KS GK 58363 504 [5] H20.4 SB GS GK 63541 492 [6] H20.4 SB KS GK 13548 117 [7] H20.4 DJ(西) GS GK 10461 81 [8] H20.4 DJ(西) KS GK 2316 20 [9] H20.4 TH GS GK 52564 407 [10] H20.4 TH KS GK 12853 111 [11] H20.4 NH(大根) GS GK 47786 370 [12] H20.4 NH(大根) KS GK 7758 67 [13] H20.4 NH(鶴巻) GS GK 48818 378 [14] H20.4 NH(鶴巻) KS GK 22234 192
Sheets("予算") … 実行結果
[A] [B] [C] [D] [E] [F] [G]&[H] [40] 月 地名 伝表発行 GS KS 金額 [41] 2008/4/1 EK (m-o-mo) 215 27767 [42] DJ (m-o-mo) 215 215 55534 [43] SB (m-o-mo) 215 215 55534 [44] DJ(西) (m-o-mo) 215 215 55534 [45] TH (m-o-mo) 215 215 55534 [46] NH(大根) (m-o-mo) 215 215 55534 [47] NH(鶴巻) (m-o-mo) 215 215 55534
To,m-o-moさん サンプルデータやシートレイアウトが変わっているなら、私にも教えていただきたいと思います。
(かみちゃん) 2009/08/19 17:36
こんにちは。よこから失礼します。
■■引用開始
ご指摘ありがとうございます。 かみちゃんさんは私のわがままを聞いていただき 最後までDictionaryを最後までお付き合いしていただきました。 正直1/3しか理解していません。ただ私の求めるものはできています。 それにたいしたコメントのファイルも送付で確認していただいています。 本物のデータで確認したところ確かに上手く集計できていません(エラーもでていません) この場合VBA勉強中ならどうしますか? 1.そっく質問する 2.まずはある程度コードの意味云々を調べてから質問する。 (今の私の力量では一日二日で解決できないでしょ) ■■引用終了
Dictionaryが分からないから質問されたのではないのですか? かみちゃんさんもあちらのスレッドで「先にコードを動かして理解は後にしましょう(大意)」と おっしゃっていますね。 理解できたのは3分の1だけで、のこり3分の2は理解できてない自覚がおありなら とうぜん、1の「引き続き質問する(大意)」ではないですか。
解答する = コードを提供する 解決する = コードが動く 最後まで = コードが動くまで と思っておられませんよね?
やっと「理解」のためのスタート地点に立ったのに、ここで質問を終わりにするのでは なんのために質問されたのか、分からなくなってしまいます。
−佳−
>やっと「理解」のためのスタート地点に立ったのに、ここで質問を終わりにするのでは >なんのために質問されたのか、分からなくなってしまいます。
佳さん、ひどい勘違いじゃないの?
m-o-moさんは、あちらのスレッドで > いくつか質問があります。また明日によろしくお願いします。 > >(m-o-mo)
終わりにするなんて言ってないんだけど? (seiya)
To,m-o-moさん
私の手元で期待している結果が得られなかったので、勉強してみました。
c(i + 7, 4) = "=sum(e" & i & ":f" & i + 6 & ")"
を
c(i + 7, 4) = "=SUM(G" & i + 38 & ":G" & i + 6 + 38 & ")" ^^^ ^^^^^^ ^^^ ^^^^^^ として、
c(iii, 1) = a(ii, 2): c(iii, myInd) = c(iii, myInd) + a(i, 6)
を
c(iii, 1) = a(ii, 2): c(iii, myInd) = c(iii, myInd) + a(ii, 6) ^^
として
c(iii, 6) = c(iii, 6) + a(i, 5)
を
c(iii, 6) = c(iii, 6) + a(ii, 5) ^^ とすると、以下のような結果が得られるようで、期待どおりではないかと思います。
[A] [B] [C] [D] [E] [F] [G]&[H] [40] 月 地名 伝表発行 GS KS 金額 [41] 2008/4/1 EK (m-o-mo) 1055 136253 [42] DJ (m-o-mo) 215 504 86130 [43] SB (m-o-mo) 492 117 77089 [44] DJ(西) (m-o-mo) 81 20 12777 [45] TH (m-o-mo) 407 111 65417 [46] NH(大根) (m-o-mo) 370 67 55544 [47] NH(鶴巻) (m-o-mo) 378 192 71052
月別内訳がどこの行に入っていても問題ありませんし、 日付の数式が上書きされることもありません。 担当別シートが年月日で並べ替わっていなくても問題ないですし、 H20.6 の EK 支店のように重複していると、加算もされますので、問題ないようです。
私としては、二次元配列の使い方について、非常によい勉強をさせていただきました。
(かみちゃん) 2009/08/20 9:30
カウンターの取り間違えでしたね If myInd > 0 Then For iii = i To i + 6 If (c(iii, 1) = "") + (c(iii, 1) = a(ii, 2)) Then c(iii, 1) = a(ii, 2) : c(iii, myInd) = c(iii, myInd) + a(i, 6) If a(i, 4) = "GK" Then c(iii, 6) = c(iii, 6) + a(i, 5) End If Exit For End If Next End If を If myInd > 0 Then For iii = i To i + 6 If (c(iii, 1) = "") + (c(iii, 1) = a(ii, 2)) Then c(iii, 1) = a(ii, 2) : c(iii, myInd) = c(iii, myInd) + a(ii, 6) If a(i, 4) = "GK" Then c(iii, 6) = c(iii, 6) + a(ii, 5) End If Exit For End If Next End If に変更してください。 数式については、引き続き回答を待ちます。 (seiya)
あ!一足違いです。 おはようございます。こうなったら意地でも最後まで両方の式を理解したいと思います(-へ- #)
>細かく見ていませんが、合計値が少し違うように思います 月計行のE列に数式を埋め込みました。 =SUM(G41:H47) c(i + 7, 4) = "=sum(e" & i & ":f" & i + 6 & ")" を c(i + 7, 4) = "=sum(g" & i & ":h" & i + 6 & ")" にできましたが、 41行目に持っていくことはわからなかったです。 しかし、 wsSummary.Range("a39"なのに なぜこれだけは3行目からはじまるのですか??
>合計値が少し違うように思います. GSとKS欄の合計が実際のデータより少ないという意味です。
>>ほぼイメージどおりですが、金額の合計は7月のみです。 >金額の合計は7月のみです。 またイメージを掲載します。 金額欄の合計値は月によって合計されたりされなかったりという意味です。
(m-o-mo)
To,m-o-moさん
> あ!一足違いです。
私の 2009/08/20 9:30 のコメントも見ていただきたいですね。
> こうなったら意地でも最後まで両方の式
何が意地なのかよくわかりませんが(^^;
> [A] [B] [C] [D] [E] [F] [G]&[H] > 月 地名 伝表発行 GS KS 金額 > [40]2008/4/1 EK (m-o-mo) 540.00
seiyaさんが、 > カウンターの取り間違えでしたね で修正されているコードでも、そのような結果になるのですか? こちらではなりませんよ。
(かみちゃん) 2009/08/20 10:17
m-o-moさん > =SUM(G41:H47)
c(i + 7, 4) = "=sum(e" & i & ":f" & i + 6 & ")" を c(i + 7, 4) = "=sum(r" & i + 38 & "c[2]:r[-1]c[3])" に変更してみてください。 (seiya)
こんにちは。かみちゃん です。
独り言です。
> c(i + 7, 4) = "=sum(r" & i + 38 & "c[2]:r[-1]c[3])"
このような方法でもできるのですね。 配列に数式を入れるは、初めて知りましたので、勉強にななりました。
それであれば、 c(i + 7, 4) = "=sum(r[-7]c[2]:r[-1]c[3])" でもいいのかも。
(かみちゃん) 2009/08/20 10:31
月計は正常に作動しました。 なかなか難しいですね。
コードの間する質問してもいいですか? GSとKSと金額の合計はなんとなくわかりました。 1.項目名を引き出すコードはどれになりますか? 2. b = .Valueとc = .Value2はB列とC列だと思ってましたが、違うのですか?
(m-o-mo)
> 1.項目名を引き出すコードはどれになりますか? > 2. b = .Valueとc = .Value2はB列とC列だと思ってましたが、違うのですか?
少し紛らわしい変数名ですよね...
1) b は A列のみのデータです 数式が入力されていて、保存したい .Value にしたのは、IsDate 関数で日付を判定したいためです。 .Value2 だと、文字列 または 数値型のデータになってしまうので 日付型のデータは数値に変換されてしまいます。
2) c は B列からG列までのデータが入っています。
それから、まだコードは完成していません。 次はエラー処理をしますので、抽出されている数値が期待値になっているか 確認してください。 (seiya)
seiya さん
>抽出されている数値が期待値になっているか の合計は↓にならないです。まだ少ないですね。
月 地名 伝表発行 GS KS 金額 2008/4/1 EK (m-o-mo) 2,064.00 DJ (m-o-mo) 430.00 1,008.00 SB (m-o-mo) 984 234.00 DJ(西) (m-o-mo) 162.00 40.00 TH (m-o-mo) 814.00 222.00 NH(大根) (m-o-mo) 740.00 134.00 NH(鶴巻) (m-o-mo) 756.00 384.00 月 地名 伝表発行 GS KS 金額
2008/4/1 EK (m-o-mo) 2,064.00
DJ (m-o-mo) 430.00 1,008.00 SB (m-o-mo) 984 234.00 DJ(西) (m-o-mo) 162.00 40.00 TH (m-o-mo) 814.00 222.00 NH(大根) (m-o-mo) 740.00 134.00 NH(鶴巻) (m-o-mo) 756.00 384.00
月計が違うということですか? それとも、抽出されたデータの数値が違っているということですか? もし月計が違うのでしたら、数式が合っているか確認してください。 (seiya)
seiya さん
済みません><あわてて修正したらseiyaさんのコメントまで消してしまいました。 >それとも、抽出されたデータの数値が違っているということですか? はいそうです >もし月計が違うのでしたら、数式が合っているか確認してください。 は問題ないですあっています。
一箇所カウンターがそのままでした。
>If a(i, 4) = "GK" Then を If a(ii, 4) = "GK" Then に変更してください。
でもこれは、金額の列に関するものですけど... (seiya)
seiya さん
直しました。 合計は何故か4月のみになってしまいました。 5月〜3月は集計されないです。 抽出されたデータ合計値は多くなっています。
(m-o-mo)
> 抽出されたデータ合計値は多くなっています。
合計値はともかく、純粋に抽出された値(人数、金額)は期待値になっていますか? それさえ正しい値であれば、後は修正できます。 (seiya)
seiya さん
>合計値はともかく、純粋に抽出された値(人数、金額)は期待値になっていますか? >それさえ正しい値であれば、後は修正できます。 今現在はなっていません。 (m-o-mo)
確認します。 コードはこのようになっていますか?
Sub test() Dim a, b, i As Long, c, ii As Long, iii As Long, myInd As Long Dim wsData As Worksheet, wsSummary As Worksheet, myYear As Long, myMonth As Long Set wsData = Workbooks("dt.xls").Sheets("担当別") Set wsSummary = Workbooks("集計.xls").Sheets("予算") a = wsData.Range("a1", wsData.Range("a" & Rows.Count).End(xlUp)).Resize(, 6).Value2 With wsSummary.Range("a39", wsSummary.Range("a" & Rows.Count).End(xlUp)) b = .Value On Error Resume Next With .Offset(, 1).Resize(, 7) .SpecialCells(2, 1).ClearContents 'On Error GoTo 0 c = .Value2 End With End With For i = 3 To UBound(b, 1) If (b(i, 1) <> "") * IsDate(b(i, 1)) Then myYear = Year(b(i, 1)) : myMonth = Month(b(i, 1)) c(i + 7, 4) = "=sum(r" & i + 38 & "c[2]:r[-1]c[3])" For ii = 2 To UBound(a, 1) If (Year(a(ii, 1)) = myYear) * (Month(a(ii, 1)) = myMonth) Then myInd = 0 For iii = 4 To 5 If a(ii, 3) = c(i - 1, iii) Then myInd = iii : Exit For End If Next If myInd > 0 Then For iii = i To i + 6 If (c(iii, 1) = "") + (c(iii, 1) = a(ii, 2)) Then c(iii, 1) = a(ii, 2) : c(iii, myInd) = c(iii, myInd) + a(ii, 6) If a(ii, 4) = "GK" Then c(iii, 6) = c(iii, 6) + a(ii, 5) End If Exit For End If Next End If End If Next End If Next wsSummary.Range("b39").Resize(UBound(c, 1), 7).Value = c Set wsData = Nothing : Set wsSummary = Nothing End Sub (seiya)
seiya さん
あ!済みません。何かがずれたようです。 最新コードで集計したところ12か月分集計できました。
金額の合計値は期待した数字どおりです。
KSとGS合計値が違った理由がわかりました。 私のデータが一部だぶりがありました。 なぞを究明してみます。少し時間をください。
(m-o-mo)
ゆっくり時間をかけて検証してください。
検証が済むまでの間に...
問題を解決するには、Algorythmが必要です。 これが整理されれば、95%は解決したことになります。
今回の場合、与えられているものは: 1) 元データ (データベース形式) 2) 定型レポート 2) に含まれるデータ 日付 (年月、数式はそのまま保存) 条件設定を含むヘッダー (人名等) 抽出されるデータ数は最大でも7(限定) 合計欄に数式が設定してある。
ここで、マニュアルで処理することを考えます。
Ex.1 2) の年月に該当するデータを1)から順に拾っていき、同年月の該当データを2) に 随時埋め込んでいく。 Ex.2 1) のデータから、同一年月の条件に合ったデータをグループ化して、2)の該当位置に 各データグループごと埋め込む。 というようなことが考えられると思います。
Ex1,Ex2ともに、Auto/Advanced Filterである程度目的は達成されるでしょう。 ですが、ここで
3) 各年月での同一支店のデータは一行に纏める
という厄介な問題が出てきます。
私のとった手法は Ex1の方で 2) のA列で日付(年月)を拾って、その度に 1) の日付列をループ 該当データがあれば、2) のB列に同一支店があればその行に加算、 なければ、最初の空白行に新たなデータとして挿入。 という、単純明快な動作です。
処理速度を上げるために、データを配列変数にしていることを別にすれば 理解は難しいことでは無いと思います。 もしわからない箇所があれば、いつでも質問してください。
私はDictionaryを使用する際に一番考慮することは、ループの回数を極力減らす、ということです。 Ex2 の処理はどちらかというと、Dictionary向けだと思います。(勿論Dictionaryを使用しなくても可能です)
最初のお尋ねで Dictionary ということでしたが、 私は率直なところ、なぜ? と思った次第です。 今回のケースはDictionary を使用すれば、多少コードが短縮されたり、処理速度に 若干の差は出るでしょうが、それほどのメリットは無い様な気がしました。
今後、いろいろな場面でコードを書く必要が生じた場合には参考にしてください。
ちなみに 私は、メモ帳のみでコードを書いています。 従って、自身のコードもコンパイルさえできません。 また、折角ファイルをアップされても、それを開くこともできません。 タイプミス、記述ミス等が出てきますが、これも勉強だと思ってください。 (seiya)
seiya さん
おさがわせしてすみません。
>KSとGS合計値が違った理由がわかりました。 違ったのは一行だけでした^^;; この条件を追加していただけますか? If a(ii, 4) = "GK" Then
(m-o-mo)
> この条件を追加していただけますか? >If a(ii, 4) = "GK" Then
If a(ii, 4) = "GK" Then c(iii, 6) = c(iii, 6) + a(ii, 5) End If に入ってますけど? (seiya)
>ちなみに 私は、メモ帳のみでコードを書いています。 それは、すごい特技ですね。 これで今までの会話が理解できました。 「コンパイル」???意味通じずにスルーしちゃいました^^;;
>最初のお尋ねで Dictionary ということでしたが私は率直なところ、なぜ? 2ヶ月前にマクロをはじめたばかりです。 マクロで集計を調べたところ二次元配列とDictionaryにたどり着いたんです。 例題を見る限り違いがわかりませんでした。 もともとDictionaryのあとに違う課題で二次元配列を聞くつもりでした。
結果こうして二つを並べてみますと処理方法?(コード書く過程?)が違いますね。 思いがけずに両方勉強できてよかったと思っています。 ただ頭がパンク状態です(@。@) 明日からお盆休みなので、休日後もう一度コードを見直したいと思います。
(m-o-mo)
> もともとDictionaryのあとに違う課題で二次元配列を聞くつもりでした。 そうでしたか。 ひとつの問題に関して、処理方法は複数存在するはずですので 比較するのもよいかもしれません。
配列を扱うには、その特性を理解する必要があります。 現段階のコードが要件を満たしたなら、その辺のエラー処理 を加えます。
明日(金曜日)はこちらにこられませんので、土曜日以降になります。 (seiya)
>If a(ii, 4) = "GK" Then > > If a(ii, 4) = "GK" Then > c(iii, 6) = c(iii, 6) + a(ii, 5) > End If
GSの合計条件 =1.(A42=担当別!A:A) 日付 2.(B42=担当別!B:B) 地名 3.(E41=担当別!C:C) GS 4.(担当別!D:D="GK") GK 5.(担当別!$F:$F) 合計値 なっているていうことですね。データの合計が違うのは何だろう??
(m-o-mo)
seiya さん
>配列を扱うには、その特性を理解する必要があります。 良いサイト知ってますか? いろいろ探しましが、なかなかないですね。
>明日(金曜日)はこちらにこられませんので、土曜日以降になります。 大丈夫です。 本日以降、私の次の回答は来週の水曜日になります。m(_ _)m
(m-o-mo)
> 本日以降、私の次の回答は来週の水曜日になります。m(_ _)m では、そのように。
配列については http://pc.nikkeibp.co.jp/article/NPC/20070803/279043/ でしょうか? (seiya)
>GSの合計条件 =1.(A42=担当別!A:A) 日付 > 2.(B42=担当別!B:B) 地名 > 3.(E41=担当別!C:C) GS > 4.(担当別!D:D="GK") GK > 5.(担当別!$F:$F) 合計値 これは、担当別E列に入る数式の合計条件ですか? (seiya)
すみません私のコードの解読が違ったようです。
[A] [B] [C] [D] [E] [F] [G]&[H] [40] 月 地名 伝表発行 GS KS 金額 [41] 2008/4/1 EK (m-o-mo) 1055 136253 [42] DJ (m-o-mo) 215 504 86130 [43] SB (m-o-mo) 492 117 77089 [44] DJ(西) (m-o-mo) 81 20 12777 [45] TH (m-o-mo) 407 111 65417 [46] NH(大根) (m-o-mo) 370 67 55544 [47] NH(鶴巻) (m-o-mo) 378 192 71052 [48]計 =SUM(G$41:H47) これは問題ありません。 ↑ ↑ の合計条件を関数に例えますとどのようになっていますか?
>これは、担当別E列に入る数式の合計条件ですか? はいそうです。
1) >=SUM(G$41:H47) これはG列の数式ですか? そうであれば > c(i + 7, 4) = "=sum(r" & i + 38 & "c[2]:r[-1]c[3])" は c(i + 7, 6) = "=sum(r" & i + 38 & "c:r[-1]c)" にならないといけません。
E,F列の合計はその条件で関数では無理です。
もう一度整理して、どの列にどのような条件で合計するのか説明してください。 (seiya)
取りあえず、E-Fにご提示の条件で合計を出しますので確認してください。
Sub test() Dim a, b, i As Long, c, ii As Long, iii As Long, myInd As Long Dim wsData As Worksheet, wsSummary As Worksheet, myYear As Long, myMonth As Long Set wsData = Workbooks("dt.xls").Sheets("担当別") Set wsSummary = Workbooks("集計.xls").Sheets("予算") a = wsData.Range("a1", wsData.Range("a" & Rows.Count).End(xlUp)).Resize(, 6).Value2 With wsSummary.Range("a39", wsSummary.Range("a" & Rows.Count).End(xlUp)) b = .Value On Error Resume Next With .Offset(, 1).Resize(, 7) .SpecialCells(2, 1).ClearContents 'On Error GoTo 0 c = .Value2 End With End With For i = 3 To UBound(b, 1) If (b(i, 1) <> "") * IsDate(b(i, 1)) Then myYear = Year(b(i, 1)) : myMonth = Month(b(i, 1)) c(i + 7, 6) = "=sum(r" & i + 38 & "c:r[-1]c)" '<- G列の数式 For ii = 2 To UBound(a, 1) If (Year(a(ii, 1)) = myYear) * (Month(a(ii, 1)) = myMonth) Then myInd = 0 For iii = 4 To 5 If a(ii, 3) = c(i - 1, iii) Then myInd = iii : Exit For End If Next If myInd > 0 Then For iii = i To i + 6 If (c(iii, 1) = "") + (c(iii, 1) = a(ii, 2)) Then c(iii, 1) = a(ii, 2) : c(iii, myInd) = c(iii, myInd) + a(ii, 6) If a(ii, 4) = "GK" Then c(iii, 6) = c(iii, 6) + a(ii, 5) c(i + 7, Ind) = c(i + 7, Ind) + a(ii, 5) '<- E,F の合計計算 End If Exit For End If Next End If End If Next End If Next wsSummary.Range("b39").Resize(UBound(c, 1), 7).Value = c Set wsData = Nothing : Set wsSummary = Nothing End Sub (seiya)
あ!一足違いです。 月計はこのままで大丈夫です。 > c(i + 7, 4) ^^^[48]行目月計E列〜G列結合されていますので。”4”で問題ありません。 ちなみに、 >=SUM(G$41:H47)は > c(i + 7, 4) = "=sum(r" & i + 38 & "c[2]:r[-1]c[3])"を実行した結果の数式です。^^
問題はE,F列の合計です。当初の条件↓です。※を追加
1.各地名の[E]と[F]の人数を合計 ([E][F]のGS&KSは 担当別[C]列の項目名。合計値は担当別[F]列の人数) ※ ↑に担当別のGKさんのデータのみ。の条件を追加したいだけです。 ☆合計値が実際より多いのでここかなと思いました。違っていたらスルーしてください。
2.[G]列は金額の合計 (担当別のGKさんのデータのみ。合計値は[E]金額です。)
そうすると、E,F列それぞれSUM(E$41:E47),SUM(F$41:E47)になればよいのですか? (seiya)
seiya さん
>そうすると、E,F列それぞれSUM(E$41:E47),SUM(F$41:E47)になればよいのですか? sumを使うのはG列の合計のみです。なのでそのままで大丈夫です。
>c(i + 7, 4) = "=sum(r" & i + 38 & "c[2]:r[-1]c[3])" を使用しています。合計値はあっています。
>c(i + 7, Ind) = c(i + 7, Ind) + a(ii, 5)エラーになりました。 c(i + 7, myInd) = c(i + 7, myInd) + a(ii, 5) ^^^^^^^ ^^^^^^ を追加したところエラーが出なくなりました。あっていますか?
やはり合計値は変わらずに多いです。何が問題でしょか???
本日は時間切れです><。次回は水曜日にお願いします。
(m-o-mo)
>> >c(i + 7, Ind) = c(i + 7, Ind) + a(ii, 5)エラーになりました。 > c(i + 7, myInd) = c(i + 7, myInd) + a(ii, 5)
そうでした。 その計算はそれぞれのKGデータの金額です。 E,Fを加算すると、G列の合計と合致するはずです。 (seiya)
seiyaさん
長々お待たせしてすみません。
合計についてですが、 If myInd > 0 Then For iii = i To i + 6 If (c(iii, 1) = "") + (c(iii, 1) = a(ii, 2)) Then c(iii, 1) = a(ii, 2) : c(iii, myInd) = c(iii, myInd) + a(ii, 6) ★ ↓これを下に持って行きました。 If a(ii, 4) = "GK" Then c(iii, 6) = c(iii, 6) + a(ii, 5) c(iii, 1) = a(ii, 2) : c(iii, myInd) = c(iii, myInd) + a(ii, 6) ★1 End If
いろいろ消したり、追加したり、動かしたりで、★がEとFの合計だとわかり、 ★を★1に移動したところ思い通りの結果を得ることができました。 コードの意味はわかりませんが、、、、
c(iii, 1) = a(ii, 2) : c(iii, myInd) = c(iii, myInd) + a(ii, 6) ★1 ↑この形はどういう意味でしょか?EとFの合計はわかりましたが、 1. 意味合いは c(iii, 1) = a(ii, 2) : c(iii, myInd) と c(iii, 1) = c(iii, myInd) + a(ii, 6) を一列にしたものでしょか? 2.「:」の意味はありますか??(月の所もありますね「:」と「*」
(m-o-mo) 2008/8/26 8:34
m-o-moさん
G列の各数値は
担当別のC列の値が予算のE/F列の列見出しに合致して、担当別のD列がKGのF列の金額
です。 この金額の出し方はあっていますか? ちなみに、現在のE/F列の合計は、各担当別内訳になっていますので、合算するとG列合計 になっているはずです。 (seiya)
seiya さん
返信ありがとうございます。
>G列の各数値は >担当別のC列の値が予算のE/F列の列見出しに合致して、担当別のD列がKGの E列 の金額 その通りです。結果もその通りに出ています ^^b
>E,Fを加算すると、G列の合計と合致するはずです。 勘違いをしたら済みません。違ったらスルーしてください。 E列の値 + F列の値 = G列の値 て言うことですか??なら違います。
EとF列の格数値は 担当別のC列の値が予算のE/F列の列見出しに合致して、担当別のD列がKGの F列 の人数
です。なので単純に考えて★1に持ってきました。
(m-o-mo)
> E列の値 + F列の値 = G列の値 て言うことですか??なら違います 違います。 G列合計の内訳です。 E/F列の各合計ではありません。
> EとF列の格数値は > 担当別のC列の値が予算のE/F列の列見出しに合致して、担当別のD列がKGの F列 の人数
現在、E/F列の各数値はこのようになっていません。(ここが違ったのですね)
確認します。 E/F/Gの各数値は、担当別のD列がKGのみのデータを抽出ですか? (seiya)
seiya さん
>E/F/Gの各数値は、担当別のD列がKGのみのデータを抽出ですか? はいそうです。
>E/F/Gの各数値は、担当別のD列がKGのみのデータを抽出ですか? E/F/Gの各数値は、E/F列の列見出しに合致して担当別のD列がKGのみのデータを抽出です。
(m-o-mo)
これで試してください。 Sub test() Dim a, b, i As Long, c, ii As Long, iii As Long, myInd As Long Dim wsData As Worksheet, wsSummary As Worksheet, myYear As Long, myMonth As Long Set wsData = Workbooks("dt.xls").Sheets("担当別") Set wsSummary = Workbooks("集計.xls").Sheets("予算") a = wsData.Range("a1", wsData.Range("a" & Rows.Count).End(xlUp)).Resize(, 6).Value2 With wsSummary.Range("a39", wsSummary.Range("a" & Rows.Count).End(xlUp)) b = .Value On Error Resume Next With .Offset(, 1).Resize(, 7) .SpecialCells(2, 1).ClearContents 'On Error GoTo 0 c = .Value2 End With End With For i = 3 To UBound(b, 1) If (b(i, 1) <> "") * IsDate(b(i, 1)) Then myYear = Year(b(i, 1)) : myMonth = Month(b(i, 1)) c(i + 7, 4) = "=sum(r" & i + 38 & "c[2]:r[-1]c[3])" For ii = 2 To UBound(a, 1) If (Year(a(ii, 1)) = myYear) * (Month(a(ii, 1)) = myMonth) * _ (a(ii, 4) = "GK") Then myInd = 0 For iii = 4 To 5 If a(ii, 3) = c(i - 1, iii) Then myInd = iii : Exit For End If Next If myInd > 0 Then For iii = i To i + 6 If (c(iii, 1) = "") + (c(iii, 1) = a(ii, 2)) Then c(iii, 1) = a(ii, 2) : c(iii, myInd) = c(iii, myInd) + a(ii, 6) c(iii, 6) = c(iii, 6) + a(ii, 5) Exit For End If Next End If End If Next End If Next wsSummary.Range("b39").Resize(UBound(c, 1), 7).Value = c Set wsData = Nothing : Set wsSummary = Nothing End Sub (seiya)
seiya さん
希望通りです (☆o☆) なるほどこうするとIFを一個減らせるんですね。
(m-o-mo)
やっとここまで来ましたね。 数値が期待値になったところで、先に触れておいたError Trapping をします。
配列を扱う場合、Subscript Out of range という実行時エラーが付きまといます。 例えば、配列の添え字(Index)の範囲を超えて指定された場合に起こります。
a(1 To 100, 1 To 5) のような配列で a(106, 1) と指定した場合、 106 は既に 100 を超えていますので、エラーになります。 これは配列特有の現象で、シート上で下記のように指定してもエラーになりません。
Set rng = Range("a1:a100") rng.Cells(106, 1)
指定された範囲外のセルでも取得できます。
今回の場合 1) c(i + 7, 4) = "=sum(r" & i + 38 & "c[2]:r[-1]c[3])" 2) For iii = i To i + 6 でのループで範囲外になるケースが予想されます。
ループカウンター i は For i = 3 To UBound(a, 1) で使用されており、配列 a の3行目から、最終行までループしています。 その間に、日付データを拾ってそこから各処理が始まります。
もし、配列 a の最終行から、最終行 - 6 の間に何らかの日付が存在した場合には 1), 2) 共にエラーの対象になってしまいます。
そこで 1) の c(i + 7, 4) = "=sum(r" & i + 38 & "c[2]:r[-1]c[3])" でエラーを回避してしまえば 2) のエラーも発生しませんので
For i = 3 To UBound(b, 1) - 7 ^^^^ とすれば、SubScript Out Of Range の実行時エラーは回避できますので 'On Error GoTo 0 の ' を削除して試してください。 (seiya)
seiya さん
>配列を扱う場合、Subscript Out of range という実行時エラーが付きまといます。 なるほどです。 〆(@、@)メモメモ "'" はなぜ?と思いましたが、そういう理由だったんですね。
>' を削除して試してください。 実行した結果エラーなく希望通りの結果になっています ^^b
(m-o-mo)
コードの内容で不明な箇所があったら質問してください。 (seiya)
seiya さん
>コードの内容で不明な箇所があったら質問してください。 はいあります。
コードを一通り検証してみました。 間違った箇所を指摘していただけますか?
なんとなく意味はわかりますが、なぜそれを使ったのかはわかりません。
例えば「:」と「*」の違いは?みたいな・・・・。
(m-o-mo)
1) コード中の : は改行を意味します。
c(iii, 1) = a(ii, 2) : c(iii, myInd) = c(iii, myInd) + a(ii, 6) は c(iii, 1) = a(ii, 2) c(iii, myInd) = c(iii, myInd) + a(ii, 6) と同じことです。
2) * は乗算(掛け算)をしています。 If の条件節では And と同等です。
vba では True の実際の値は -1 です。 そして、True/False の判断基準は 0 か否かで判断します。(0 以外は True)
If 条件1 * 条件2 * 条件3 Then
この場合、条件1がTrue(-1), 条件2がTrue(-1), 条件3がTrue(-1) 以外は 0 になります。 -1 * -1 * -1 <> 0 -1 * 0 * -1 = 0 つまり、全ての条件が True であるときにのみ成立することになります。
(seiya)
ていうことは(=〜=) If (Year(a(ii, 1)) = myYear) * (Month(a(ii, 1)) = myMonth) * _ (a(ii, 4) = "GK") Then myInd = 0 ← はIf条件がtrueの時に myInd = iii: Exit For ← iiiに行って処理する?? (m-o-mo)
myInd は 担当がE/F列のどちらに合致するか判定するための変数で使用しています。 myInd = 0 ----1) For iii = 4 To 5 If a(ii, 3) = c(i - 1, iii) Then myInd = iii : Exit For ----2) End If Next If myInd > 0 Then ----3) 1) ループする前に myInd = 0 で 変数を初期化 2) E/F列にループして、どちらかに合致した場合 myInd にループカウンター(iii) を格納してループを脱出 3) ループ終了後 myInd が 0 (初期値)でなければ、つまり 4 か 5 であればどちらの担当かを判断できる ということです。 (seiya)
そうしますと
c(iii, 1) = a(ii, 2): c(iii, myInd) = c(iii, myInd) + a(ii, 6) 1)^^^^ 2)^^^^ 1) For iii = i To i + 6 の両方の意味合いでしょか?? 2) 4 か 5 であればどちらの担当かを判断する ていうことですね^^??
(m-o-mo)
ちょっと紛らわしいカウンターの使い方をしましたね。
For iii = i To i + 6 の カウンター iii は、その前の For iii = 4 To 5 のiii とは別のものと思ってください。 理解しやすくなるのなら、iv とでもすれば
For iv = i To i + 6 If (c(iv, 1) = "") + (c(iv, 1) = a(ii, 2)) Then c(iv, 1) = a(ii, 2) : c(iv, myInd) = c(iv, myInd) + a(ii, 6) c(iv, 6) = c(iv, 6) + a(ii, 5) Exit For End If Next のようになります。 (seiya)
。。。。。〆(。@;;)メモメモ
>For iii = 4 To 5 のiii とは別のものと思ってください。 そうなんですか。ネットでも同じカウンターを使用していましたので、 ちょっと質問してみました。
あとは '予算A列の空欄x予算A列の値? If (b(i, 1) <> "") * IsDate(b(i, 1)) Then ^^^^^^??? A列の日付が一行しかないため空欄も含むという意味ですか?
(m-o-mo)
その行は
(b(i, 1) <> "") b(i, 1) が空白でなく
* IsDate(b(i, 1)) 且つb(i, 1) が日付
という条件です。 (seiya)
なるほどようやく分かりました。^^
1.wsSummary.Range("b39").Resize(UBound(c, 1), 7).Value = c ^^^は= c = .Value2ですか?? 2. IF使用しているので、 IF 真の時 Else 義のとき End If も可能でしょか??
(m-o-mo)
1) .Value でも .Value2 でも変わらないと思いますが? Value と Value2 の違いはHelpを参照してください。 そこは、元のデータ範囲に、でーたを加工した配列を戻しているだけです。
2) If 構文の基本形は
If Tue Then True時の処理 Else True以外の処理 End If
ですので、可能ですがこの場合具体的にどのようにしたいのでしょう? (seiya)
次月の目標額を挿入したい。
If 次月 Then 別の処理 Else True以外Sub testの処理 End If のような。。上手く伝えられずにすみません><。 (m-o-mo)
何をしたいかわかりませんが 構文的には可能です。 としか、コメントしようがないですね... (seiya)
>何をしたいかわかりませんが
説明することが一番苦手な私。。。。。
1.担当者別の毎月営業実績表(データ 2009/8まで) ("dt.xls").Sheets("担当別") 2.個人年間営業実績 ("集計.xls").Sheets("予算")
3.次月目標データ(次月2009/9 の目標契約値) ("dt.xls").Sheets("Sheets1").Range("B6:P:12")
2.は1.のデータを集計しているのでもちろん8月まで集計しています。 9月は 3. のデータを引っ張りたいですが、
今一番困っているのはIFの↓条件??
dt = date(year(date),month(date)+1,1) If dt?? Then
(m-o-mo)
> 9月は 3. のデータを引っ張りたいですが、
1) ("dt.xls").Sheets("Sheets1").Range("B6:P:12")のシートレイアウトの説明が必要 2) ("集計.xls").Sheets("予算")に 1) の日付、およびスペースは確保されている?
とにかく、詳しい説明がないと何もできません。 それと、今後話を進めていくためにも、m-o-moさんがどの程度VBAの知識をお持ちか 知っておく必要があると思います。
私が提示したコードは殆どチンプンカンプンの状態ですか? (seiya)
>今後話を進めていくためにも、m-o-moさんどの程度VBAの知識があるかを知っておく必要があると思います。 それは、コード提示するていうことですね。 後日に提示します。後もう少し><
>私が提示したコードは殆どチンプンカンプンの状態ですか? いえ、丁寧に説明していただいたので、理解できました。 (↑の質問はなにて感じですね、、、すみません)
(m-o-mo)
ということは Loopに付いては問題なく理解できる と考えてよろしいですね?
> 後日に提示します。後もう少し>< それと同時に、各シートのレイアウトおよび、期待値等の詳細を載せてください。 (seiya)
こんにちは。かみちゃん です。
To,m-o-moさん
平日日中は、まったく時間がとれない時期になってきたので、このくらいの時間しかコメントできないのですが、 できましたら、スルーしないで読んでいただければうれしいのですが、
> 次月の目標額を挿入したい。
シートレイアウトに変更/追加があるのではないでしょうか? それであれば、別スレッドにしたほうがいいのでは? もちろん、質問しているm-o-moさん、アドバイスされているseiyaさんの双方のご迷惑にならないという前提ですが。 スレッドを参考に勉強している者(少なくとも私は、こちらのスレッドでは、その立場にいるつもりです)にとっては、 スレッドがここまで伸びてくると、わかりにくくなってきているのが事実です。
あと、もうひとつのDictionaryのスレッドも同じようにシートレイアウトに変更/追加が生じるのでしょうか?
(かみちゃん) 2009/08/26 22:16
seiya さん
>Loopに付いては問題なく理解できる Loopは↓のことですか?IFのループ?
http://officetanaka.net/excel/vba/tips/tips63.htm
P.S 条件追加の件はスルーしてください。 頭の整理してから。 自分で作ってみて、わからない時はまた質問に来ます。 そのときはご指導よろしくお願いします。
(m-o-mo)
> 頭の整理してから。 > 自分で作ってみて、わからない時はまた質問に来ます。 > そのときはご指導よろしくお願いします。
了解しました。 Algorythm をしっかり考えて整理してください。
現時点では大まかなことしか助言できませんが、
If (b(i, 1) <> "") * IsDate(b(i, 1)) Then If b(i, 1) > Date Then '<- 今日の日付より大の場合 別処理 Else 現在の処理
のような感じでいけると思います。
予断になりますが、誤解のないように指摘しておきます。 Dictionary,または配列を使用するからできるのではありません。 Algorythmさえしっかりしたものがあれば、どのようにしてもできるのです。 (seiya)
> シートレイアウトに変更/追加があるのではないでしょうか? > それであれば、別スレッドにしたほうがいいのでは?
m-o-moさんと私とのやり取りでは、一貫して同じレイアウトです。 このような発言は謹んでください。 (seiya)
seiya さん
>Algorythmさえしっかりしたものがあれば、どのようにしてもできるのです。 。。。。。〆(。@;;)メモメモ あ!手本?書いていただきましたね。 あと、ヒントを元にチャレンジしてみます。(↑一番苦手な分野です。(汗))
長々とレスをしていただき本当にありがとうございます。m(_ _)m 理解が悪く、説明が下手でseiyaさんに大変苦労させ申し訳ない気持ちがいっぱいです。 それでもここまでお付き合い頂き感謝がいっぱいです。 途中で不快な思いをさせ済みませんでした。
チャレンジ失敗したときひょっこりと質問にきますので、 その時もよろしくお願いします。σ(^^;;;;
(m-o-mo)
P.S コメントを書いてアップするつもりが、 「一覧(最新順〜)」を間違いてクリックしてしまい。×2 感謝のコメントがだんだん短くなったような。(=。=)
> 理解が悪く、説明が下手でseiyaさんに大変苦労させ申し訳ない気持ちがいっぱいです。
私はそのように感じていません。 このスレに投稿した言いっ放しの心無い者達が不必要に余計な気遣いをさせてしまったようですし、 また不必要にこのスレを長くしているようです。
気にせずがんばってください。 (seiya)
seiya さん
エールをありがとうございます。^^^^^^ヾ(ToT) がんばります。 p(^o^)q
P.S コメントはすべて読ませていただいています。 一意見として受け止めています。
(m-o-mo)
m-o-moさん
とりあえず、Baseは同じでDictionaryを使用した場合のコードを載せておきます。 ループがかなり少なくなりますので、体感できるかわかりませんが処理速度は上がっているはずです。
Sub test2() Dim a, b, i As Long, c, ii As Long, myInd As Long Dim wsData As Worksheet, wsSummary As Worksheet, z As String, x Set wsData = Workbooks("dt.xls").Sheets("担当別") Set wsSummary = Workbooks("集計.xls").Sheets("予算") a = wsData.Range("a1", wsData.Range("a" & Rows.Count).End(xlUp)).Resize(, 6).Value2 With wsSummary.Range("a39", wsSummary.Range("a" & Rows.Count).End(xlUp)) b = .Value On Error Resume Next With .Offset(, 1).Resize(, 7) .SpecialCells(2, 1).ClearContents On Error GoTo 0 c = .Value2 End With End With With CreateObject("Scripting.Dictionary") For i = 3 To UBound(b, 1) - 7 If (b(i, 1) <> "") * IsDate(b(i, 1)) Then z = Year(b(i, 1)) & ";" & Month(b(i, 1)) '修正 c(i + 7, 4) = "=sum(r" & i + 38 & "c[2]:r[-1]c[3])" .item(z) = i End If Next For i = 2 To UBound(a, 1) If a(i, 4) = "GK" Then z = Year(a(i, 1)) & ";" & Month(a(i, 1)) If .exists(z) Then x = .item(z) myInd = 0 For ii = 4 To 5 If a(i, 3) = c(x - 1, ii) Then '修正 myInd = ii : Exit For End If Next If myInd > 0 Then For ii = x To x + 6 If (c(ii, 1) = "") + (c(ii, 1) = a(i, 2)) Then c(ii, 1) = a(i, 2) c(ii, myInd) = c(ii, myInd) + a(i, 6) c(ii, 6) = c(ii, 6) + a(i, 5) Exit For End If Next End If End If End If Next End With wsSummary.Range("b39").Resize(UBound(c, 1), 7).Value = c Set wsData = Nothing : Set wsSummary = Nothing End Sub (seiya)
seiya さん
ありがとうございます。明日実行してみます。
Dictionaryで With CreateObject("Scripting.Dictionary") を使用するのは初めて見ました。 Dictionaryが条件になるということですか?
携帯にて御礼まで(^ o^)
(m-o-mo) 2009/8/27 19:37
こんにちは。かみちゃん です。
To,seiyaさん
> Baseは同じでDictionaryを使用した場合のコードを載せておきます。
こういうことは、謹んでいただきたいですね。 書くなら、あちらのスレッドではないかと思いますが?
現に、 > ここは既にDictionaryから離れてるのだから、 > 混乱を避ける意味でもDictionaryを使用したコードに関しては元スレに戻った方がよいと思います。 とおっしゃったのは、seiyaさんでは、ないですか?
容赦なく書き込むのは、勝手ですが、少しくらい配慮があってもいいのでは?
(かみちゃん) 2009/08/29 21:05
こんにちは。かみちゃん です。
>> Baseは同じでDictionaryを使用した場合のコードを載せておきます。 > > こういうことは、謹んでいただきたいですね。 > 書くなら、あちらのスレッドではないかと思いますが?
と書いたものの検証結果をお知らせします。
z = Year(b(i, 1)) & ";" & myMonth = Month(b(i, 1)) は z = Year(b(i, 1)) & ";" & Month(b(i, 1)) で If a(ii, 3) = c(i - 1, ii) Then は If a(i, 3) = c(2, ii) Then
としないと期待している結果は出ません。 ご確認ください。
(かみちゃん) 2009/08/29 21:24
seiya さん
コード有難うございます。 参考させて頂きます。
本当有難うございました。
またなにかありましたらよろしくしくお願いします。
(m-o-mo) 00:02
> 容赦なく書き込むのは、勝手ですが、少しくらい配慮があってもいいのでは? 質問者の利益を考慮すれば、他の回答者の立場など考慮しませんよ。 特に、必要もないのにでしゃばって混乱させるような輩には。 (seiya)
こんにちは。かみちゃん です。
> 質問者の利益を考慮すれば、
では、 2009/08/29 21:24 は、どのような見解なのでしょうか? 明らかに間違っているはずです。それも「必要のないでしゃばり」とおっしゃるなら、もう何も言いませんが・・・
(かみちゃん) 2009/08/30 9:12
その前に、散々レイアウトが違うと無駄なスペースを使用してわいわ騒いでいたことを反省したら? (seiya)
こんにちは。かみちゃん です。
> 散々レイアウトが違うと無駄なスペースを使用してわいわ騒いでいたことを反省したら?
騒いでいたつもりはないのですが、そのように感じたなら、反省します。 質問者の利益に繋がらない点については、もう関わらないことにしますので。
(かみちゃん) 2009/08/30 9:27
m-o-moさん、
Dictionary使用のコードを、そうでないコードの違いを理解してもらうために 書いたので参考にしてください。 (まるっきり違う手法では意味がないので)
> z = Year(b(i, 1)) & ";" & myMonth = Month(b(i, 1)) は z = Year(b(i, 1)) & ";" & Month(b(i, 1))
> If a(ii, 3) = c(i - 1, ii) Then は If a(ii, 3) = c(x - 1, ii) Then ^^^ にしてください。
おもな違いは Dictionarty 使用 配列 a, b/c に対してループは一周のみ
Dictionary 未使用 配列 a に対して、配列 b の日付の数だけのループが必要 (seiya)
こんにちは。かみちゃん です。
seiyaさん
スレッドでは、不愉快な思いをさせ、ご迷惑おかけしています。 「あなたにアドバイスしていない」と言われそうですが、教えていただきたいことがあります。
> If a(ii, 3) = c(x - 1, ii) Then > ^^^ > にしてください。
a(ii, 3) で使用している添え字ii は、予算シートのB列から列数かと思いますが、配列変数a は 担当別シートの値を持っているので、添え字の使い方がおかしくないですか?
質問者ではないのですが、勉強させていただきたく、私が間違っているかもしれませんので、教えていただくわけにはいかないでしょうか?
> Dictionary使用のコードを、そうでないコードの違いを理解してもらう
質問者を含めて閲覧している者に、勉強してもらいたいために、 わざと、間違っているコードをお書きになっているなら、そうおっしゃていただいても構いません。
(かみちゃん) 2009/08/30 10:17
If a(ii, 3) = c(x - 1, ii) Then
は、
If a(i, 3) = c(x - 1, ii) Then ^^^
ではないのでしょうか?
# すでに指摘されているのですが・・・
(おちえて)
おちえてさん、 そうでした、 コードを修正しておきます。 ありがとうございました。 (seiya)
seiya さん
レス続いてること気づかずに、 返信遅れてすみません。
コードは自分なりに編集してエラーなく使用しています。^^ わかりやすく説明していただいたので、なんとなく編集したら、できました。
配列の基礎を勉強中ですが、 躓くときは質問に来たいと思います。 そのときも教えていただけますと大変うれしいです。
本当にありがとうございました。感謝でいっぱいです。
(m-o-mo)
m-o-moさん
二つのコードを比較できるような形で書いたつもりですので参考にしてください。 両方ともに配列を使用しています。(勿論使用しなくてもできます)
Dictionaryは別の方法でもそれらしきことはできますが、ここでは「比較」ということで そちらには触れないでおきます。
もし上記2コードが理解できて、なおかつ興味があるようでしたら質問してください。 (seiya)
seiya さん
了解です。 本当にありがとうございます。
(m-o-mo)
[ 一覧(最新更新順) ]
YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki.
Modified by kazu.