返回列表 上一主題 發帖

[發問] 用VBA來執行SUMPRODUCT多條件統計

[發問] 用VBA來執行SUMPRODUCT多條件統計

各位前輩

原使用SUMPRODUCT多條件統計來執行六個月資料,但今日需執行二年資料,運算時間長,中途修改資料又要重新運算,等待時間長。
所以請教前輩,如何用VBA來執行SUMPRODUCT多條件統計運算。

W1.rar (11.63 KB)
100 字節以內
不支持自定義 Discuz! 代碼

回復 1# b9208
試試看
  1. Option Explicit
  2. Sub Ex()
  3.     Dim D(1 To 2) As Object, i As Integer, M As String
  4.     Dim R As Integer, C As Integer, A As Range
  5.     Set D(1) = CreateObject("scripting.dictionary")    '字典物件
  6.     Set D(2) = CreateObject("scripting.dictionary")
  7.     With Sheets("明細")
  8.         i = 6
  9.         Do While .Cells(i, "d") <> ""
  10.             M = .Cells(i, "D") & Mid(.Cells(i, "E"), 1, 4) & .Cells(i, "F")
  11.             D(1)(M) = D(1)(M) + 1                                                               '全部
  12.             M = .Cells(i, "D") & Mid(.Cells(i, "E"), 1, 4) & .Cells(i, "F") & .Cells(i, "L")
  13.             D(2)(M) = D(2)(M) + 1                                                               '區域
  14.             i = i + 1
  15.         Loop
  16.     End With
  17.      With Sheets("統計")
  18.         For Each A In .Range("F3:J12,F18:J27,F33:J42,F48:J57").Areas                     '修正為你的全部 及 區域 的範圍
  19.             With A
  20.                 For R = 3 To .Rows.Count - 1
  21.                     For C = 2 To .Columns.Count
  22.                         If .Cells(1) = "全部" Then                  '全部
  23.                             .Cells(R, C) = D(1)(.Cells(R, 1) & Mid(.Cells(1, C), 1, 4) & .Cells(2, C))
  24.                         Else                                        '區域
  25.                              .Cells(R, C) = D(2)(.Cells(R, 1) & Mid(.Cells(1, C), 1, 4) & .Cells(2, C) & .Cells(1))
  26.                         End If
  27.                     Next
  28.                 Next
  29.                 For C = 2 To .Columns.Count
  30.                     .Cells(.Rows.Count, C).FormulaR1C1 = "=SUM(R[-" & .Rows.Count - 3 & "]C:R[-1]C)"  '公式
  31.                     .Cells(.Rows.Count, C) = .Cells(.Rows.Count, C).Value
  32.                 Next
  33.         
  34.             End With
  35.         Next
  36.      End With
  37. End Sub
複製代碼
感恩的心......(在麻辣家族討論區.用心學習會有進步的)
但資源無限,後援有限,  一天1元的贊助,人人有能力.

TOP

回復 2# GBKEE
非常感謝版主回覆
下列補充說明:
1. 各輸出表格之週次及單位,由程式運算後自動代出。
2. 依B4:B13設定篩選單位,輸出篩選單位全部統計資料表。(如檔案內QWE,ASD單位)
3. 如果B18:B21有設定篩選區域,則再增加輸出該區域統計資料表。(如檔案內QWE,ASD單位之北部資料)
以上請參考附件

W111.rar (17.22 KB)
100 字節以內
不支持自定義 Discuz! 代碼

TOP

