VBA-003.多表日期彙總求和

1、需求

如下圖:一個車號一個工作表且格式一樣,現根據各工作表B列日期,按照彙總表的第一行月份2019年1月、2月······統計出各車號的E列金額。麻煩各位老師幫看看怎麼寫代碼


VBA-003.多表日期彙總求和


VBA-003.多表日期彙總求和

2、思路分析

1)彙總條件是年+月,所以需要將數據表中的相關數據按照年+月的形式彙總求和

2)將彙總後的結果與彙總條件比對,對坐入號

3)因為要對每個數據表進行日期彙總求和,所以將此功能單獨剝離,主過程中調用即可,減少代碼調試困難

3、代碼

<code>Sub 名稱彙總()
'   ws_name:工作表名變量參數,字符型
'   last_row: 彙總表已使用區域的總行數,數值型
'   retruan_arr:接收日期彙總功能的返回值,數組類型
'   dt:存儲年+月的變量,字符型
    Dim ws_name As String, i&, last_row&, return_arr, x&, dt As String
    
    last_row = ActiveSheet.UsedRange.Rows.Count
    Range("e2:v" & last_row).ClearContents
'   return_arr接收所有數據表的返回值
    ReDim return_arr(1 To last_row)
    
    For i = 2 To last_row
        ws_name = Cells(i, 3)
        '   案例存在多張隱藏表,且隱藏表的結構與其他數據表結構不一,故使用隱藏判斷跳過不予彙總
        '   如果工作簿中無隱藏表,此判斷可刪除
        '   Visible = -1,表示工作表為可見狀態
        If Worksheets(ws_name).Visible = -1 Then
            '   將所有的數據表(結果是一個二維數組)嵌套寫入一個一維數組中,整體形成一個三維數組
            return_arr(i - 1) = 日期彙總(ws_name)
        End If
    Next i
    
'   彙總表區域的日期與return_arr中的日期維度相比較,如一致則寫入對應的單元格中
    For i = 1 To last_row
    '   彙總表的日期區域,即E1:V1區域,共計18個月
        For x = 1 To 18
        '   因為表中存在隱藏表,故return_arr一維數組存在空白佔位元素,故須進行忽略錯誤處理
            On Error Resume Next
            '   循環return_arr每個數據表中的日期維度
            For y = 1 To UBound(return_arr(i), 1)
                dt = Year(Cells(1, x + 4)) & "-" & Month(Cells(1, x + 4))
                If dt = return_arr(i)(y, 1) Then
                '   return_arr(i)(y,2):return_arr第i個元素中第y行,第2列的元素
                    Cells(i + 1, x + 4) = return_arr(i)(y, 2)
                End If
            Next y
        Next x
    Next i
End Sub


Function 日期彙總(ws_name As String)
    
    Dim arr, last_row, x&, brr(), i&, temp As String
    last_row = Worksheets(ws_name).UsedRange.Rows.Count
    arr = Worksheets(ws_name).Range("b2:e" & last_row)

    For x = 1 To last_row
    
    '   將2019/1/24改為年+月格式,即2019-4
        temp = Year(arr(x, 1)) & "-" & Month(arr(x, 1))
        On Error Resume Next
        '   檢測工作表的B列日期處理後的temp是否已存在於brr數組中,如存在,則對應元素累加,否則新增相應元素
        '   match函數的第二個參數Array必須是一維數組,而brr是二維數組,故須使用Index函數提取單維數據
        '   Index(brr,1,0):brr是一個行數為2,列數不固定的數組,第一行值為日期,第二行值為金額累加值,故此句的意思即提取brr的第一行數據,也就是日期行
        temp = Application.WorksheetFunction.Match(temp, Application.WorksheetFunction.Index(brr, 1, 0), 0)
        '   如果元素存在數組中,則程序不報錯,即Err=0,否則程序報錯,Err>0
        If Err = 0 Then
            brr(2, Int(temp)) = brr(2, Int(temp)) + arr(x, 4)
        Else
            i = i + 1
            ReDim Preserve brr(1 To 2, 1 To i)
            brr(1, i) = temp
            brr(2, i) = arr(x, 4)
        End If
    Next x
    '   個人習慣,將日期行與金額行轉置為日期列與金額列,便於主過程使用
    日期彙總 = Application.WorksheetFunction.Transpose(brr)
    
End Function
/<code> 


VBA-003.多表日期彙總求和


分享到:


相關文章: