Vba thay thế hàm Countifs. (1 người xem)

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

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

kh0jy3n

Thành viên thường trực
Tham gia
21/4/12
Bài viết
345
Được thích
115
Gửi các Bác.
Hiện tại em đang làm một file báo biểu dùng rất nhiều tới hàm Countifs , tới tầm 60.000 dong làm file chạy chậm quá.
về khoản Vba em ngủ quá :(.
bác nào rảnh viết hộ em xin code hàm countifs em có để Vd ở file đính kèm ạ.

Em cảm ơn !
 

File đính kèm

Gửi các Bác.
Hiện tại em đang làm một file báo biểu dùng rất nhiều tới hàm Countifs , tới tầm 60.000 dong làm file chạy chậm quá.
về khoản Vba em ngủ quá :(.
bác nào rảnh viết hộ em xin code hàm countifs em có để Vd ở file đính kèm ạ.

Em cảm ơn !
Dùng dictionary là được
 
Upvote 0
Gửi các Bác.
Hiện tại em đang làm một file báo biểu dùng rất nhiều tới hàm Countifs , tới tầm 60.000 dong làm file chạy chậm quá.
về khoản Vba em ngủ quá :(.
bác nào rảnh viết hộ em xin code hàm countifs em có để Vd ở file đính kèm ạ.

Em cảm ơn !
Bạn xem code nhé.Mà sao mình thấy khác kết quả nhỉ.Hay là mình không hiểu câu hỏi.
Mã:
Sub dem()
Dim i As Long, j As Long, lr As Long, arr, arr1, dic As Object, lr1 As Long, b As Long, c As Long
Set dic = CreateObject("scripting.dictionary")
With Sheets("TONG HOP")
     lr = .Range("B" & Rows.Count).End(xlUp).Row
     If lr < 4 Then Exit Sub
     .Range("C4:h" & lr).ClearContents
     arr = .Range("B3:H" & lr).Value
     For i = 2 To UBound(arr, 1)
         dic.Add arr(i, 1), i
     Next i
     For i = 2 To UBound(arr, 2)
         dic.Add arr(1, i), i
     Next i
End With
With Sheets("DANH SACH")
     lr1 = .Range("C" & Rows.Count).End(xlUp).Row
     arr1 = .Range("c3:e" & lr1).Value
     For i = 1 To UBound(arr1, 1)
         b = dic.Item(arr1(i, 1))
         If b Then
            For j = 2 To 3
                 c = dic.Item(arr1(i, j))
                 If c Then
                    arr(b, c) = arr(b, c) + 1
                 End If
            Next j
         End If
      Next i
End With
With Sheets("TONG HOP")
     .Range("B3:H" & lr).Value = arr
End With
End Sub
Bài đã được tự động gộp:

Sao bài của bạn nhiều vòng lặp lồng nhau vậy.Có tới 3 cái.Nếu dữ liệu là 60 nghìn dòng thì nó có tận.60000*6000*6 phép tính.:D
 
Lần chỉnh sửa cuối:
Upvote 0
Cũng chưa cần đến Dictionary:
PHP:
Sub Array_()
 Dim Rws As Long, J As Long, W As Integer:          Dim Arr()
 
 Arr() = Sheets("Danh Sach").[B3].CurrentRegion.Offset(1, 1).Value
 ReDim dArr(1 To 5, 1 To 7)
 For J = 1 To UBound(Arr())
    If Arr(J, 1) = "" Then Exit For
    W = Right(Arr(J, 2), 1)
    dArr(W, 1) = Arr(J, 2)
    If Arr(J, 3) = "NAM" Then
        dArr(W, 2) = dArr(W, 2) + 1
    Else
        dArr(W, 3) = dArr(W, 3) + 1
    End If
    If Len(Arr(J, 4)) > 5 And Not IsNumeric(Arr(J, 4)) Then
        dArr(W, 6) = dArr(W, 6) + 1
    ElseIf Len(Arr(J, 4)) < 3 Then
        dArr(W, 7) = dArr(W, 7) + 1
    Else
        If Hour(Arr(J, 4)) >= 18 Then
            dArr(W, 5) = dArr(W, 5) + 1
        Else
            dArr(W, 4) = dArr(W, 4) + 1
        End If
    End If
 Next J
 Sheets("Tong Hop").[b4].Resize(5, 7).Value = dArr()
End Sub
 
Upvote 0
Cũng chưa cần đến Dictionary:
PHP:
Sub Array_()
Dim Rws As Long, J As Long, W As Integer:          Dim Arr()

Arr() = Sheets("Danh Sach").[B3].CurrentRegion.Offset(1, 1).Value
ReDim dArr(1 To 5, 1 To 7)
For J = 1 To UBound(Arr())
    If Arr(J, 1) = "" Then Exit For
    W = Right(Arr(J, 2), 1)
    dArr(W, 1) = Arr(J, 2)
    If Arr(J, 3) = "NAM" Then
        dArr(W, 2) = dArr(W, 2) + 1
    Else
        dArr(W, 3) = dArr(W, 3) + 1
    End If
    If Len(Arr(J, 4)) > 5 And Not IsNumeric(Arr(J, 4)) Then
        dArr(W, 6) = dArr(W, 6) + 1
    ElseIf Len(Arr(J, 4)) < 3 Then
        dArr(W, 7) = dArr(W, 7) + 1
    Else
        If Hour(Arr(J, 4)) >= 18 Then
            dArr(W, 5) = dArr(W, 5) + 1
        Else
            dArr(W, 4) = dArr(W, 4) + 1
        End If
    End If
Next J
Sheets("Tong Hop").[b4].Resize(5, 7).Value = dArr()
End Sub
Em chưa test nhưng mà nếu mà có C11 thì nó có lỗi không nhỉ anh.Mà ví dụ nó không có C2 thì bị cách dòng anh.
 
Lần chỉnh sửa cuối:
Upvote 0
Em chưa test nhưng mà nếu mà có C11 thì nó có lỗi không nhỉ anh.Mà ví dụ nó không có C2 thì bị cách dòng anh.
Người ta làm chỉ cho đúng dữ liệu giả dụ ấy thôi. Nếu có C37, hay không chỉ C, hoặc C1, ..., C5, NK51, BT64 v...v thì tèo.

Viết code nên luôn coi dữ liệu chỉ là giả dụ.
 
Upvote 0
Người ta làm chỉ cho đúng dữ liệu giả dụ ấy thôi. Nếu có C37, hay không chỉ C, hoặc C1, ..., C5, NK51, BT64 v...v thì tèo.

Viết code nên luôn coi dữ liệu chỉ là giả dụ.
Nhưng đôi khi căn cứ vào dữ liệu quy luật thì giúp code thuận hơn - còn sai là do người hỏi hay lười cứ làm giả số liệu kiểu làm đại cho nhanh 1 2 3 hay a b c 1 2 3... không làm dữ liệu giả định tổng quát và gần thực tế
 
Upvote 0
Nhưng đôi khi căn cứ vào dữ liệu quy luật thì giúp code thuận hơn - còn sai là do người hỏi hay lười cứ làm giả số liệu kiểu làm đại cho nhanh 1 2 3 hay a b c 1 2 3... không làm dữ liệu giả định tổng quát và gần thực tế
Tất nhiên nhưng nhìn A1..A9, C1..C5 tôi có cảm giác là dữ liệu giả lập, người hỏi lười soạn dữ liệu. Với dữ liệu kiểu đó tôi luôn cảnh giác, và cho là dữ liệu thực có thể rất khác.
 
Upvote 0
Bạn xem code nhé.Mà sao mình thấy khác kết quả nhỉ.Hay là mình không hiểu câu hỏi.
Mã:
Sub dem()
Dim i As Long, j As Long, lr As Long, arr, arr1, dic As Object, lr1 As Long, b As Long, c As Long
Set dic = CreateObject("scripting.dictionary")
With Sheets("TONG HOP")
     lr = .Range("B" & Rows.Count).End(xlUp).Row
     If lr < 4 Then Exit Sub
     .Range("C4:h" & lr).ClearContents
     arr = .Range("B3:H" & lr).Value
     For i = 2 To UBound(arr, 1)
         dic.Add arr(i, 1), i
     Next i
     For i = 2 To UBound(arr, 2)
         dic.Add arr(1, i), i
     Next i
End With
With Sheets("DANH SACH")
     lr1 = .Range("C" & Rows.Count).End(xlUp).Row
     arr1 = .Range("c3:e" & lr1).Value
     For i = 1 To UBound(arr1, 1)
         b = dic.Item(arr1(i, 1))
         If b Then
            For j = 2 To 3
                 c = dic.Item(arr1(i, j))
                 If c Then
                    arr(b, c) = arr(b, c) + 1
                 End If
            Next j
         End If
      Next i
End With
With Sheets("TONG HOP")
     .Range("B3:H" & lr).Value = arr
End With
End Sub
:D
Kết quả lệch do công thức trong file sai
 
Upvote 0
Sao bài của bạn nhiều vòng lặp lồng nhau vậy.Có tới 3 cái.Nếu dữ liệu là 60 nghìn dòng thì nó có tận.60000*6000*6 phép tính.:D

Hi tại vì mình thấy code của bạn chưa tận dụng được cái item của dic nên nó mới tốn vòng lặp vậy à.
Thời gian xử lý code như nhau, mỗi người 1 cách viết khác nhau thôi, không biết bạn giỏi tới đâu mà tính toán như đúng rồi. Còn đi cười người khác nữa
 
Lần chỉnh sửa cuối:
Upvote 0
Người ta làm chỉ cho đúng dữ liệu giả dụ ấy thôi. Nếu có C37, hay không chỉ C, hoặc C1, ..., C5, NK51, BT64 v...v thì tèo.
Viết code nên luôn coi dữ liệu chỉ là giả dụ.
Tết nhất thêm rảnh rỗi mà!
Dữ liệu thế nào làm thế í cái đã; Nếu DL khác thì chế lại; mấy khi được thêm bài mới.
 
Upvote 0
Thời gian xử lý code như nhau, mỗi người 1 cách viết khác nhau thôi, không biết bạn giỏi tới đâu mà tính toán như đúng rồi. Còn đi cười người khác nữa
Bạn thử dữ liệu với 60000 dòng ở trang dữ liệu và 1000 dòng ở trang kết quả xem thế nào.Mình không cười ai cả mình thấy thế góp ý cho bạn thôi.Nêu bạn không thích thì thôi mình xin lỗi.
 
Upvote 0
Gửi các Bác.
Hiện tại em đang làm một file báo biểu dùng rất nhiều tới hàm Countifs , tới tầm 60.000 dong làm file chạy chậm quá.
về khoản Vba em ngủ quá :(.
bác nào rảnh viết hộ em xin code hàm countifs em có để Vd ở file đính kèm ạ.

Em cảm ơn !
Viết thí thí cho vui.
 

File đính kèm

Upvote 0
Gửi các Bác.
Hiện tại em đang làm một file báo biểu dùng rất nhiều tới hàm Countifs , tới tầm 60.000 dong làm file chạy chậm quá.
về khoản Vba em ngủ quá :(.
bác nào rảnh viết hộ em xin code hàm countifs em có để Vd ở file đính kèm ạ.

Em cảm ơn !
Thêm cách dùng Instr
Theo cách gọi tên cột và dòng trong file
Mã:
Sub GPE()
  Dim i As Long, j As Long, iR As Long, jC As Long
  Dim sArr(), Res(), rowStr As String, colStr As String

  With Sheets("TONG HOP")
    i = .Range("B" & Rows.Count).End(xlUp).Row
    If i < 4 Then Exit Sub
    sArr = .Range("B3:H" & i).Value
  End With
  ReDim Res(1 To UBound(sArr) - 1, 1 To 6)
  rowStr = "##": colStr = "##"
  For i = 2 To UBound(sArr, 1)
    rowStr = rowStr & Right(sArr(i, 1), 2)
  Next i
  For j = 2 To UBound(sArr, 2)
    colStr = colStr & Right(sArr(1, j), 2)
  Next j
  With Sheets("DANH SACH")
    i = .Range("C" & Rows.Count).End(xlUp).Row
    If i < 3 Then Exit Sub
    sArr = .Range("C3:E" & i).Value
  End With
  For i = 1 To UBound(sArr, 1)
    iR = InStr(1, rowStr, Right(sArr(i, 1), 2)) \ 2
    If iR > 0 Then
      For j = 2 To 3
        jC = InStr(1, colStr, Right(sArr(i, j), 2)) \ 2
        If jC > 0 Then Res(iR, jC) = Res(iR, jC) + 1
      Next j
    End If
  Next i
  With Sheets("TONG HOP")
    .Range("C4").Resize(UBound(Res), UBound(Res, 2)) = Res
  End With
End Sub
 
Upvote 0
Thêm cách dùng Instr
Theo cách gọi tên cột và dòng trong file
Mã:
Sub GPE()
  Dim i As Long, j As Long, iR As Long, jC As Long
  Dim sArr(), Res(), rowStr As String, colStr As String

  With Sheets("TONG HOP")
    i = .Range("B" & Rows.Count).End(xlUp).Row
    If i < 4 Then Exit Sub
    sArr = .Range("B3:H" & i).Value
  End With
  ReDim Res(1 To UBound(sArr) - 1, 1 To 6)
  rowStr = "##": colStr = "##"
  For i = 2 To UBound(sArr, 1)
    rowStr = rowStr & Right(sArr(i, 1), 2)
  Next i
  For j = 2 To UBound(sArr, 2)
    colStr = colStr & Right(sArr(1, j), 2)
  Next j
  With Sheets("DANH SACH")
    i = .Range("C" & Rows.Count).End(xlUp).Row
    If i < 3 Then Exit Sub
    sArr = .Range("C3:E" & i).Value
  End With
  For i = 1 To UBound(sArr, 1)
    iR = InStr(1, rowStr, Right(sArr(i, 1), 2)) \ 2
    If iR > 0 Then
      For j = 2 To 3
        jC = InStr(1, colStr, Right(sArr(i, j), 2)) \ 2
        If jC > 0 Then Res(iR, jC) = Res(iR, jC) + 1
      Next j
    End If
  Next i
  With Sheets("TONG HOP")
    .Range("C4").Resize(UBound(Res), UBound(Res, 2)) = Res
  End With
End Sub
Em không hiểu sao lại phải lấy là 2 ký tự hả anh.Nếu có trường hợp 2 ký tự cuối giống nhau thì sao.
 
Upvote 0
@@
Em cảm ơn mọi người nhiều ạ.
Chúc mọi người một ngày tốt lanh ạ .
^^^^

Nhiệt tình đăng cấp là cảm giác đầu tiền em cảm nhận dc từ diễn đàn.
 
Upvote 0
Bạn thử dữ liệu với 60000 dòng ở trang dữ liệu và 1000 dòng ở trang kết quả xem thế nào.Mình không cười ai cả mình thấy thế góp ý cho bạn thôi.Nêu bạn không thích thì thôi mình xin lỗi.
Không cần phải thử gì cả, dữ liệu gì thì máy vẫn phải kiểm tra tới chứ có bỏ qua được đâu, vấn đề là đừng để nó kiểm tra đi kiểm tra lại nhiều lần thôi. Tôi thấy bạn đang cười tôi ở trên đó mà bạn nói không cười
 
Upvote 0
em nhờ các bác trên diễn đàn giúp em
em muốn tổng hợp tồn kho nhập xuất tồn
théo chi nhánh hải hà
theo chi nhanh đầm hà
và tổng công ty
em cảm ơn nhiều
 

File đính kèm

Upvote 0
Trời, cả năm rồi mà còn có ngừoi đào mồ lên, hỏi một câu chẳng ăn nhập gì với chủ đề thớt hết.
Mà người này lại là thành viên từ hơn tám năm về trước mới ác. Khả năng là lười đăng ký nít mới cho nên mượn nít hỏi bài.
 
Upvote 0
Trời, cả năm rồi mà còn có ngừoi đào mồ lên, hỏi một câu chẳng ăn nhập gì với chủ đề thớt hết.
Mà người này lại là thành viên từ hơn tám năm về trước mới ác. Khả năng là lười đăng ký nít mới cho nên mượn nít hỏi bài.
nhập xuất tồn mình đang dùng công thức counifs mà bác.
giờ muốn chuyển thành code vba cho tiện, vì công thức chạy chậm quá
 
Upvote 0
Các bác giúp em với ạ. Em gặp tình trạng giống chủ thớt, nhưng file của em có nhiều cột nên không biết làm thế nào. Do nhiều file hơn 200.000 dòng, mà phải 3 hoặc 4 điều kiện lọc nên dùng Countifs thì máy tính đơ luôn ạ.
Em gởi file cắt bớt còn 50 dòng cho nhẹ. Các điều kiện đếm là 4 cột "hoten, ngaysinh, gioitinh, diachi".
Nhờ các bác giúp đỡ.
 

File đính kèm

Upvote 0
Các bác giúp em với ạ. Em gặp tình trạng giống chủ thớt, nhưng file của em có nhiều cột nên không biết làm thế nào. Do nhiều file hơn 200.000 dòng, mà phải 3 hoặc 4 điều kiện lọc nên dùng Countifs thì máy tính đơ luôn ạ.
Em gởi file cắt bớt còn 50 dòng cho nhẹ. Các điều kiện đếm là 4 cột "hoten, ngaysinh, gioitinh, diachi".
Nhờ các bác giúp đỡ.
Bạn đọc giờ giấc giùm để khỏi mang tiếng là nhà khảo cổ. Với đề của bạn, tôi nghĩ diễn đàn này đã có câu trả lời, bạn chỉ cần dùng chức năng tìm kiếm là thấy. Nếu lười thì bạn đăng thành 1 bài mới, sẽ có người giúp bạn.
 
Upvote 0
Bạn đọc giờ giấc giùm để khỏi mang tiếng là nhà khảo cổ. Với đề của bạn, tôi nghĩ diễn đàn này đã có câu trả lời, bạn chỉ cần dùng chức năng tìm kiếm là thấy. Nếu lười thì bạn đăng thành 1 bài mới, sẽ có người giúp bạn.
Mình nghĩ bài này phù hợp với vấn đề của mình nên mới đăng vào đây chứ không phải lười tạo thread mới. Còn tìm kiếm thì mình không biết phải dùng từ khóa thế nào cho nó phù hợp. Nếu mình phạm quy thì cho mình xin lỗi. Mình sẽ tìm thử.
 
Upvote 0
Mình nghĩ bài này phù hợp với vấn đề của mình nên mới đăng vào đây chứ không phải lười tạo thread mới. Còn tìm kiếm thì mình không biết phải dùng từ khóa thế nào cho nó phù hợp. Nếu mình phạm quy thì cho mình xin lỗi. Mình sẽ tìm thử.
Tôi không trách gì bạn nhưng 1 chủ đề đã bị chê là đào mộ mà mình còn chen vào nhờ thì khó tìm được người giúp.
 
Upvote 0
Trời, cả năm rồi mà còn có ngừoi đào mồ lên, hỏi một câu chẳng ăn nhập gì với chủ đề thớt hết.
Mà người này lại là thành viên từ hơn tám năm về trước mới ác. Khả năng là lười đăng ký nít mới cho nên mượn nít hỏi bài.

Quá đơn giản
Mã:
Public Sub Mazda()
                                                Const C As Long = 200 - 180
Dim sArr(), dArr(), I As Long, K As Long, R As Long, Rws As Long, Col As Long, xCoL As Long, Tmp As Variant
                                                                         sArr = Sheets("DANH SACH").Range("C2", Sheets("DANH SACH").Range("C1000000").End(xlUp)).Resize(, 3).Value
R = UBound(sArr)
                                        ReDim dArr(1 To R, 1 To C)
                                                With CreateObject("Scripting.Dictionary")
    dArr(1, 1) = "STT"
                                                                                                                                   dArr(1, 2) = sArr(1, 1)
                                                    dArr(1, 3) = "NAM"
                                                    
                                                    
                                                    
                                                    
                                                    
                                                    
                                                    
                                                    
                                                    
                                                    
                                                    
                                                    
                                                    
                                                    
                                                    
                                                    
                                                    
                                                    
                                                    
                                                    
                                                    
                                                    
                                                    
                                                    
                                                    
                                                    
                                                    
                                                    
                                                    
                                                    
                                                    
                                                    
                                                    
                                                    
                                                    
                                                    
                                                    
                                                    
                                                    
                                                    
                                                    
                                                     dArr(1, 4) = "NU"
    K = 1: Col = 4
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    For I = 2 To R
    
    
    
    
    
    
    
    
    
    If sArr(I, 1) <> Empty Then
      
          
                Tmp = sArr(I, 1)
                
                
                
                
                
                
                
        If Not .Exists(Tmp) Then
            K = K + 1
                         .Item(Tmp) = K
            dArr(K, 1) = K - 1
            
            
            
            
            
            
            
            
            
            dArr(K, 2) = Tmp
            
            
            
            
            
            
            
            
            
        End If
              
        Tmp = sArr(I, 3)
                                                                            If Not .Exists(Tmp) Then
                          Col = Col + 1
            .Item(Tmp) = Col
            
            
            
            
            
            
            
            
            
            
            
            
            dArr(1, Col) = Tmp
        End If

   Rws = .Item(sArr(I, 1))
  
  
  
  
  
  
  
  
  
  
                                                          If sArr(I, 2) = "NAM" Then
                                                          
                                                          
                                                          
                                                          
                                                          
                                                          
                                                          
                                                          
                                                          
                                                          
                                                          
                                                          
                          dArr(Rws, 3) = dArr(Rws, 3) + 1
                                                  Else
                                         dArr(Rws, 4) = dArr(Rws, 4) + 1
        End If
        

 
        xCoL = .Item(sArr(I, 3))
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
                                                  dArr(Rws, xCoL) = dArr(Rws, xCoL) + 1
    End If
                                                                                                                                                    Next I
End With
                                                                                                                                                                                                With Sheets("TONG HOP")
    .Range("A3").Resize(1000000, C).ClearContents
                                                                                                                                                    .Range("A3").Resize(K, Col) = dArr
End With
End Sub
 
Upvote 0

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

Back
Top Bottom