Xin sửa giúp, Code VBA chạy chậm quá (1 người xem)

Liên hệ QC

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

ntquantn

Thành viên chính thức
Tham gia
13/4/12
Bài viết
72
Được thích
12
Xin chào cả nhà,

Mình có làm 1 form tổng kết nhanh dữ liệu bán hàng, code đã chạy được đúng ý (là khi thử với khoảng 100 dòng dữ liệu và ngày tra cứu ngắn), nhưng khi mình thử trên file dữ liệu cả năm (có khoảng 100.000 dòng) thì chạy chậm kinh khủng (mất khoảng 45ph mới xong)

Rất mong các bạn xem file đính kèm và sửa code giúp mình nhé.

Trân trọng cảm ơn
 

File đính kèm

Xin chào cả nhà,

Mình có làm 1 form tổng kết nhanh dữ liệu bán hàng, code đã chạy được đúng ý (là khi thử với khoảng 100 dòng dữ liệu và ngày tra cứu ngắn), nhưng khi mình thử trên file dữ liệu cả năm (có khoảng 100.000 dòng) thì chạy chậm kinh khủng (mất khoảng 45ph mới xong)

Rất mong các bạn xem file đính kèm và sửa code giúp mình nhé.

Trân trọng cảm ơn
làm trực tiếp trên cells thì nó sẽ rất chậm, nếu dữ liệu lớn thì bạn nên đưa vào mảng để xử lý
 
Upvote 0
Bạn có thể giúp mình được không, vì mình vẫn chưa hiểu về mảng nên không biết cách làm như thế nào với mảng.
 
Upvote 0
Nghiên cứu Excel 2016 và các chức năng mới của nó.
Dữ liệu hằng trăm ngàn dòng không phải là lĩnh vực của bảng tính thông dụng. Muốn làm việc cho hiệu quả thì phải qua các chức năng mở rộng thêm. Có nghĩa là phải cập nhật phiên bản đều đều.
 
Upvote 0
Thử code
Mã:
Private Sub Baocao()
Dim Arr(), i As Date, j As Long, k As Date, tungay As Date, denngay As Date, EndR As Long, tenbh As String, tenship As String
Dim tongtienban As Double, tongtienship As Double, tongtienbannv As Double, tongtienshipnv As Double, tongdtBL As Double, tongdtDL As Double

If Me.txtTungay.Value = "" Then
  MsgBox ("Hay nhap ngay bat dau")
  Exit Sub
Else
  tungay = Format(Me.txtTungay.Value, "dd/mm/yyyy")
End If

If Me.txtDenngay.Value = "" Then
  MsgBox ("Hay nhap ngay ket thuc")
  Exit Sub
Else
  denngay = Format(Me.txtDenngay.Value, "dd/mm/yyyy")
End If

If Me.cobnvBH.Value <> "" Then tenbh = Me.cobnvBH.Value

If Me.cobnvBH.Value <> "" Then tenship = Me.cobnvGH.Value

With Sheets("Banle")
  EndR = .Range("C" & Rows.Count).End(xlUp).Row
  Arr = .Range("B4:Q" & EndR).Value
End With

For i = 1 To UBound(Arr)
  If Arr(i, 2) >= tungay And Arr(i, 2) <= denngay Then
    If Arr(i, 3) = tenbh Then tongtienbannv = tongtienbannv + Arr(i, 14)
    If Left(Arr(i, 1), 2) = "HD" Then tongdtBL = tongdtBL + Arr(i, 14)
    If Left(Arr(i, 1), 2) = "DL" Then tongdtDL = tongdtDL + Arr(i, 14)
    tongtienban = tongtienban + Arr(i, 14)
   
    If IsNumeric(Arr(i, 15)) Then
      tongtienship = tongtienship + Arr(i, 15)
      If Arr(i, 16) = tenship Then tongtienshipnv = tongtienshipnv + Arr(i, 15)
    End If
  End If
Next i

