Hỏi code nào chạy hàm max nhanh hơn ko?

  • Thread starter Thread starter qtm1987
  • Ngày gửi Ngày gửi
Liên hệ QC

qtm1987

Thành viên thường trực
Tham gia
15/9/09
Bài viết
340
Được thích
244
Nghề nghiệp
Kế toán tổng hợp
Trong excel mình gõ vào ô A2 = max($A$1:A1) + 1 {đây là cột số thứ tự 1 2 3 4 5 ....n số} rồi kéo công thức này cho các ô bên dưới. Nếu khoản chục hàng thì công thức xử lý nhanh nhưng nếu khoản 60.000 dòng thì thấy tốc độ xử lý công thức này rất chậm làm máy treo lun &&&%$R. Cho mình hỏi có code nào trong VBA thực hiện được công việc giống công thức này ko và tốc độ khi xử lý số dòng lớn như vậy có nhanh được không? Mong sự giúp đỡ của các bạn trong diễn đàn.
 

File đính kèm

Lần chỉnh sửa cuối:
Anh ndu96081631 ơi, cũng file đó giờ ở cột T là số thự tự của phiếu thu thỏa 3 điều kiện (giá trị tại cột A <> "", giá trị tại cột F = "1111", giá trị tại cột G <> "33311") thì mới đánh số thự tự. Cột T này có thể sử dụng code theo kiểu mảng mà anh viết cho cột A được không anh.
 
Upvote 0
Anh ndu96081631 ơi, cũng file đó giờ ở cột T là số thự tự của phiếu thu thỏa 3 điều kiện (giá trị tại cột A <> "", giá trị tại cột F = "1111", giá trị tại cột G <> "33311") thì mới đánh số thự tự. Cột T này có thể sử dụng code theo kiểu mảng mà anh viết cho cột A được không anh.
Vậy đánh STT cùng lúc cho cột A và cột T luôn nha
PHP:
Sub STT()
  Dim i As Long, n As Long, k As Long, tmp1 As String, tmp2 As String, sArray, Arr1(), Arr2()
  With Sheets("Phat sinh")
    sArray = .Range(.[A6], .[P65536].End(xlUp))
    ReDim Arr1(1 To UBound(sArray, 1), 1 To 1)
    ReDim Arr2(1 To UBound(sArray, 1), 1 To 1)
    For i = 1 To UBound(sArray, 1)
      If CStr(sArray(i, 16)) <> "" Then
        tmp2 = CStr(sArray(i, 16))
        If tmp2 <> tmp1 Then
          n = n + 1
          Arr1(i, 1) = n
          If (sArray(i, 6) = 1111) And (sArray(i, 7) <> 33311) Then
            k = k + 1
            Arr2(i, 1) = k
          End If
        End If
      End If
      tmp1 = CStr(sArray(i, 16))
    Next
    If n Then
      .Range("A6").Resize(i - 1).Value = Arr1
      .Range("T6").Resize(i - 1).Value = Arr2
    End If
  End With
End Sub
 
Upvote 0
Mọi người cho mình hỏi, với file excel số lượng dòng quá lớn thì những hàm công thức tính toán trong excel sẽ làm tốc độ đọc file chậm đúng không vậy. Cái file excel của mình sử dụng nhiều cột phụ để đi đến 1 kết quả nên dùng các hàm index, offset, match,.... khi mở file thì như rùa bò ////// bây giờ nếu mình sử dụng code để thay thế thì việc dùng hàm công thức của excel để viết trong VBA thì tốc độ có nhanh hơn không?
Trong file excel của mình, tại cột AJ (lọc ra giá trị thuế đầu ra), mình dùng quá nhiều cột phụ để tìm ra kết quả cho cột AJ, bây giờ mình dùng code này: (em bắt chước viết theo kiểu của anh ndu, có gì sai anh sửa giúp em với nhé -+*/ )
PHP:
Sub tinh33311()
Dim i As Long, j As Long, n As Long, sArray, Arr()
With Sheets("Phat sinh")
    sArray = .Range(.[A6], .[AO65536].End(xlUp))
    ReDim Arr(1 To UBound(sArray, 1), 1 To 1)
    For i = 1 To UBound(sArray, 1)
        For j = i + 1 To UBound(sArray, 1)
        If (CStr(sArray(j, 1)) = "") And (sArray(j, 7) = 33311) And (sArray(j, 3) = sArray(i, 34)) Then
            Arr(i, 1) = sArray(j, 10)
        End If
        Next
    Next
    .Range("AJ6").Resize(i - 1).Value = Arr
