Nhờ thay thế hàm SUMPRODUCT trong file để Excel tính toán nhanh hơn (1 người xem)

Liên hệ QC

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

MinhKhai

Giải pháp Ếc-xào
Tham gia
16/4/08
Bài viết
941
Được thích
573
Bên cạnh hàm Vlookup thì em hay dùng hàm SUMPRODUCT vì nó rất dễ dùng để tính toán theo nhiều điều kiện.
Nhưng thật không may là đối với dữ liệu lớn, hàm SUMPRODUCT khiến file Excel chạy ì ạch 1 cách rõ rệt, cụ thể như trong file có link dưới đây.
Nhờ các anh chị gợi ý cách dùng hàm khác hoặc chuyển đổi giúp sang dùng VBA để tăng tốc độ tính toán mỗi khi có sự thay đổi trong sheet. (Em vẫn cần bật tính năng Auto Calculation của Excel)

Xin cảm ơn !

 
Bên cạnh hàm Vlookup thì em hay dùng hàm SUMPRODUCT vì nó rất dễ dùng để tính toán theo nhiều điều kiện.
Nhưng thật không may là đối với dữ liệu lớn, hàm SUMPRODUCT khiến file Excel chạy ì ạch 1 cách rõ rệt, cụ thể như trong file có link dưới đây.
Nhờ các anh chị gợi ý cách dùng hàm khác hoặc chuyển đổi giúp sang dùng VBA để tăng tốc độ tính toán mỗi khi có sự thay đổi trong sheet. (Em vẫn cần bật tính năng Auto Calculation của Excel)

Xin cảm ơn !

Dùng code này cho sheet.
Mã:
Private Sub Worksheet_Change(ByVal Target As Range)
    With Sheet1
        If Not Intersect(Target, .Range("D3", "F3")) Is Nothing Then
            If (.Range("D3").Value = Empty) Or (.Range("F3").Value = Empty) Then Exit Sub
            Dim sArr, Arr1(1 To 28, 1 To 14), Arr2(1 To 28, 1 To 33), i As Long, j As Long, k As Long, Tmp As String, iCol As Byte, nam%, Thang As Byte
            sArr = Sheet2.Range("B3:E" & Sheet2.Range("E1000000").End(xlUp).Row).Value
            iCol = IIf(.Range("D3").Value = "Kg", 3, 2)
            nam = .Range("F3").Value: Thang = Val(Right(.Range("D38"), 2))
            k = 0
            With CreateObject("Scripting.Dictionary")
                For i = 1 To UBound(sArr)
                    Tmp = sArr(i, 1)
                    j = Month(sArr(i, 4)) + 2
                    If Year(sArr(i, 4)) = nam Then
                        If Not .Exists(Tmp) Then
                            k = k + 1
                            .Add Tmp, k
                            
                            Arr1(k, 1) = Tmp: Arr1(k, 2) = sArr(i, iCol)
                            Arr1(k, j) = sArr(i, iCol)
                            
                            If Thang = Month(sArr(i, 4)) Then
                                Arr2(k, 1) = Tmp: Arr2(k, 2) = sArr(i, iCol)
                                Arr2(k, Day(sArr(i, 4)) + 2) = sArr(i, iCol)
                            End If
                        Else
                            Arr1(.Item(Tmp), 2) = Arr1(.Item(Tmp), 2) + sArr(i, iCol)
                            Arr1(.Item(Tmp), j) = Arr1(.Item(Tmp), j) + sArr(i, iCol)
                            
                            If Thang = Month(sArr(i, 4)) Then
                                j = Day(sArr(i, 4)) + 2
                                Arr2(.Item(Tmp), 2) = Arr2(.Item(Tmp), 2) + sArr(i, iCol)
                                Arr2(.Item(Tmp), j) = Arr2(.Item(Tmp), j) + sArr(i, iCol)
                            End If
                        End If
                    End If
                Next i
            End With
            .Range("C6:P33").ClearContents
            .Range("C40:AI67").ClearContents
            If k Then
                .Range("C6").Resize(k, 14) = Arr1
                .Range("C40").Resize(k, 33) = Arr2
            End If
        End If
    End With
End Sub
 