Me.lbnvBH.Caption = Format(tongtienbannv, " #.###")
Me.lbnvGH.Caption = Format(tongtienshipnv, " #.###")
Me.lbdtBL.Caption = Format(tongdtBL, " #.###")
Me.lbdtDL.Caption = Format(tongdtDL, " #.###")
Me.lbPhiShip.Caption = Format(tongtienship, " #.###")
Me.lbTongDT.Caption = Format(tongtienban, " #.###")
End Sub
Cẩn thận với lệnh: Format(Me.txtTungay.Value, "dd/mm/yyyy")
 
Upvote 0
Nhồm vô Form của bạn, mình thấy rằng bạn cần tổng kết theo 8 tiêu chí (chỉ tiêu)
Theo mình bạn nên diễn giải tiếng Việt từng tiêu chí 1 một cách lần lượt;
Đọc VBA của bạn không chắc đại đa số hiểu hết cách tính của bạn. Trong số ít không hiểu í có mình.
Thôi thì bạn giới thiệu trước 4 hay 5 tiêu chí nào bạn cho là dễ trước đi xem sao.

Mong được bạn giúp đỡ!
 
Upvote 0
Thử code
Mã:
Private Sub Baocao()
Dim Arr(), i As Date, j As Long, k As Date, tungay As Date, denngay As Date, EndR As Long, tenbh As String, tenship As String
Dim tongtienban As Double, tongtienship As Double, tongtienbannv As Double, tongtienshipnv As Double, tongdtBL As Double, tongdtDL As Double

If Me.txtTungay.Value = "" Then
  MsgBox ("Hay nhap ngay bat dau")
  Exit Sub
Else
  tungay = Format(Me.txtTungay.Value, "dd/mm/yyyy")
End If

If Me.txtDenngay.Value = "" Then
  MsgBox ("Hay nhap ngay ket thuc")
  Exit Sub
Else
  denngay = Format(Me.txtDenngay.Value, "dd/mm/yyyy")
End If

If Me.cobnvBH.Value <> "" Then tenbh = Me.cobnvBH.Value

If Me.cobnvBH.Value <> "" Then tenship = Me.cobnvGH.Value

With Sheets("Banle")
  EndR = .Range("C" & Rows.Count).End(xlUp).Row
  Arr = .Range("B4:Q" & EndR).Value
End With

For i = 1 To UBound(Arr)
  If Arr(i, 2) >= tungay And Arr(i, 2) <= denngay Then
    If Arr(i, 3) = tenbh Then tongtienbannv = tongtienbannv + Arr(i, 14)
    If Left(Arr(i, 1), 2) = "HD" Then tongdtBL = tongdtBL + Arr(i, 14)
    If Left(Arr(i, 1), 2) = "DL" Then tongdtDL = tongdtDL + Arr(i, 14)
    tongtienban = tongtienban + Arr(i, 14)
  
    If IsNumeric(Arr(i, 15)) Then
      tongtienship = tongtienship + Arr(i, 15)
      If Arr(i, 16) = tenship Then tongtienshipnv = tongtienshipnv + Arr(i, 15)
    End If
  End If
Next i

Me.lbnvBH.Caption = Format(tongtienbannv, " #.###")
Me.lbnvGH.Caption = Format(tongtienshipnv, " #.###")
Me.lbdtBL.Caption = Format(tongdtBL, " #.###")
Me.lbdtDL.Caption = Format(tongdtDL, " #.###")
Me.lbPhiShip.Caption = Format(tongtienship, " #.###")
Me.lbTongDT.Caption = Format(tongtienban, " #.###")
End Sub
Cẩn thận với lệnh: Format(Me.txtTungay.Value, "dd/mm/yyyy")


Cảm ơn bạn rất nhiều,

Để mình nghiên cứu thêm code của bạn. Mình cũng vừa tự mò và làm theo dạng mảng. Mong bạn cũng xem đoạn code mình làm theo kiểu mảng, có gì góp ý thêm giúp mình với nhé. Híc ngồi gần 5h mới xong được đoạn code con con
 

File đính kèm

Upvote 0
Nhồm vô Form của bạn, mình thấy rằng bạn cần tổng kết theo 8 tiêu chí (chỉ tiêu)
Theo mình bạn nên diễn giải tiếng Việt từng tiêu chí 1 một cách lần lượt;
Đọc VBA của bạn không chắc đại đa số hiểu hết cách tính của bạn. Trong số ít không hiểu í có mình.
Thôi thì bạn giới thiệu trước 4 hay 5 tiêu chí nào bạn cho là dễ trước đi xem sao.

