Xin trợ giúp code VBA đếm và tính tổng nhiều điều kiện (1 người xem)

Liên hệ QC

Người dùng đang xem chủ đề này

Hugo Nguyen

Thành viên mới
Tham gia
15/8/20
Bài viết
38
Được thích
4
Xin chào mọi người!
Mình có 1 file gồm 2 sheet:
Sheet 1 chứa dữ liệu nguồn có 8 cột nhưng số hàng lên tới 1 triệu hàng, chứa dữ liệu giao dịch khách hàng
Sheet 2 là sheet tổng hợp, số hàng cũng lên tới 1000 hàng, mình hiện tại đang dùng hàm COUNTIFS và SUMIFS để tính số lần giao dịch và số tiền giao dịch của mỗi khách hàng (nhiều điều kiện)
Vấn đề là dữ liệu nguồn quá nhiều nên công thức không thể chạy được, mong các bác chỉ giáo chuyển công thức sang VBA giúp
Xin cảm ơn nhiều!
 

File đính kèm

Xin chào mọi người!
Mình có 1 file gồm 2 sheet:
Sheet 1 chứa dữ liệu nguồn có 8 cột nhưng số hàng lên tới 1 triệu hàng, chứa dữ liệu giao dịch khách hàng
Sheet 2 là sheet tổng hợp, số hàng cũng lên tới 1000 hàng, mình hiện tại đang dùng hàm COUNTIFS và SUMIFS để tính số lần giao dịch và số tiền giao dịch của mỗi khách hàng (nhiều điều kiện)
Vấn đề là dữ liệu nguồn quá nhiều nên công thức không thể chạy được, mong các bác chỉ giáo chuyển công thức sang VBA giúp
Xin cảm ơn nhiều!
Up cái file lên xem thử.
 
Trời. Công ty quản lý hàng triệu phát sinh giao dịch khách hàng bằng Excel. Hà tiện dữ.
Quăng cái bảng phát sinh vào một Data Model rồi từ đó mà tổng hợp này nọ.
Nếu bạn không biết Data Model trong Excel là gì thì tìm học là vừa. Dữ liệu khủng kiểu này thì không thể mỗi công việc lại nhờ người ta viết code VBA.
 
Trời. Công ty quản lý hàng triệu phát sinh giao dịch khách hàng bằng Excel. Hà tiện dữ.
Quăng cái bảng phát sinh vào một Data Model rồi từ đó mà tổng hợp này nọ.
Nếu bạn không biết Data Model trong Excel là gì thì tìm học là vừa. Dữ liệu khủng kiểu này thì không thể mỗi công việc lại nhờ người ta viết code VBA.
Do em cũng mới làm cái này thời gian ngắn đây thôi, hiện tại vẫn chỉ dùng hàm excel và VBA xử lý, cảm ơn lời khuyên và gợi ý của bác :)
 