Dùng code này cho sheet.
Mã:
Private Sub Worksheet_Change(ByVal Target As Range)
    With Sheet1
        If Not Intersect(Target, .Range("D3", "F3")) Is Nothing Then
            If (.Range("D3").Value = Empty) Or (.Range("F3").Value = Empty) Then Exit Sub
            Dim sArr, Arr1(1 To 28, 1 To 14), Arr2(1 To 28, 1 To 33), i As Long, j As Long, k As Long, Tmp As String, iCol As Byte, nam%, Thang As Byte
            sArr = Sheet2.Range("B3:E" & Sheet2.Range("E1000000").End(xlUp).Row).Value
            iCol = IIf(.Range("D3").Value = "Kg", 3, 2)
            nam = .Range("F3").Value: Thang = Val(Right(.Range("D38"), 2))
            k = 0
            With CreateObject("Scripting.Dictionary")
                For i = 1 To UBound(sArr)
                    Tmp = sArr(i, 1)
                    j = Month(sArr(i, 4)) + 2
                    If Year(sArr(i, 4)) = nam Then
                        If Not .Exists(Tmp) Then
                            k = k + 1
                            .Add Tmp, k
                           
                            Arr1(k, 1) = Tmp: Arr1(k, 2) = sArr(i, iCol)
                            Arr1(k, j) = sArr(i, iCol)
                           
                            If Thang = Month(sArr(i, 4)) Then
                                Arr2(k, 1) = Tmp: Arr2(k, 2) = sArr(i, iCol)
                                Arr2(k, Day(sArr(i, 4)) + 2) = sArr(i, iCol)
                            End If
                        Else
                            Arr1(.Item(Tmp), 2) = Arr1(.Item(Tmp), 2) + sArr(i, iCol)
                            Arr1(.Item(Tmp), j) = Arr1(.Item(Tmp), j) + sArr(i, iCol)
                           
                            If Thang = Month(sArr(i, 4)) Then
                                j = Day(sArr(i, 4)) + 2
                                Arr2(.Item(Tmp), 2) = Arr2(.Item(Tmp), 2) + sArr(i, iCol)
                                Arr2(.Item(Tmp), j) = Arr2(.Item(Tmp), j) + sArr(i, iCol)
                            End If
                        End If
                    End If
                Next i
            End With
            .Range("C6:P33").ClearContents
            .Range("C40:AI67").ClearContents
            If k Then
                .Range("C6").Resize(k, 14) = Arr1
                .Range("C40").Resize(k, 33) = Arr2
            End If
        End If
    End With
End Sub
Đúng là dùng Code, file chạy phe phé. Cảm ơn bác rất nhiều
Khi chạy code cái ô C40:C67 bị xóa trắng, em chưa rõ nguyên nhân, bác chỉ giúp với

1586879292322.png
 
Đúng là dùng Code, file chạy phe phé. Cảm ơn bác rất nhiều
Khi chạy code cái ô C40:C67 bị xóa trắng, em chưa rõ nguyên nhân, bác chỉ giúp với

View attachment 235589
Sửa code của #2 nhé! Bỏ lệnh này ra ngoài lệnh IF.
Mã:
Arr2(k, 1) = Tmp
Cụ thể sửa.
Mã:
                       If Not .Exists(Tmp) Then
                            k = k + 1
                            .Add Tmp, k
                          
                            Arr1(k, 1) = Tmp: Arr1(k, 2) = sArr(i, iCol)
                            Arr1(k, j) = sArr(i, iCol)
                          
                            If Thang = Month(sArr(i, 4)) Then
                                Arr2(k, 1) = Tmp: Arr2(k, 2) = sArr(i, iCol)
                                Arr2(k, Day(sArr(i, 4)) + 2) = sArr(i, iCol)
                            End If
                        Else
                            Arr1(.Item(Tmp), 2) = Arr1(.Item(Tmp), 2) + sArr(i, iCol)
                            Arr1(.Item(Tmp), j) = Arr1(.Item(Tmp), j) + sArr(i, iCol)
                          
                            If Thang = Month(sArr(i, 4)) Then
                                j = Day(sArr(i, 4)) + 2
                                Arr2(.Item(Tmp), 2) = Arr2(.Item(Tmp), 2) + sArr(i, iCol)
                                Arr2(.Item(Tmp), j) = Arr2(.Item(Tmp), j) + sArr(i, iCol)
                            End If
                        End If
Thành
Mã:
                       If Not .Exists(Tmp) Then
                            k = k + 1
                            .Add Tmp, k
                          
                            Arr1(k, 1) = Tmp: Arr1(k, 2) = sArr(i, iCol)
                            Arr1(k, j) = sArr(i, iCol)
                            Arr2(k, 1) = Tmp
                            If Thang = Month(sArr(i, 4)) Then
                                Arr2(k, 2) = sArr(i, iCol)
                                Arr2(k, Day(sArr(i, 4)) + 2) = sArr(i, iCol)
                            End If
                        Else
                            Arr1(.Item(Tmp), 2) = Arr1(.Item(Tmp), 2) + sArr(i, iCol)
                            Arr1(.Item(Tmp), j) = Arr1(.Item(Tmp), j) + sArr(i, iCol)
                          
                            If Thang = Month(sArr(i, 4)) Then
                                j = Day(sArr(i, 4)) + 2
                                Arr2(.Item(Tmp), 2) = Arr2(.Item(Tmp), 2) + sArr(i, iCol)
                                Arr2(.Item(Tmp), j) = Arr2(.Item(Tmp), j) + sArr(i, iCol)
                            End If
                        End If