Mong được bạn giúp đỡ!

Tức là mình cần vài thông tin sơ bộ theo khoảng thời gian ( thường là từ 1 tuần đến 1 tháng) của:
1: Người bán hàng ( theo ca) ( là doanh thu tổng hợp của người bán ca đó)
2 Người giao hàng theo ca (số tiền phải trả cho người giao hàng)
3 Tổng công nợ của khách hàng chưa thanh toán
4 Tổng giá trị khuyến mại và giảm trừ (theo giá niêm yết)
5 Tổng doanh thu bán hàng khách lẻ
6 Tổng doanh thu giao đại lý (bán buôn)
7 Tổng thu tiền phí giao hàng ( cũng bằng tổng số tiền sẽ phải trả cho người giao hàng)
8 là tổng của bán lẻ và bán buôn (không gồm phí giao hàng và chưa tính giảm trừ ở mục 4)
 
Upvote 0
Thử code
Mã:
Private Sub Baocao()
Dim Arr(), i As Date, j As Long, k As Date, tungay As Date, denngay As Date, EndR As Long, tenbh As String, tenship As String
Dim tongtienban As Double, tongtienship As Double, tongtienbannv As Double, tongtienshipnv As Double, tongdtBL As Double, tongdtDL As Double

If Me.txtTungay.Value = "" Then
  MsgBox ("Hay nhap ngay bat dau")
  Exit Sub
Else
  tungay = Format(Me.txtTungay.Value, "dd/mm/yyyy")
End If

If Me.txtDenngay.Value = "" Then
  MsgBox ("Hay nhap ngay ket thuc")
  Exit Sub
Else
  denngay = Format(Me.txtDenngay.Value, "dd/mm/yyyy")
End If

If Me.cobnvBH.Value <> "" Then tenbh = Me.cobnvBH.Value

If Me.cobnvBH.Value <> "" Then tenship = Me.cobnvGH.Value

With Sheets("Banle")
  EndR = .Range("C" & Rows.Count).End(xlUp).Row
  Arr = .Range("B4:Q" & EndR).Value
End With

For i = 1 To UBound(Arr)
  If Arr(i, 2) >= tungay And Arr(i, 2) <= denngay Then
    If Arr(i, 3) = tenbh Then tongtienbannv = tongtienbannv + Arr(i, 14)
    If Left(Arr(i, 1), 2) = "HD" Then tongdtBL = tongdtBL + Arr(i, 14)
    If Left(Arr(i, 1), 2) = "DL" Then tongdtDL = tongdtDL + Arr(i, 14)
    tongtienban = tongtienban + Arr(i, 14)
 
    If IsNumeric(Arr(i, 15)) Then
      tongtienship = tongtienship + Arr(i, 15)
      If Arr(i, 16) = tenship Then tongtienshipnv = tongtienshipnv + Arr(i, 15)
    End If
  End If
Next i

Me.lbnvBH.Caption = Format(tongtienbannv, " #.###")
Me.lbnvGH.Caption = Format(tongtienshipnv, " #.###")
Me.lbdtBL.Caption = Format(tongdtBL, " #.###")
Me.lbdtDL.Caption = Format(tongdtDL, " #.###")
Me.lbPhiShip.Caption = Format(tongtienship, " #.###")
Me.lbTongDT.Caption = Format(tongtienban, " #.###")
End Sub
Cẩn thận với lệnh: Format(Me.txtTungay.Value, "dd/mm/yyyy")

Mã:
For i = 1 To UBound(Arr)
  If Arr(i, 2) >= tungay And Arr(i, 2) <= denngay Then
Code của bạn chạy nhanh thật. Cảm ơn bạn rất nhiều. Trong phần của bạn chỉ dùng 1 vòng for hay quá

Bạn có thể giúp mình thêm phần đếm số lượng hóa đơn (không trùng nhau) có dạng HDxxxxxx (hóa đơn bán lẻ) và DLxxxxxx (Hóa đơn bán buôn) được không?? (Được Voi đòi Hai bà trưng quá hic hic)
 