Xin chào mọi người!
Mình có 1 file gồm 2 sheet:
Sheet 1 chứa dữ liệu nguồn có 8 cột nhưng số hàng lên tới 1 triệu hàng, chứa dữ liệu giao dịch khách hàng
Sheet 2 là sheet tổng hợp, số hàng cũng lên tới 1000 hàng, mình hiện tại đang dùng hàm COUNTIFS và SUMIFS để tính số lần giao dịch và số tiền giao dịch của mỗi khách hàng (nhiều điều kiện)
Vấn đề là dữ liệu nguồn quá nhiều nên công thức không thể chạy được, mong các bác chỉ giáo chuyển công thức sang VBA giúp
Xin cảm ơn nhiều!
Thử code
Mã:
Sub XYZ()
  Dim sArr(), tArr, Arr, kRes(), tRes(), Res, Dic As Object
  Dim sRow&, sCol&, n&, i&, iR&, k&, jC&, iKey
 
  Application.ScreenUpdating = False
  tArr = Array("D2:AJ2", "AL2:BR2", "BT2:CS2", "CU2:DT2")
  ReDim tRes(0 To 3)
  Set Dic = CreateObject("scripting.dictionary")
  With Sheets("DATA")
    sArr = .Range("A2", .Range("I" & Rows.Count).End(xlUp)).Value
  End With
  sRow = UBound(sArr)
  ReDim kRes(1 To sRow / 5, 1 To 1)
  For i = 1 To sRow
    iKey = sArr(i, 1)
    If Dic.exists(iKey) = False Then
      k = k + 1
      kRes(k, 1) = iKey
      Dic.Add iKey, k
    End If
  Next i
  With Sheets("FINAL")
    For n = 0 To 3
      Arr = .Range(tArr(n)).Value
      sCol = UBound(Arr, 2)
      ReDim Res(1 To k, 1 To sCol)
      tRes(n) = Res
      For j = 1 To sCol - 2
        Dic.Item(n & "#" & Arr(1, j)) = j
      Next j
    Next n
    
    For i = 1 To sRow
      iR = Dic.Item(sArr(i, 1))
      n = 0
      If Dic.exists(n & "#" & sArr(i, 2)) Then
        jC = Dic.Item(n & "#" & sArr(i, 2))
        tRes(n)(iR, jC) = tRes(n)(iR, jC) + 1
      End If
      n = 1
      If Dic.exists(n & "#" & sArr(i, 2)) Then
        jC = Dic.Item(n & "#" & sArr(i, 2))
        tRes(n)(iR, jC) = tRes(n)(iR, jC) + sArr(i, 9)
      End If
      n = 2
      If Dic.exists(n & "#" & sArr(i, 4)) Then
        jC = Dic.Item(n & "#" & sArr(i, 4))
        tRes(n)(iR, jC) = tRes(n)(iR, jC) + 1
      End If
      n = 3
      If Dic.exists(n & "#" & sArr(i, 4)) Then
        jC = Dic.Item(n & "#" & sArr(i, 4))
        tRes(n)(iR, jC) = tRes(n)(iR, jC) + sArr(i, 9)
      End If
    Next i
    
    i = .Range("C" & Rows.Count).End(xlUp).Row
    If i > 3 Then .Range("C4:DT" & i).ClearContents
    .Range("C4").Resize(k, sCol) = kRes
    
    For n = 0 To 3
      Res = tRes(n)
      sCol = UBound(tRes(n), 2)
      For i = 1 To k
        For j = 1 To sCol - 2
          tRes(n)(i, sCol - 1) = tRes(n)(i, sCol - 1) + tRes(n)(i, j)
        Next j
        tRes(n)(i, sCol) = tRes(n)(i, sCol - 1) / (sCol - 2)
      Next i
      .Cells(4, .Range(tArr(n)).Column).Resize(k, sCol) = tRes(n)
    Next n
  End With
  Application.ScreenUpdating = True
End Sub
 
Thử code
Mã:
Sub XYZ()
  Dim sArr(), tArr, Arr, kRes(), tRes(), Res, Dic As Object
  Dim sRow&, sCol&, n&, i&, iR&, k&, jC&, iKey

  Application.ScreenUpdating = False
  tArr = Array("D2:AJ2", "AL2:BR2", "BT2:CS2", "CU2:DT2")
  ReDim tRes(0 To 3)
  Set Dic = CreateObject("scripting.dictionary")
  With Sheets("DATA")
    sArr = .Range("A2", .Range("I" & Rows.Count).End(xlUp)).Value
  End With
  sRow = UBound(sArr)
  ReDim kRes(1 To sRow / 5, 1 To 1)
  For i = 1 To sRow
    iKey = sArr(i, 1)
    If Dic.exists(iKey) = False Then
      k = k + 1
      kRes(k, 1) = iKey
      Dic.Add iKey, k
    End If
  Next i
  With Sheets("FINAL")
    For n = 0 To 3
      Arr = .Range(tArr(n)).Value
      sCol = UBound(Arr, 2)
      ReDim Res(1 To k, 1 To sCol)
      tRes(n) = Res
      For j = 1 To sCol - 2
        Dic.Item(n & "#" & Arr(1, j)) = j
      Next j
    Next n
   
    For i = 1 To sRow
      iR = Dic.Item(sArr(i, 1))
      n = 0
      If Dic.exists(n & "#" & sArr(i, 2)) Then
        jC = Dic.Item(n & "#" & sArr(i, 2))
        tRes(n)(iR, jC) = tRes(n)(iR, jC) + 1
      End If
      n = 1
      If Dic.exists(n & "#" & sArr(i, 2)) Then
        jC = Dic.Item(n & "#" & sArr(i, 2))
        tRes(n)(iR, jC) = tRes(n)(iR, jC) + sArr(i, 9)
      End If
      n = 2
      If Dic.exists(n & "#" & sArr(i, 4)) Then
        jC = Dic.Item(n & "#" & sArr(i, 4))
        tRes(n)(iR, jC) = tRes(n)(iR, jC) + 1
      End If
      n = 3
      If Dic.exists(n & "#" & sArr(i, 4)) Then
        jC = Dic.Item(n & "#" & sArr(i, 4))
        tRes(n)(iR, jC) = tRes(n)(iR, jC) + sArr(i, 9)
      End If
    Next i
   
    i = .Range("C" & Rows.Count).End(xlUp).Row
    If i > 3 Then .Range("C4:DT" & i).ClearContents
    .Range("C4").Resize(k, sCol) = kRes
   
    For n = 0 To 3
      Res = tRes(n)
      sCol = UBound(tRes(n), 2)
      For i = 1 To k
        For j = 1 To sCol - 2
          tRes(n)(i, sCol - 1) = tRes(n)(i, sCol - 1) + tRes(n)(i, j)
        Next j
        tRes(n)(i, sCol) = tRes(n)(i, sCol - 1) / (sCol - 2)
      Next i
      .Cells(4, .Range(tArr(n)).Column).Resize(k, sCol) = tRes(n)
    Next n
  End With
  Application.ScreenUpdating = True