回復 3# b9208
試試看
  1. Option Explicit
  2. Dim D(1 To 2) As Object, 週次 As Object, 統計單位 As Variant, Ar        'Dim : 此模組的私用變數(僅此模組可用)
  3. Sub EX()
  4.     Dim i As Integer, ii As Integer, M As String, Rng As Range
  5.     'Dim Rng As Range, M As String
  6.     'Dim R As Integer, C As Integer
  7.     Set D(1) = CreateObject("scripting.dictionary")    '字典物件
  8.     Set D(2) = CreateObject("scripting.dictionary")
  9.     Set 週次 = CreateObject("scripting.dictionary")
  10.     With Sheets("統計")
  11.         i = Application.CountA(.[b4:b13])
  12.         統計單位 = Join(Application.Transpose(.Range(.[b4], .[b4].Offset(i - 1))), ",")        '統計單位=QWE,ASD
  13.     End With
  14.     With Sheets("明細")
  15.         i = 6
  16.         Do While .Cells(i, "D") <> ""
  17.             ' "," & 統計單位 & "," -> ,QWE,ASD,
  18.             If InStr("," & 統計單位 & ",", "," & .Cells(i, "F") & ",") Then   '比對到  ,QWE,   ,ASD, .....
  19.                 週次(.Cells(i, "F").Value) = 週次(.Cells(i, "F").Value) & "," & Mid(.Cells(i, "E"), 1, 4)
  20.                 M = .Cells(i, "D") & Mid(.Cells(i, "E"), 1, 4) & .Cells(i, "F")
  21.                 D(1)(M) = D(1)(M) + 1                                                               '全部
  22.                 M = .Cells(i, "D") & Mid(.Cells(i, "E"), 1, 4) & .Cells(i, "F") & .Cells(i, "L")
  23.                 D(2)(M) = D(2)(M) + 1                                                               '區域
  24.             End If
  25.             i = i + 1
  26.         Loop
  27.     End With
  28.     統計單位 = Split(統計單位, ",")                                             ' QWE,ASD,ZXC 置於陣列
  29.     With Sheets("統計")
  30.         .[F:J].Clear
  31.         For i = 0 To UBound(統計單位)
  32.             Ar = Array("全部", "單位", "MON", "TUE", "WED", "THU", "FRI", "SAT", "SUN", "小計")
  33.             If i = 0 Then
  34.                 Set Rng = .[F3]
  35.             Else
  36.                 Set Rng = .Cells(.Rows.Count, "F").End(xlUp).Offset(6)          '每張表格間隔五列
  37.             End If
  38.             週次(統計單位(i)) = Mid(週次(統計單位(i)), 2)
  39.             週次(統計單位(i)) = Split(週次(統計單位(i)), ",")                   '取得週次
  40.    
  41.             表格製造 Rng, i
  42.             表格統計 Rng.CurrentRegion
  43.             
  44.             For ii = 0 To Application.CountA(.Range("B18:B21")) - 1
  45.                 Set Rng = .Cells(.Rows.Count, "F").End(xlUp).Offset(6)          '每張表格間隔五列
  46.                 Ar(0) = .[B18].Offset(ii)
  47.                 表格製造 Rng, i
  48.                 表格統計 Rng.CurrentRegion
  49.             Next
  50.     Next
  51. End With
  52. End Sub
  53. Private Sub 表格製造(Rng As Range, i As Integer)
  54.     Rng.Resize(UBound(Ar) + 1).Value = Application.Transpose(Ar)
  55.     With Rng.Offset(, 1).Resize(1, UBound(週次(統計單位(i))) + 1)
  56.         .Value = 週次(統計單位(i))
  57.         .Offset(1) = 統計單位(i)
  58.     End With
  59.     Rng.CurrentRegion.Borders.LineStyle = 1  '框線
  60. End Sub
  61. Private Sub 表格統計(Rng As Range)
  62.     Dim R As Integer, C As Integer
  63.     With Rng
  64.         For R = 3 To .Rows.Count - 1
  65.             For C = 2 To .Columns.Count
  66.                 If .Cells(1) = "全部" Then                  '全部
  67.                     .Cells(R, C) = D(1)(.Cells(R, 1) & Mid(.Cells(1, C), 1, 4) & .Cells(2, C))
  68.                 Else                                        '區域
  69.                     .Cells(R, C) = D(2)(.Cells(R, 1) & Mid(.Cells(1, C), 1, 4) & .Cells(2, C) & .Cells(1))
  70.                 End If
  71.             Next
  72.         Next
  73.         For C = 2 To .Columns.Count
  74.             .Cells(.Rows.Count, C).FormulaR1C1 = "=SUM(R[-" & .Rows.Count - 3 & "]C:R[-1]C)"  '公式
  75.             .Cells(.Rows.Count, C) = .Cells(.Rows.Count, C).Value
  76.         Next
  77.     End With
  78. End Sub