File đính kèm

  • HieuCD_GPE.png
    HieuCD_GPE.png
    59 KB · Đọc: 7
  • Dung FOR.png
    Dung FOR.png
    58.8 KB · Đọc: 8
  • tapdungarray.png
    tapdungarray.png
    58.6 KB · Đọc: 5
Lần chỉnh sửa cuối:
Upvote 0
Mã:
For i = 1 To UBound(Arr)
  If Arr(i, 2) >= tungay And Arr(i, 2) <= denngay Then
Code của bạn chạy nhanh thật. Cảm ơn bạn rất nhiều. Trong phần của bạn chỉ dùng 1 vòng for hay quá

Bạn có thể giúp mình thêm phần đếm số lượng hóa đơn (không trùng nhau) có dạng HDxxxxxx (hóa đơn bán lẻ) và DLxxxxxx (Hóa đơn bán buôn) được không?? (Được Voi đòi Hai bà trưng quá hic hic)
Chạy thử code mới
Mã:
Private Sub Baocao()
Dim Arr(), i As Long, j As Long, k As Long, tungay As Date, denngay As Date, EndR As Long
Dim HoaDon As String, tenbh As String, tenship As String, So_HD_BL As Long, So_HD_DL As Long
Dim TongTienBan As Double, TongTienShip As Double, TongTienBanNV As Double, TongTienShipNV As Double
Dim TongdtBL As Double, TongdtDL As Double, TongCongNo As Double, TongGiamTru As Double

If Me.txtTungay.Value = "" Then
  MsgBox ("Hay nhap ngay bat dau")
  Exit Sub
Else
  tungay = Format(Me.txtTungay.Value, "dd/mm/yyyy")
End If

If Me.txtDenngay.Value = "" Then
  MsgBox ("Hay nhap ngay ket thuc")
  Exit Sub
Else
  denngay = Format(Me.txtDenngay.Value, "dd/mm/yyyy")
End If

If Me.cobnvBH.Value <> "" Then tenbh = Me.cobnvBH.Value

If Me.cobnvBH.Value <> "" Then tenship = Me.cobnvGH.Value

With Sheets("Banle")
  EndR = .Range("C" & Rows.Count).End(xlUp).Row
  Arr = .Range("B4:R" & EndR).Value
End With
With CreateObject("scripting.dictionary")
  For i = 1 To UBound(Arr)
    If Arr(i, 2) >= tungay And Arr(i, 2) <= denngay Then
     
      HoaDon = Arr(i, 1)
      If Left(HoaDon, 2) = "HD" Then
        TongdtBL = TongdtBL + Arr(i, 14)
        If Not .exists(HoaDon) Then
          So_HD_BL = So_HD_BL + 1
          .Add HoaDon, ""
        End If
      ElseIf Left(HoaDon, 2) = "DL" Then
        TongdtDL = TongdtDL + Arr(i, 14)
        If Not .exists(HoaDon) Then
          So_HD_DL = So_HD_DL + 1
          .Add HoaDon, ""
        End If
      End If
     
      If Arr(i, 17) = "" Then TongCongNo = TongCongNo + Arr(i, 14)
     
      If Arr(i, 12) <> "" And IsNumeric(Arr(i, 12)) Then TongGiamTru = TongGiamTru + Arr(i, 12) * Arr(i, 14)
      If Arr(i, 13) <> "" And IsNumeric(Arr(i, 13)) Then TongGiamTru = TongGiamTru + Arr(i, 13)
     
      If Arr(i, 3) = tenbh Then TongTienBanNV = TongTienBanNV + Arr(i, 14)
      TongTienBan = TongTienBan + Arr(i, 14)
   
      If IsNumeric(Arr(i, 15)) Then
        TongTienShip = TongTienShip + Arr(i, 15)
        If Arr(i, 16) = tenship Then TongTienShipNV = TongTienShipNV + Arr(i, 15)
      End If
    End If
  Next i