Ngoài ra code trên còn bổ sung thêm điều kiện ô D38, cụ thể sửa code ở #2 như sau:
Thay đoạn code.
Mã:
 If Not Intersect(Target, .Range("D3", "F3")) Is Nothing Then
            If (.Range("D3").Value = Empty) Or (.Range("F3").Value = Empty) Then Exit Sub
thành
Mã:
If Not Intersect(Target, .Range("D3,F3,D38")) Is Nothing Then
            If (.Range("D3").Value = Empty) Or (.Range("F3").Value = Empty) Or (.Range("D38").Value = Empty) Then Exit Sub
 
Lần chỉnh sửa cuối:
Sửa code của #2 nhé! Bỏ lệnh này ra ngoài lệnh IF.
Mã:
Arr2(k, 1) = Tmp
Cụ thể sửa.
Mã:
                       If Not .Exists(Tmp) Then
                            k = k + 1
                            .Add Tmp, k
                         
                            Arr1(k, 1) = Tmp: Arr1(k, 2) = sArr(i, iCol)
                            Arr1(k, j) = sArr(i, iCol)
                         
                            If Thang = Month(sArr(i, 4)) Then
                                Arr2(k, 1) = Tmp: Arr2(k, 2) = sArr(i, iCol)
                                Arr2(k, Day(sArr(i, 4)) + 2) = sArr(i, iCol)
                            End If
                        Else
                            Arr1(.Item(Tmp), 2) = Arr1(.Item(Tmp), 2) + sArr(i, iCol)
                            Arr1(.Item(Tmp), j) = Arr1(.Item(Tmp), j) + sArr(i, iCol)
                         
                            If Thang = Month(sArr(i, 4)) Then
                                j = Day(sArr(i, 4)) + 2
                                Arr2(.Item(Tmp), 2) = Arr2(.Item(Tmp), 2) + sArr(i, iCol)
                                Arr2(.Item(Tmp), j) = Arr2(.Item(Tmp), j) + sArr(i, iCol)
                            End If
                        End If
Thành
Mã:
                       If Not .Exists(Tmp) Then
                            k = k + 1
                            .Add Tmp, k
                         
                            Arr1(k, 1) = Tmp: Arr1(k, 2) = sArr(i, iCol)
                            Arr1(k, j) = sArr(i, iCol)
                            Arr2(k, 1) = Tmp
                            If Thang = Month(sArr(i, 4)) Then
                                Arr2(k, 2) = sArr(i, iCol)
                                Arr2(k, Day(sArr(i, 4)) + 2) = sArr(i, iCol)
                            End If
                        Else
                            Arr1(.Item(Tmp), 2) = Arr1(.Item(Tmp), 2) + sArr(i, iCol)
                            Arr1(.Item(Tmp), j) = Arr1(.Item(Tmp), j) + sArr(i, iCol)
                         
                            If Thang = Month(sArr(i, 4)) Then
                                j = Day(sArr(i, 4)) + 2
                                Arr2(.Item(Tmp), 2) = Arr2(.Item(Tmp), 2) + sArr(i, iCol)
                                Arr2(.Item(Tmp), j) = Arr2(.Item(Tmp), j) + sArr(i, iCol)
                            End If
                        End If
Ngoài ra code trên còn bổ sung thêm điều kiện ô D38, cụ thể sửa code ở #2 như sau:
Thay đoạn code.
Mã:
If Not Intersect(Target, .Range("D3", "F3")) Is Nothing Then
            If (.Range("D3").Value = Empty) Or (.Range("F3").Value = Empty) Then Exit Sub
thành
Mã:
If Not Intersect(Target, .Range("D3,F3,D38")) Is Nothing Then
            If (.Range("D3").Value = Empty) Or (.Range("F3").Value = Empty) Or (.Range("D38").Value = Empty) Then Exit Sub
Bác chỉ dẫn rất chi tiết và hiệu quả, đặc biệt phần thêm điều kiện ở ô D38.
Bây giờ chỉ là việc em tìm hiểu để khi thêm điều kiện tính toán thì sửa code như thế nào thôi.
Cảm ơn 2 bác, chúc 2 bác mạnh khỏe !
 
Web KT

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

Back
Top Bottom