End Sub
Cảm ơn bác, file ví dụ đã chạy OK, nhưng file thực tế của em số cột nhiều hơn cũng như hạng mục tính nhiều hơn, em đang sửa code của bác cho phù hợp, trong quá trình sửa gặp vấn đề mong bác chỉ giáo, cảm ơn bác.
 
Xin chào mọi người!
Mình có 1 file gồm 2 sheet:
Sheet 1 chứa dữ liệu nguồn có 8 cột nhưng số hàng lên tới 1 triệu hàng, chứa dữ liệu giao dịch khách hàng
Sheet 2 là sheet tổng hợp, số hàng cũng lên tới 1000 hàng, mình hiện tại đang dùng hàm COUNTIFS và SUMIFS để tính số lần giao dịch và số tiền giao dịch của mỗi khách hàng (nhiều điều kiện)
Vấn đề là dữ liệu nguồn quá nhiều nên công thức không thể chạy được, mong các bác chỉ giáo chuyển công thức sang VBA giúp
Xin cảm ơn nhiều!
Sao không thử với PivotTable.
 

File đính kèm

Thử code
Mã:
Sub XYZ()
  Dim sArr(), tArr, Arr, kRes(), tRes(), Res, Dic As Object
  Dim sRow&, sCol&, n&, i&, iR&, k&, jC&, iKey

  Application.ScreenUpdating = False
  tArr = Array("D2:AJ2", "AL2:BR2", "BT2:CS2", "CU2:DT2")
  ReDim tRes(0 To 3)
  Set Dic = CreateObject("scripting.dictionary")
  With Sheets("DATA")
    sArr = .Range("A2", .Range("I" & Rows.Count).End(xlUp)).Value
  End With
  sRow = UBound(sArr)
  ReDim kRes(1 To sRow / 5, 1 To 1)
  For i = 1 To sRow
    iKey = sArr(i, 1)
    If Dic.exists(iKey) = False Then
      k = k + 1
      kRes(k, 1) = iKey
      Dic.Add iKey, k
    End If
  Next i
  With Sheets("FINAL")
    For n = 0 To 3
      Arr = .Range(tArr(n)).Value
      sCol = UBound(Arr, 2)
      ReDim Res(1 To k, 1 To sCol)
      tRes(n) = Res
      For j = 1 To sCol - 2
        Dic.Item(n & "#" & Arr(1, j)) = j
      Next j
    Next n
   
    For i = 1 To sRow
      iR = Dic.Item(sArr(i, 1))
      n = 0
      If Dic.exists(n & "#" & sArr(i, 2)) Then
        jC = Dic.Item(n & "#" & sArr(i, 2))
        tRes(n)(iR, jC) = tRes(n)(iR, jC) + 1
      End If
      n = 1
      If Dic.exists(n & "#" & sArr(i, 2)) Then
        jC = Dic.Item(n & "#" & sArr(i, 2))
        tRes(n)(iR, jC) = tRes(n)(iR, jC) + sArr(i, 9)
      End If
      n = 2
      If Dic.exists(n & "#" & sArr(i, 4)) Then
        jC = Dic.Item(n & "#" & sArr(i, 4))
        tRes(n)(iR, jC) = tRes(n)(iR, jC) + 1
      End If
      n = 3
      If Dic.exists(n & "#" & sArr(i, 4)) Then
        jC = Dic.Item(n & "#" & sArr(i, 4))
        tRes(n)(iR, jC) = tRes(n)(iR, jC) + sArr(i, 9)
      End If
    Next i
   
    i = .Range("C" & Rows.Count).End(xlUp).Row
    If i > 3 Then .Range("C4:DT" & i).ClearContents
    .Range("C4").Resize(k, sCol) = kRes
   
    For n = 0 To 3
      Res = tRes(n)
      sCol = UBound(tRes(n), 2)
      For i = 1 To k
        For j = 1 To sCol - 2
          tRes(n)(i, sCol - 1) = tRes(n)(i, sCol - 1) + tRes(n)(i, j)
        Next j
        tRes(n)(i, sCol) = tRes(n)(i, sCol - 1) / (sCol - 2)
      Next i
      .Cells(4, .Range(tArr(n)).Column).Resize(k, sCol) = tRes(n)
    Next n
  End With
  Application.ScreenUpdating = True
