Excel (VBA) |
![]() ![]() |
(Windows 10全般 : Excel 2021)
重複する作業ごとにまとめた表を作りたいです
投稿日時: 23/10/17 21:34:11
投稿者: ぽよ@初心者
|
---|---|
毎日の作業を重複する作業ごとに時間も足して1ヶ月分まとめた表を作りたいです
|
![]() |
投稿日時: 23/10/17 22:19:27
投稿者: WinArrow
|
---|---|
基本的なこと
|
![]() |
投稿日時: 23/10/18 06:54:11
投稿者: simple
|
---|---|
既に指摘がありますが、集計に適したデータの持ち方を工夫することが推奨されます。
<<Sheet1>> A列 B C D E F G列 1 作業 計画 結果 作業 計画 結果 2 Aさん A 1 1 A 1 1 3 B 2 2 B 2 2 4 D 3 2 F 3 2 5 C 1 1 C 1 1 6 合計 7 6 7 6 7 Bさん X 1 1 A 1 1 8 D 3 2 D 3 2 9 10 C 2 1 C 1 1 11 合計 6 4 5 4 仮に、作業は"A", "B", "C", "D", "E", "F", "X"の7種類としました。 <<Sheet2>> A列 B列 C D 1 氏名 作業 計画 結果 2 Aさん A 2 2 3 B 4 4 4 C 2 2 5 D 3 2 6 E 0 0 7 F 3 2 8 X 0 0 9 Bさん A 1 1 10 B 0 0 11 C 3 2 12 D 6 4 13 E 0 0 14 F 0 0 15 X 1 1 C1: =SUMIF(Sheet1!$B$2:$E$6,$B2,Sheet1!$C$2:$F$6) D1: =SUMIF(Sheet1!$B$2:$E$6,$B2,Sheet1!$D$2:$G$6) 以下コピー C8: =SUMIF(Sheet1!$B$7:$E$11,$B9,Sheet1!$C$7:$F$11) D8: =SUMIF(Sheet1!$B$7:$E$11,$B9,Sheet1!$D$7:$G$11) 以下コピー あと、計画が0の作業は、オートフィルタ等で抽出してから行削除するとよいかもしれない。 ■参考コード Sub test1() Dim ws1 As Worksheet, ws2 As Worksheet Dim lastRow As Long, lastCol As Long Dim rng As Range Dim r As Range Dim r1 As Range, r2 As Range, r3 As Range Dim s As String Dim k As Long Dim ary Dim cnt As Long ary = Array("A", "B", "C", "D", "E", "F", "X") '作業は仮にこの7種だとする '■必要に応じて修正 cnt = UBound(ary) + 1 Set ws1 = Worksheets("Sheet1") '■必要に応じて修正 Set ws2 = Worksheets("Sheet2") '■必要に応じて修正 lastRow = ws1.Cells(Rows.Count, "A").End(xlUp).Row lastCol = ws1.Cells(1, Columns.Count).End(xlToLeft).Column Set rng = ws1.Range("A2", ws1.Cells(lastRow, "A")).SpecialCells(xlCellTypeBlanks) ws2.Range("A1:D1") = Array("氏名", "作業", "計画", "結果") k = 2 '各人ごとに作業別の計画数、実行数をSUMIF関数で計算 For Each r In rng.Areas Set r1 = r(1).Offset(-1, 1).Resize(r.Cells.Count + 2, lastCol - 3) Set r2 = r1.Offset(, 1) Set r3 = r1.Offset(, 2) ws2.Cells(k, 1).Resize(cnt, 1) = r1(1).Offset(, -1) ws2.Cells(k, 2).Resize(cnt, 1) = Application.Transpose(ary) '作業名 '作業の計画数を抽出 s = "=SUMIF(" & r1.Address(True, True, , True) & "," _ & ws2.Cells(k, 2).Address(False, True) & "," _ & r2.Address(True, True, , True) & ")" ws2.Cells(k, 3).Resize(cnt, 1).Formula = s ''値だけにするには ''ws2.Cells(k, 3).Resize(cnt, 1).Value = ws2.Cells(k, 3).Resize(cnt, 1).Value '作業の実行数を抽出 s = "=SUMIF(" & r1.Address(True, True, , True) & "," _ & ws2.Cells(k, 2).Address(False, True) & "," _ & r3.Address(True, True, , True) & ")" ws2.Cells(k, 4).Resize(cnt, 1).Formula = s ''ws2.Cells(k, 4).Resize(cnt, 1).Value = ws2.Cells(k, 4).Resize(cnt, 1).Value k = k + cnt Next '必要なら、このあとで、計画=0のものだけオートフィルタで抽出し、 'それを選択して行削除すればよいでしょう。 '氏名も、上と同じならフォントの色を白にする条件付き書式を使うとよいでしょう。 End Sub Sub test2() Dim ws1 As Worksheet, ws3 As Worksheet Dim lastRow As Long, lastCol As Long Dim dic As Object Dim dic2 As Object Dim d As Object Dim rng As Range Dim r As Range Dim mat, v, ary Dim k As Long, j As Long Dim pos As Long Dim key Dim m Set ws1 = Worksheets("Sheet1") '■必要に応じて修正 Set ws3 = Worksheets("Sheet3") '■必要に応じて修正 lastRow = ws1.Cells(Rows.Count, "A").End(xlUp).Row lastCol = ws1.Cells(1, Columns.Count).End(xlToLeft).Column Set dic = CreateObject("Scripting.Dictionary") Set rng = ws1.Range("A2", ws1.Cells(lastRow, "A")).SpecialCells(xlCellTypeBlanks) ' Dictionayを使って、計画数、実行数をカウント For Each r In rng.Areas mat = r(1).Offset(-1, 1).Resize(r.Cells.Count + 1, lastCol).Value Set dic2 = CreateObject("Scripting.Dictionary") For k = 1 To UBound(mat) For j = 1 To UBound(mat, 2) Step 3 v = mat(k, j) If v <> "" Then If dic2.exists(v) Then ary = dic2(v) ary(0) = ary(0) + mat(k, j + 1) ary(1) = ary(1) + mat(k, j + 2) dic2(v) = ary Else ary = Array(mat(k, j + 1), mat(k, j + 2)) dic2(v) = ary End If End If Next Next Set dic(r(1).Offset(-1).Value) = dic2 Set dic2 = Nothing Next '結果出力 ----------- ws3.Range("A1:D1") = Array("氏名", "作業", "計画", "結果") pos = 2 '2行目から書き出す For Each key In dic Set d = dic(key) ws3.Cells(pos, 1).Resize(d.Count, 1) = key ws3.Cells(pos, 2).Resize(d.Count, 1) = Application.Transpose(d.keys) m = d.items For k = 0 To UBound(m) ws3.Cells(pos + k, 3).Resize(1, 2) = m(k) Next pos = pos + d.Count Next '氏名、作業で昇順ソート With ws3 .Columns("A:D").Sort _ key1:=.Range("A2"), order1:=xlAscending, _ key2:=.Range("B2"), order1:=xlAscending, _ Header:=xlYes End With End Sub 初心者を自称されていますが、もしそうであれば、 Dictionaryを使った後者の方法は、もう少し先でトライしたほうがよいでしょう。 なお、コードを提示しましたのは、説明するのが却って難しいという理由に過ぎません。 ですので、ここはこう変更して欲しい、といったお話がありましても、 それにお応えする積りはありませんので予めお伝えしておきます。 |
![]() |
投稿日時: 23/10/19 20:06:46
投稿者: simple
|
---|---|
誤解してはいけないので補足します。
|
![]() |
投稿日時: 23/11/09 12:12:08
投稿者: ぽよ@初心者
|
---|---|
コード作成依頼をしてしまいすみませんでした。
|