複製代碼
感恩的心......(在麻辣家族討論區.用心學習會有進步的)
但資源無限,後援有限,  一天1元的贊助,人人有能力.

TOP

回復 4# GBKEE
前輩您好
VBA經執行測試後,表格位置及數據都正確,
但每週數據都重複出現多筆。
例如2012年度有1201~1251週,計51週筆,
但程式執行後確產出6000多筆週次資料。
不懂原因
非常感謝指導
100 字節以內
不支持自定義 Discuz! 代碼

TOP

回復 5# b9208
上傳檔案看看
感恩的心......(在麻辣家族討論區.用心學習會有進步的)
但資源無限,後援有限,  一天1元的贊助,人人有能力.

TOP

回復 6# GBKEE
檔案如附件
謝謝

    W04.rar (25.29 KB)
100 字節以內
不支持自定義 Discuz! 代碼

TOP

回復 7# b9208
唉週次沒有弄好,更正如下
  1. Option Explicit
  2. Dim D(1 To 2) As Object, 週次 As Object, Ar '        'Dim : 此模組的私用變數(僅此模組可用)
  3. Sub EX()
  4.     Dim i As Integer, ii As Integer, M As String, Rng As Range, 統計單位 As Variant
  5.     Set D(1) = CreateObject("scripting.dictionary")    '字典物件
  6.     Set D(2) = CreateObject("scripting.dictionary")
  7.     Set 週次 = CreateObject("scripting.dictionary")
  8.     With Sheets("統計")
  9.         i = Application.CountA(.[b4:b13])
  10.         統計單位 = Join(Application.Transpose(.Range(.[b4], .[b4].Offset(i - 1))), ",")        '統計單位=QWE,ASD
  11.     End With
  12.     With Sheets("明細")
  13.         i = 6
  14.         Do While .Cells(i, "D") <> ""
  15.             ' "," & 統計單位 & "," -> ,QWE,ASD,
  16.             If InStr("," & 統計單位 & ",", "," & .Cells(i, "F") & ",") Then   '比對到  ,QWE,   ,ASD, .....
  17.                
  18.                 If InStr("," & 週次(.Cells(i, "F").Value) & ",", "," & Mid(.Cells(i, "E"), 1, 4)) & "," = 0 Then '統計單位: 比對週次不存在, .....
  19.                     週次(.Cells(i, "F").Value) = IIf(週次(.Cells(i, "F").Value) = "", "", 週次(.Cells(i, "F").Value) & ",") & Mid(.Cells(i, "E"), 1, 4)
  20.                 End If
  21.                
  22.                 M = .Cells(i, "D") & Mid(.Cells(i, "E"), 1, 4) & .Cells(i, "F")
  23.                 D(1)(M) = D(1)(M) + 1                                                               '全部
  24.                 M = .Cells(i, "D") & Mid(.Cells(i, "E"), 1, 4) & .Cells(i, "F") & .Cells(i, "L")
  25.                 D(2)(M) = D(2)(M) + 1                                                               '區域
  26.             End If
  27.             i = i + 1
  28.         Loop
  29.     End With
  30.     With Sheets("統計")
  31.         .[F:IQ].Clear
  32.         For i = 0 To Application.CountA(.Range("B4:B13")) - 1
  33.             Ar = Array("全部", "單位", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun", "小計")
  34.             If i = 0 Then
  35.                 Set Rng = .[F3]
  36.             Else
  37.                 Set Rng = .Cells(.Rows.Count, "F").End(xlUp).Offset(6)          '每張表格間隔五列
  38.             End If
  39.            
  40.             週次(.Range("B4").Offset(i).Value) = Split(週次(.Range("B4").Offset(i).Value), ",")
  41.             '取得統計單位之週次
  42.    
  43.             表格製造 Rng, .Range("B4").Offset(i)
  44.             表格統計 Rng.CurrentRegion
  45.             
  46.             For ii = 0 To Application.CountA(.Range("B18:B21")) - 1
  47.                 Set Rng = .Cells(.Rows.Count, "F").End(xlUp).Offset(6)          '每張表格間隔五列
  48.                 Ar(0) = .[B18].Offset(ii)
  49.                 表格製造 Rng, .Range("B4").Offset(i)
  50.                 表格統計 Rng.CurrentRegion
  51.             Next
  52.     Next
  53. End With
  54. End Sub
  55. Private Sub 表格製造(Rng As Range, 單位 As String)
  56.     Rng.Resize(UBound(Ar) + 1).Value = Application.Transpose(Ar)
  57.     With Rng.Offset(, 1).Resize(1, UBound(週次(單位)) + 1)
  58.         .Value = 週次(單位)
  59.         .Offset(1) = 單位
  60.     End With
  61.     Rng.CurrentRegion.Borders.LineStyle = 1  '框線
  62. End Sub
  63. Private Sub 表格統計(Rng As Range)
  64.     Dim R As Integer, C As Integer
  65.     With Rng
  66.         For R = 3 To .Rows.Count - 1
  67.             For C = 2 To .Columns.Count
  68.                 If .Cells(1) = "全部" Then                  '全部
  69.                     .Cells(R, C) = D(1)(.Cells(R, 1) & Mid(.Cells(1, C), 1, 4) & .Cells(2, C))
  70.                 Else                                        '區域
  71.                     .Cells(R, C) = D(2)(.Cells(R, 1) & Mid(.Cells(1, C), 1, 4) & .Cells(2, C) & .Cells(1))
  72.                 End If
  73.             Next
  74.         Next
  75.         For C = 2 To .Columns.Count
  76.             .Cells(.Rows.Count, C).FormulaR1C1 = "=SUM(R[-" & .Rows.Count - 3 & "]C:R[-1]C)"  '公式
  77.             .Cells(.Rows.Count, C) = .Cells(.Rows.Count, C).Value
  78.         Next
  79.     End With
  80. End Sub
複製代碼
感恩的心......(在麻辣家族討論區.用心學習會有進步的)
但資源無限,後援有限,  一天1元的贊助,人人有能力.

TOP

回復 8# GBKEE
GBKEE版主
非常感謝指導
執行ok
如果d欄至最後一筆資料其中有空格,則執行不完整。
今修訂增加判斷   Do While .Cells(i, "D") <> "" Or .Cells(i, "F") <> ""
執行就ok
另一修訂將Do迴圈改成For迴圈,也ok。
u = .[d65536].End(xlUp).Row
For i = 6 To u

請教於Excel 2010中判斷最後一筆資料列,應如何修改下面式子。
u = .[d65536].End(xlUp).Row
謝謝指導
100 字節以內
不支持自定義 Discuz! 代碼

TOP

回復 9# b9208
  1. Sub Ex()
  2.     Dim U As Long, E As String
  3.     Select Case Application.Version
  4.         Case "12.0"
  5.             E = 2007
  6.         Case "11.0"
  7.             E = 2003
  8.         Case "10.0"
  9.             E = 2002
  10.         Case "9.0"
  11.             E = 2000
  12.         Case "8.0"
  13.             E = 97
  14.         Case "7.0"
  15.             E = 95
  16.         Case "5.0"
  17.             E = "5.0"
  18.         Case Else
  19.             E = "未知"
  20.     End Select
  21.     With ActiveSheet
  22.       MsgBox "Excel " & E & " 版本的總列數:  " & .Rows.Count
  23.         U = .Range("d" & .Rows.Count).End(xlUp).Row
  24.     End With
  25. End Sub
複製代碼
感恩的心......(在麻辣家族討論區.用心學習會有進步的)
但資源無限,後援有限,  一天1元的贊助,人人有能力.

TOP

        靜思自在 : 【時日莫空過】一個人在世間做了多少事,就等於壽命有多長。因此必須與時間競爭,切莫使時日空過。
返回列表 上一主題