End With
End Sub
với 2 vòng for như thế này thì tốc độ có bị chậm khi dữ liệu lớn không?
 
Upvote 0
với 2 vòng for như thế này thì tốc độ có bị chậm khi dữ liệu lớn không?
Thì bạn cứ thí nghiệm đi sẽ có ngay câu trả lời, cần gì hỏi
Nếu như dùng mảng mà vẫn chậm thì:
- Xem lại cấu trúc dữ liệu ---> Suy nghĩ liệu có cần phải bố trí lại cho hợp lý hơn không?
- Xem lại giải thuật của code ---> Suy nghĩ xem phương án mà ta đang dùng trong code liệu đã tối ưu chưa?
2 cái này rất quan trọng đấy
 
Upvote 0
Anh NDU xem giúp em lỗi này với. Tại cột C em có công thức=IF(N65=N64,C64,IF(T65<>0,"PT_"&RIGHT("000"&T65,4),IF(U65<>0,"PC_"&RIGHT("000"&U65,4),"CK_"&RIGHT("000"&V65,4)))) và em đổi sang dùng code cho cột C này như sau:
PHP:
Sub soct()
Dim i As Long, j As Long, tmp1 As String, tmp2 As String, sArray, Arr()
With Sheets("Phat sinh")
    sArray = .Range(.[A6], .[AG65536].End(xlUp))
    tmp1 = CStr(.Range("P5").Value)
    ReDim Arr(1 To UBound(sArray, 1), 1 To 1)
    For i = 1 To UBound(sArray, 1)
    If (CStr(sArray(i, 6)) = "1111") Then
        If sArray(i, 16) <> "" And CStr(sArray(i, 16)) = tmp1 Then
            j = i - 1
            Arr(i, 1) = sArray(j, 3)
        ElseIf sArray(i, 16) <> "" And CStr(sArray(i, 16)) <> tmp1 Then
            Arr(i, 1) = "PT_" & Right("0000" & sArray(i, 20), 4)
        End If
    ElseIf (CStr(sArray(i, 7)) = "1111") Then
        If sArray(i, 16) <> "" And CStr(sArray(i, 16)) = tmp1 Then
            j = i - 1
            Arr(i, 1) = sArray(j, 3)
        ElseIf sArray(i, 16) <> "" And CStr(sArray(i, 16)) <> tmp1 Then
            Arr(i, 1) = "PC_" & Right("0000" & sArray(i, 21), 4)
        End If
    ElseIf (CStr(sArray(i, 6)) <> "1111") And (CStr(sArray(i, 7)) <> "1111") Then
        If sArray(i, 16) <> "" And CStr(sArray(i, 16)) = tmp1 Then
            j = i - 1
            Arr(i, 1) = sArray(j, 3)
        ElseIf sArray(i, 16) <> "" And CStr(sArray(i, 16)) <> tmp1 Then
            Arr(i, 1) = "CK_" & Right("0000" & sArray(i, 22), 4)
        End If
    End If
    tmp1 = sArray(i, 16)
    Next
    .Range("C6").Resize(i - 1).Value = Arr
End With
End Sub
khi chạy code này thì em phải chạy code 3 lần thì nó mới ra kết quả (click vào nút command button 3 hoặc 4 lần) code em sai chỗ nào vậy anh.
 

File đính kèm

Upvote 0
Anh NDU xem giúp em lỗi này với. Tại cột C em có công thức=IF(N65=N64,C64,IF(T65<>0,"PT_"&RIGHT("000"&T65,4),IF(U65<>0,"PC_"&RIGHT("000"&U65,4),"CK_"&RIGHT("000"&V65,4)))) và em đổi sang dùng code cho cột C này như sau:
PHP:
Sub soct()
Dim i As Long, j As Long, tmp1 As String, tmp2 As String, sArray, Arr()
With Sheets("Phat sinh")
    sArray = .Range(.[A6], .[AG65536].End(xlUp))
    tmp1 = CStr(.Range("P5").Value)
    ReDim Arr(1 To UBound(sArray, 1), 1 To 1)
    For i = 1 To UBound(sArray, 1)
    If (CStr(sArray(i, 6)) = "1111") Then
        If sArray(i, 16) <> "" And CStr(sArray(i, 16)) = tmp1 Then
            j = i - 1
            Arr(i, 1) = sArray(j, 3)
        ElseIf sArray(i, 16) <> "" And CStr(sArray(i, 16)) <> tmp1 Then
            Arr(i, 1) = "PT_" & Right("0000" & sArray(i, 20), 4)
        End If
    ElseIf (CStr(sArray(i, 7)) = "1111") Then
        If sArray(i, 16) <> "" And CStr(sArray(i, 16)) = tmp1 Then
            j = i - 1
            Arr(i, 1) = sArray(j, 3)
        ElseIf sArray(i, 16) <> "" And CStr(sArray(i, 16)) <> tmp1 Then
            Arr(i, 1) = "PC_" & Right("0000" & sArray(i, 21), 4)
        End If
    ElseIf (CStr(sArray(i, 6)) <> "1111") And (CStr(sArray(i, 7)) <> "1111") Then
        If sArray(i, 16) <> "" And CStr(sArray(i, 16)) = tmp1 Then
            j = i - 1
            Arr(i, 1) = sArray(j, 3)
        ElseIf sArray(i, 16) <> "" And CStr(sArray(i, 16)) <> tmp1 Then
            Arr(i, 1) = "CK_" & Right("0000" & sArray(i, 22), 4)
        End If
    End If
    tmp1 = sArray(i, 16)
    Next
    .Range("C6").Resize(i - 1).Value = Arr
