• 締切済み

超初心者がマクロ集計をすることになりました

マクロを使った集計システムを作成することになったのですが、マクロのマの字も知らない初心者です。 以下の表を集計するマクロを初心者向けで教えてください。 氏名        作業No   月No   時間内   時間外   社員No 山本太郎      3210      5     8      0      120 山本太郎      5120      8     8      12     120 山本太郎      3210      5     4      0      120 山田花子      1203      4     8      2      320 山田花子      3210      5     8      12     320 佐藤治郎      5201      10    8      8      91 佐藤治郎      3210      5     8      8      91 佐藤治郎      3210      5     8      12     91 という表があるとします。 これを、以下のようにしたい場合のマクロを教えてください。 氏名        社員No    作業No    時間内   時間外 山本太郎       120      3210-10    12       0 山本太郎       120      5120-8     8       12 山田花子      320      1203-4     8        2 山田花子       320      3210-5     8       12 佐藤治郎       91       5201-10    8        8 佐藤治郎       91       3210-10    16       20   ※作業Noと月Noのデータを“-”をつけて結合しています。 ※1人が同じ「作業No+月No」の作業を複数行っていたら、合計します。 すみませんが、よろしくお願いします。

みんなの回答

  • tom04
  • ベストアンサー率49% (2537/5117)
回答No.2

こんにちは! 一例です。 Sheet1のデータをSheet2に表示するようにしてみました。 尚、Sheet2の1行目項目は入力済みだとします。 Alt+F11キー → メニュー → 挿入 → 標準モジュールに↓のコードをコピー&ペーストして マクロを実行してみてください。 (Alt+F8キー → マクロ → マクロ実行です) Sub Sample1() 'この行から Dim i As Long, endRow As Long, c As Range, wS1 As Worksheet, wS2 As Worksheet Set wS1 = Worksheets("Sheet1") Set wS2 = Worksheets("Sheet2") Application.ScreenUpdating = False endRow = wS2.Cells(Rows.Count, 1).End(xlUp).Row If endRow > 1 Then wS2.Rows(2 & ":" & endRow).ClearContents End If endRow = wS1.Cells(Rows.Count, 1).End(xlUp).Row wS1.Range("A:A").Insert With Range(wS1.Cells(2, 1), wS1.Cells(endRow, 1)) .Formula = "=B2&C2" .Value = .Value End With wS2.Range("A:A").Insert For i = 2 To endRow Set c = wS2.Range("A:A").Find(what:=wS1.Cells(i, 1), LookIn:=xlValues, lookat:=xlWhole) If c Is Nothing Then With wS2.Cells(Rows.Count, "A").End(xlUp).Offset(1) .Value = wS1.Cells(i, "A") .Offset(, 1) = wS1.Cells(i, "B") .Offset(, 2) = wS1.Cells(i, "G") .Offset(, 3) = wS1.Cells(i, "C") & "-" End With End If Next i For i = 2 To wS2.Cells(Rows.Count, 1).End(xlUp).Row With wS2.Cells(i, "D") .Value = .Value & WorksheetFunction.SumIf(wS1.Range("A:A"), wS2.Cells(i, 1), wS1.Range("D:D")) .Offset(, 1) = WorksheetFunction.SumIf(wS1.Range("A:A"), wS2.Cells(i, 1), wS1.Range("E:E")) .Offset(, 2) = WorksheetFunction.SumIf(wS1.Range("A:A"), wS2.Cells(i, 1), wS1.Range("F:F")) End With Next i wS1.Range("A:A").Delete wS2.Range("A:A").Delete Application.ScreenUpdating = True End Sub 'この行まで ※ 細かい説明は割愛します。考え方として・・・ (1)Sheet1・Sheet2ともA列を挿入 → 作業列として使用 → 元データのA列とB列を「&」でつなげています。 (2)あとはそれぞれのA列を使って、SUMIF関数で対応できると思います。 参考になりますかね?m(_ _)m

  • Nouble
  • ベストアンサー率18% (330/1783)
回答No.1

私が読んだ過去の本には 「プログラミングはデータ構造の設計とアルゴリズムの選択でほぼ終わる」 と、書いていました。 これをお示し頂いたものに当てはめると データ構造の設計は、 主キーの配下に 氏名データ、社員No.、作業No.、時間内勤務時間、時間外勤務時間、 この5つのデータがあれば、1件のデータが成立すると解ります。 折角のVBAなのですから これを隠し作業用シートに縦に並べれば仕事が楽でしょう 次にアルゴリズムですが 考えるべきは追加、削除、統合、でしょうか? 追加は 折角のシートなのでソート機能を使っても良いのですが、 MAX(INDEX((社員No.の列=追加する社員No.)*(作業No.の列=追加する作業No.)*ROW(社員No.の列),,)) これを評価し自然数だった場合はその次に挿入 そうじゃなかった場合 MAX(INDEX((社員No.の列=追加する社員No.)*ROW(社員No.の列),,)) これを評価し自然数だった場合はその次に挿入 そうじゃなかった場合 データの一番下に挿入 削除は 削除済み値用データ群に移動(カット&ペースト) して件数を減少 集計、統合、は WITH 隠しシート名 LARGE(INDEX((社員No.の列=追加する社員No.)*(作業No.の列=追加する作業No.)*ROW(社員No.の列),,),ROW(.RANGE(.CELLS(1,1),.CELLS(COUNTA(社員No.の列),1)))) END WITH これを評価し (※注:動作未確認です) RANGEで返させて 次男内の列と時間外の列にオフセットし 総和を取り RANGえの.ROWの値のセルに書き込み Rengeを1つオフセットし、1行少なくリサイズし このレンジについて行全体を削除処理すれば良いでしょうか? 実際のプログラミングは「仕事」ですのでご自身でお願いしますね。 如何でしょうか? お役に立てていたならば幸いです。

muchi2013
質問者

お礼

ありがとうございます。 サッパリ分かりませんが、おっしゃる通り仕事ですので、調べて見ます。

関連するQ&A