End Sub
Em dùng Code bác sửa theo yêu cầu thực tế nhưng lúc chạy nó báo lỗi, VBA em lại mù mờ quá, em gửi bản em sửa lên đây nhờ bác xem sửa lại giúp em với, cảm ơn bác rất nhiều!
Bài đã được tự động gộp:

Sao không thử với PivotTable.
Vâng em cũng đang thử với Pivot Table, có vấn đề gì mong bác giúp đỡ, cảm ơn bác
 

File đính kèm

Em dùng Code bác sửa theo yêu cầu thực tế nhưng lúc chạy nó báo lỗi, VBA em lại mù mờ quá, em gửi bản em sửa lên đây nhờ bác xem sửa lại giúp em với, cảm ơn bác rất nhiều!
Bài đã được tự động gộp:


Vâng em cũng đang thử với Pivot Table, có vấn đề gì mong bác giúp đỡ, cảm ơn bác
Các cột mới, xét dữ liệu ở dòng 3
Mình không khuyến khích cờ bạc, bạn nhờ người khác
 
Thớt nói bên nguồn có hàng triệu dòng, bên tổng hợp cũng có hàng ngàn dòng. E rằng chỉ có Data Model mới đưa cho Power Pivot làm được.
Vâng dữ liệu nguồn mỗi tháng có khoảng 1 triệu dòng bác ạ, mà e muốn tổng hợp nhiều tháng một lần, nếu chỉ đơn thuần Pivot Tabel thì không thể làm đúng không bác?
Còn Data Model e chưa làm qua bao giờ? Cho e hỏi cái đó khó không bác?
 
Cũng giống như học Excel.
Muốn học thiết kế file trước thì lúc đầu khó lúc sau càng dễ, bởi vì thiết kế file thuận lợi thì công thức khá đơn giản.
Muốn học công thức trước thì lúc đầu dễ lúc sau càng lúc càng khó, bởi vì nếu file thiết kế không thuận lợi thì phải dùng công thức khủng.
 
Trường hợp của bạn giống của tôi, dữ liệu tổng hợp theo một số tháng nó lên tới hàng chục triệu dòng. Tôi nghĩ bạn học Power Bi hoặc Tableau sẽ dễ dàng xử lý hơn. Dùng excel tôi nghĩ không chịu nổi nhiệt đâu!
 
thật ra với dữ liệu lớn như vậy nếu lựa chọn mình sẽ chọn Pivot Table, với VBA chạy vòng lập xử lý đống dữ liệu đó lâu hơn nhiều, còn sumifs thì thôi thua luôn.
 
Web KT

Bài viết mới nhất

Back
Top Bottom