End With
End Sub
khi chạy code này thì em phải chạy code 3 lần thì nó mới ra kết quả (click vào nút command button 3 hoặc 4 lần) code em sai chỗ nào vậy anh.
Theo công thức màu đỏ cho ở trên thì code phải vầy mới đúng
PHP:
Sub soct()
  Dim i As Long, j As Long, tmp1 As String, tmp2 As String, sArray, Arr()
  With Sheets("Phat sinh")
    sArray = .Range(.[A6], .[A65536].End(xlUp)).Resize(, 22).Value
    tmp1 = CStr(.Range("N5").Value)
    tmp2 = CStr(.Range("C5").Value)
    ReDim Arr(1 To UBound(sArray, 1), 1 To 1)
    For i = 1 To UBound(sArray, 1)
      If CStr(sArray(i, 14)) = tmp1 Then
        Arr(i, 1) = tmp2
      ElseIf CStr(sArray(i, 20)) <> "" Then
        Arr(i, 1) = "PT_" & Right("0000" & sArray(i, 20), 4)
      ElseIf sArray(i, 21) <> "" Then
        Arr(i, 1) = "PC_" & Right("0000" & sArray(i, 21), 4)
      Else
        Arr(i, 1) = "CK_" & Right("0000" & sArray(i, 22), 4)
      End If
      tmp1 = CStr(sArray(i, 14))
      tmp2 = CStr(sArray(i, 3))
    Next
    .Range("C6").Resize(i - 1).Value = Arr
  End With
End Sub
Code này dùng để đánh STT cho cột C
 
Lần chỉnh sửa cuối:
Upvote 0
Theo công thức màu đỏ cho ở trên thì code phải vầy mới đúng
PHP:
Sub soct()
  Dim i As Long, j As Long, tmp1 As String, tmp2 As String, sArray, Arr()
  With Sheets("Phat sinh")
    sArray = .Range(.[A6], .[A65536].End(xlUp)).Resize(, 22).Value
    tmp1 = CStr(.Range("N5").Value)
    tmp2 = CStr(.Range("C5").Value)
    ReDim Arr(1 To UBound(sArray, 1), 1 To 1)
    For i = 1 To UBound(sArray, 1)
      If CStr(sArray(i, 14)) = tmp1 Then
        Arr(i, 1) = tmp2
      ElseIf CStr(sArray(i, 20)) <> "" Then
        Arr(i, 1) = "PT_" & Right("0000" & sArray(i, 20), 4)
      ElseIf sArray(i, 21) <> "" Then
        Arr(i, 1) = "PC_" & Right("0000" & sArray(i, 21), 4)
      Else
        Arr(i, 1) = "CK_" & Right("0000" & sArray(i, 22), 4)
      End If
      tmp1 = CStr(sArray(i, 14))
      tmp2 = CStr(sArray(i, 3))
    Next
    .Range("C6").Resize(i - 1).Value = Arr
  End With
End Sub
Anh ơi, em vẫn không hiểu tại sao chạy code này vẫn phải chạy code nhiều lần thì mới điền hết số chứng từ vào cột C. Có cách nào điền hết số chứng từ vào cột C chỉ với 1 lần chạy code không anh.
 
Upvote 0
Anh ơi, em vẫn không hiểu tại sao chạy code này vẫn phải chạy code nhiều lần thì mới điền hết số chứng từ vào cột C. Có cách nào điền hết số chứng từ vào cột C chỉ với 1 lần chạy code không anh.
Tôi sơ ý!
Bạn sửa chổ này:
tmp2 = CStr(sArray(i, 3))
thành:
tmp2 = CStr(Arr(i, 1))
thử lại nhé
 