End With
Me.lbnvBH.Caption = Format(TongTienBanNV, " #.###")
Me.lbnvGH.Caption = Format(TongTienShipNV, " #.###")
Me.lbhdBL.Caption = Format(So_HD_BL, " #.###")
Me.lbhdDL.Caption = Format(So_HD_DL, " #.###")
Me.lbTongCongno.Caption = Format(TongCongNo, " #.###")
Me.lbKMGT.Caption = Format(TongGiamTru, " #.###")
Me.lbdtBL.Caption = Format(TongdtBL, " #.###")
Me.lbdtDL.Caption = Format(TongdtDL, " #.###")
Me.lbPhiShip.Caption = Format(TongTienShip, " #.###")
Me.lbTongDT.Caption = Format(TongTienBan, " #.###")
End Sub
 
Upvote 0
Cảm ơn bạn nhiều lắm. ><></

Nếu có thể bạn giải thích giúp mình thêm về đoạn code bên dưới mà bạn dùng để đếm số hóa đơn (không trùng nhau) nhé, mình vẫn đang trong quá trình bắt đầu với VBA nên còn mù mờ quá.

With CreateObject("scripting.dictionary") For i = 1 To UBound(Arr) If Arr(i, 2) >= tungay And Arr(i, 2) <= denngay Then HoaDon = Arr(i, 1) If Left(HoaDon, 2) = "HD" Then TongdtBL = TongdtBL + Arr(i, 14) If Not .exists(HoaDon) Then So_HD_BL = So_HD_BL + 1 .Add HoaDon, "" End If ElseIf Left(HoaDon, 2) = "DL" Then TongdtDL = TongdtDL + Arr(i, 14) If Not .exists(HoaDon) Then So_HD_DL = So_HD_DL + 1 .Add HoaDon, "" End If End If
 
Upvote 0
Cảm ơn bạn nhiều lắm. ><></
Nếu có thể bạn giải thích giúp mình thêm về đoạn code bên dưới mà bạn dùng để đếm số hóa đơn (không trùng nhau) nhé, mình vẫn đang trong quá trình bắt đầu với VBA nên còn mù mờ quá.
Bạn tải toàn bộ loạt bài rất hay và thiết thực về VBA của bạn Befain để nắm căn bản về With ... End With, Dictionary , If ... Else(hoặc ElseIf) ... End If và nhiều vấn đề thiết yếu khác
Mã:
...
With CreateObject("scripting.dictionary") ' nhiêm vụ của Dic là loại trùng
  For i = 1 To UBound(Arr)
   If Arr(i, 2) >= tungay And Arr(i, 2) <= denngay Then
   
     HoaDon = Arr(i, 1) 'gán biến HoaDon là số hóa đơn dòng thứ i
     If Left(HoaDon, 2) = "HD" Then 'nếu 2 ký tự đầu  bên trái HoaDon là "HD" (hóa đơn bán lẽ) thì
       TongdtBL = TongdtBL + Arr(i, 14) 'cộng vào doanh thu bán lẽ
       
      If Not .exists(HoaDon) Then ' nếu số hóa đơn bán lẽ  chưa có trong Dic
         So_HD_BL = So_HD_BL + 1 'số HD bán lẽ tăng lên 1, nhằm đếm số HD bán lẽ
         .Add HoaDon, "" 'add số HD bán lẽ vào Dic, lần sau nếu gặp số hóa đơn nầy sẽ bị loại và không đếm
       End If
'nếu hoa đơn chỉ có 2 loại HD và DL thì thay lệnh dưới bằng Else, ElseIF .... nhằm tìm hóa đơn đại lý, đề phòng có loại hóa đơn khác, để đơn giản bạn có thể xét bán lẽ và đại lý bằng hai If ... End độc lập nhưng tốc độ code sẽ chậm hơn một chút và logic không chặc chẽ
    ElseIf Left(HoaDon, 2) = "DL" Then
       TongdtDL = TongdtDL + Arr(i, 14)
       If Not .exists(HoaDon) Then ' nếu số hóa đơn đại lý  chưa có trong Dic
         So_HD_DL = So_HD_DL + 1
         .Add HoaDon, ""
       End If
     End If
  ... 
  Next i
End With
 
Upvote 0
Web KT

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

Back
Top Bottom