Upvote 0
hay quá. code chạy được rồi /-*+/. cám ơn anh NDU nhìu nhìu
 
Upvote 0
Em thay code này:
PHP:
sArray = .Range(.[A6], .[A65536].End(xlUp)).Resize(, 22).Value
bằng code:
PHP:
sArray = .Range(.[A6], .[V65536].End(xlUp))
2 kiểu này là giống nhau đúng không anh NDU.-+*/
 
Upvote 0
Sẽ giống, chỉ khi dòng cuối có dữ liệu của cột 'A' trùng với dòng cuối có dữ liệu của cột 'V'
 
Upvote 0
PHP:
Sub Thang()
Dim i As Long, arr(), sArray
With Sheets("Phat sinh")
    .Range("AF6:AF65536").ClearContents
    sArray = .Range(.[C6], .[D65536].End(xlUp))
    ReDim arr(1 To UBound(sArray, 1), 1 To 1) 
    For i = 1 To UBound(sArray, 1)
        If Not IsEmpty(sArray(i, 2)) Then
            arr(i, 1) = Month(sArray(i, 2))
        Else
            .Range("D" & (i + 5)).Select
            MsgBox "Vui long nhap vao ngay chung tu tai o D" & (i + 5), vbYesNo, "Thong bao"    
        End If
    Next
.Range("AF6").Resize(i, 1).Value = arr
End With
End Sub
Khi chạy code này tại sao ô cuối cùng trong cột D khi giá trị rỗng thì code thỏa điều kiện nhưng ko nhảy ra thông báo nhập ngày chứng từ cho ô này và kết quả ở ô cuối cột AF luôn hiện giá trị #N/A. Ai giúp mình lỗi này với.
 

File đính kèm

Upvote 0
PHP:
Sub Thang()
Dim i As Long, arr(), sArray
With Sheets("Phat sinh")
    .Range("AF6:AF65536").ClearContents
    sArray = .Range(.[C6], .[D65536].End(xlUp))
    ReDim arr(1 To UBound(sArray, 1), 1 To 1) 
    For i = 1 To UBound(sArray, 1)
        If Not IsEmpty(sArray(i, 2)) Then
            arr(i, 1) = Month(sArray(i, 2))
        Else
            .Range("D" & (i + 5)).Select
            MsgBox "Vui long nhap vao ngay chung tu tai o D" & (i + 5), vbYesNo, "Thong bao"    
        End If
    Next
.Range("AF6").Resize(i, 1).Value = arr
End With
End Sub
Khi chạy code này tại sao ô cuối cùng trong cột D khi giá trị rỗng thì code thỏa điều kiện nhưng ko nhảy ra thông báo nhập ngày chứng từ cho ô này và kết quả ở ô cuối cột AF luôn hiện giá trị #N/A. Ai giúp mình lỗi này với.
Khi chạy code này tại sao ô cuối cùng trong cột D khi giá trị rỗng thì code thỏa điều kiện nhưng ko nhảy ra thông báo nhập ngày chứng từ cho ô này ?
Code chạy đúng, bạn khai báo:
Câu 1
sArray = .Range(.[C6], .[D65536].End(xlUp))
Cell cuối cùng có dữ liệu ở cột D là cell [D62] chứ không phải cell [D63]
Nếu cột C luôn chứa đủ dữ liệu bạn khai báo lại:
sArray = .Range(.[C6], .[C65536].End(xlUp)).Resize(, 2)
Câu 2
kết quả ở ô cuối cột AF luôn hiện giá trị #N/A.
Bạn khai báo:
For i = 1 To UBound(sArray, 1)
Trong code bạn sử dụng vòng lặp For.....Next ==> khi chạy hết vòng lặp biến i luôn luôn lớn hơn UBound(sArray, 1) một bước nhảy (ở code này là 1)
.Range("AF6").Resize(i, 1).Value = arr
Số phần tử gán cho vùng từ [AF6] trở xuống i dòng, nhiều hơn số phần tử của mảng Arr là 1 nên cell cuối cùng báo lỗi:
Bạn khai báo lại:
.Range("AF6").Resize(UBound(sArray)).Value = Arr
Hoặc trong khai báo của bạn thì thế này cũng được
.Range("AF6").Resize(i-1, 1).Value = arr
Thân
 
Upvote 0
Web KT

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

Back
Top Bottom