xin code VBA thay cho hàm countifs và sumifs (1 người xem)

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

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

Erebus

Thành viên mới
Tham gia
30/10/16
Bài viết
41
Được thích
6
Chào các bác,
Em đang có một bài toán về đếm và tính tổng với điều kiện lớn hơn và nhỏ hơn ngày chỉ định trong chuỗi ngày.
Em có thể dùng hàm countifs và sumifs, tuy nhiên muốn nhờ các bác giúp cho 1 code VBA ạ.
Thông tin cụ thể như tệp đính kèm.
Các bác giúp em với nhé.
Em cảm ơn ạ
 

File đính kèm

PHP:
Option Explicit
Sub dem()
Dim lr&, i&, dem1&, dem2&, dem3&, rng, arr(1 To 2, 1 To 3)
Dim cong1 As Double, cong2  As Double, cong3  As Double, ngay As Double
ngay = DateValue("2022/05/25")
With Worksheets("Sheet1")
    lr = .Cells(Rows.Count, "A").End(xlUp).Row
    rng = .Range("A2:C" & lr).Value2
    For i = 1 To lr - 1
        If rng(i, 1) < ngay Then
            dem1 = dem1 + 1: cong1 = cong1 + rng(i, 3)
            arr(1, 1) = dem1
            arr(2, 1) = cong1
        ElseIf rng(i, 1) = ngay Then
            dem2 = dem2 + 1: cong2 = cong2 + rng(i, 3)
            arr(1, 2) = dem2
            arr(2, 2) = cong2
        Else
            dem3 = dem3 + 1: cong3 = cong3 + rng(i, 3)
            arr(1, 3) = dem3
            arr(2, 3) = cong3
        End If
    Next
End With
Worksheets("Sheet2").Range("B3").Resize(2, 3).Value = arr
End Sub
 

File đính kèm

Upvote 0
PHP:
Option Explicit
Sub dem()
Dim lr&, i&, dem1&, dem2&, dem3&, rng, arr(1 To 2, 1 To 3)
Dim cong1 As Double, cong2  As Double, cong3  As Double, ngay As Double
ngay = DateValue("2022/05/25")
With Worksheets("Sheet1")
    lr = .Cells(Rows.Count, "A").End(xlUp).Row
    rng = .Range("A2:C" & lr).Value2
    For i = 1 To lr - 1
        If rng(i, 1) < ngay Then
            dem1 = dem1 + 1: cong1 = cong1 + rng(i, 3)
            arr(1, 1) = dem1
            arr(2, 1) = cong1
        ElseIf rng(i, 1) = ngay Then
            dem2 = dem2 + 1: cong2 = cong2 + rng(i, 3)
            arr(1, 2) = dem2
            arr(2, 2) = cong2
        Else
            dem3 = dem3 + 1: cong3 = cong3 + rng(i, 3)
            arr(1, 3) = dem3
            arr(2, 3) = cong3
        End If
    Next
End With
Worksheets("Sheet2").Range("B3").Resize(2, 3).Value = arr
End Sub
Em cảm ơn bác ạ
 
Upvote 0
PHP:
Option Explicit
Sub dem()
Dim lr&, i&, dem1&, dem2&, dem3&, rng, arr(1 To 2, 1 To 3)
Dim cong1 As Double, cong2  As Double, cong3  As Double, ngay As Double
ngay = DateValue("2022/05/25")
With Worksheets("Sheet1")
    lr = .Cells(Rows.Count, "A").End(xlUp).Row
    rng = .Range("A2:C" & lr).Value2
    For i = 1 To lr - 1
        If rng(i, 1) < ngay Then
            dem1 = dem1 + 1: cong1 = cong1 + rng(i, 3)
            arr(1, 1) = dem1
            arr(2, 1) = cong1
        ElseIf rng(i, 1) = ngay Then
            dem2 = dem2 + 1: cong2 = cong2 + rng(i, 3)
            arr(1, 2) = dem2
            arr(2, 2) = cong2
        Else
            dem3 = dem3 + 1: cong3 = cong3 + rng(i, 3)
            arr(1, 3) = dem3
            arr(2, 3) = cong3
        End If
    Next
End With
Worksheets("Sheet2").Range("B3").Resize(2, 3).Value = arr
End Sub
Bác cho em hỏi thêm chút là nếu dùng WorksheetFunction.CountIfs/Sumifs thì có thể tính được không ạ?
 
Upvote 0
Bác cho em hỏi thêm chút là nếu dùng WorksheetFunction.CountIfs/Sumifs thì có thể tính được không ạ?
Câu trả lời là được.
Nhưng nếu cần code VBA để dán công thức vào thì chẳng thà dùng công thức trên sheet luôn cho nhanh.
 
Upvote 0
Câu trả lời là được.
Nhưng nếu cần code VBA để dán công thức vào thì chẳng thà dùng công thức trên sheet luôn cho nhanh.
vâng e hiểu, chỉ là em đang muốn học từ những cái đơn giản và dễ hiểu trước. Bác viết giúp em code bằng WorksheetFunction.CountIfs/Sumifs với ạ
 
Upvote 0
vâng e hiểu, chỉ là em đang muốn học từ những cái đơn giản và dễ hiểu trước. Bác viết giúp em code bằng WorksheetFunction.CountIfs/Sumifs với ạ
Theo yêu cầu. Dùng SumIf, CountIf là đủ. Tôi dùng Application.SumIf, bạn có thể dùng Application.WorksheetFunction.SumIf
Mã:
Sub dem_va_tong()
Dim lastRow As Long, ketqua(1 To 2, 1 To 3), ngay As Double
    ngay = DateValue("5/25")
    With ThisWorkbook.Worksheets("Sheet1")
        lastRow = .Cells(Rows.Count, "A").End(xlUp).Row
        If lastRow < 2 Then Exit Sub
        ketqua(1, 1) = Application.CountIf(.Range("A2:A" & lastRow), "<" & ngay)
        ketqua(1, 2) = Application.CountIf(.Range("A2:A" & lastRow), "=" & ngay)
        ketqua(1, 3) = Application.CountIf(.Range("A2:A" & lastRow), ">" & ngay)
        ketqua(2, 1) = Application.SumIf(.Range("A2:A" & lastRow), "<" & ngay, .Range("C2:C" & lastRow))
        ketqua(2, 2) = Application.SumIf(.Range("A2:A" & lastRow), "=" & ngay, .Range("C2:C" & lastRow))
        ketqua(2, 3) = Application.SumIf(.Range("A2:A" & lastRow), ">" & ngay, .Range("C2:C" & lastRow))
    End With
    ThisWorkbook.Worksheets("Sheet2").Range("B3").Resize(2, 3).Value = ketqua
End Sub
 
Upvote 0
Theo yêu cầu. Dùng SumIf, CountIf là đủ. Tôi dùng Application.SumIf, bạn có thể dùng Application.WorksheetFunction.SumIf
Mã:
Sub dem_va_tong()
Dim lastRow As Long, ketqua(1 To 2, 1 To 3), ngay As Double
    ngay = DateValue("5/25")
    With ThisWorkbook.Worksheets("Sheet1")
        lastRow = .Cells(Rows.Count, "A").End(xlUp).Row
        If lastRow < 2 Then Exit Sub
        ketqua(1, 1) = Application.CountIf(.Range("A2:A" & lastRow), "<" & ngay)
        ketqua(1, 2) = Application.CountIf(.Range("A2:A" & lastRow), "=" & ngay)
        ketqua(1, 3) = Application.CountIf(.Range("A2:A" & lastRow), ">" & ngay)
        ketqua(2, 1) = Application.SumIf(.Range("A2:A" & lastRow), "<" & ngay, .Range("C2:C" & lastRow))
        ketqua(2, 2) = Application.SumIf(.Range("A2:A" & lastRow), "=" & ngay, .Range("C2:C" & lastRow))
        ketqua(2, 3) = Application.SumIf(.Range("A2:A" & lastRow), ">" & ngay, .Range("C2:C" & lastRow))
    End With
    ThisWorkbook.Worksheets("Sheet2").Range("B3").Resize(2, 3).Value = ketqua
End Sub
Em cảm ơn bác nhiều ạ
 
Upvote 0
Mình cũng đang có bài toán về countif, nhưng do số lượng cần làm quá lớn, hơn 1tr3 dòng. Nên khi dùng hàm countif thì excel gần như ko tính nổi. Chỉ đơn giản là tính số lượng bị trùng thôi, nhưng nếu không dùng countif thì có cách nào khác nhanh hơn ko? Thường thì tính toán nhiều nên đưa vào mảng VBA sẽ nhanh hơn, nhưng dùng countif thì không sử dụng trong mảng được.
File lớn quá nên không up lên được.
2 cột đầu là dữ liệu gốc, giờ em cần đếm cột C xem có bao nhiêu lượt xuất hiện trong cả 2 cột A và B.
 
Lần chỉnh sửa cuối:
Upvote 0
Mình cũng đang có bài toán về countif, nhưng do số lượng cần làm quá lớn, hơn 1tr3 dòng. Nên khi dùng hàm countif thì excel gần như ko tính nổi. Chỉ đơn giản là tính số lượng bị trùng thôi, nhưng nếu không dùng countif thì có cách nào khác nhanh hơn ko? Thường thì tính toán nhiều nên đưa vào mảng VBA sẽ nhanh hơn, nhưng dùng countif thì không sử dụng trong mảng được.
File lớn quá nên không up lên được.
2 cột đầu là dữ liệu gốc, giờ em cần đếm cột C xem có bao nhiêu lượt xuất hiện trong cả 2 cột A và B.
Thử chạy code rùa bò này xem sao. Không có dữ liệu nên không test được.
Mã:
Option Explicit
Sub THU()
Dim i&, j&, Lr&, R&, t&, Dic As Object, Key, Temp
Dim Arr(), Res(), Rng As Range
With Sheet1
Set Rng = .[A2].CurrentRegion
Lr = Rng.Rows.Count
Arr = Rng.Value
ReDim KQ(1 To UBound(Arr), 1 To 1)
Set Dic = CreateObject("Scripting.Dictionary")
For i = 2 To UBound(Arr)
    If Arr(i, 3) <> Empty Then
         Key = Arr(i, 3)
        If Not Dic.Exists(Key) Then t = t + 1: Dic.Add (Key), t
        Else: Exit For
    End If
Next i
For j = 1 To 2
For i = 2 To UBound(Arr)
If Arr(i, j) <> Empty Then
    Temp = Arr(i, j)
    If Dic.Exists(Temp) Then
        R = Dic.Item(Temp)
        KQ(R, 1) = KQ(R, 1) + 1
    End If
Else: Exit For
End If
Next i
Next j
.[D2].Resize(t, 1) = KQ
End With
Set Dic = Nothing
End Sub
 
Lần chỉnh sửa cuối:
Upvote 0
Thử chạy code rùa bò này xem sao. Không có dữ liệu nên không test được.
...
Có dữ liệu thật thì nhắm code bạn chạy nổi hôn? Sheet này chứa đến trên 1,3 triệu dòng lận.

Trừ phi tôi nhầm. Thớt nói 1tr3 dòng [sic] có nghĩa là 1.000.003
.
 
Lần chỉnh sửa cuối:
Upvote 0
Mình cũng đang có bài toán về countif, nhưng do số lượng cần làm quá lớn, hơn 1tr3 dòng. Nên khi dùng hàm countif thì excel gần như ko tính nổi. Chỉ đơn giản là tính số lượng bị trùng thôi, nhưng nếu không dùng countif thì có cách nào khác nhanh hơn ko? Thường thì tính toán nhiều nên đưa vào mảng VBA sẽ nhanh hơn, nhưng dùng countif thì không sử dụng trong mảng được.
File lớn quá nên không up lên được.
2 cột đầu là dữ liệu gốc, giờ em cần đếm cột C xem có bao nhiêu lượt xuất hiện trong cả 2 cột A và B.
Excel bản nào mà số dòng nhiều thế nhỉ?

Mình dùng bản 365 chỉ có 2^20 = 1,048,576 dòng.
 
Upvote 0
Có dữ liệu thật thì nhắm code bạn chạy nổi hôn? Sheet này chứa đến trên 1,3 triệu dòng lận.

Trừ phi tôi nhầm. Thớt nói 1tr3 dòng [sic] có nghĩa là 1.000.003
.
Cảm ơn Anh đã xem bài. Tôi đã nói là code rùa bò mà. Code đưa nên chủ yếu để hy vọng có được sự góp ý về thuật toán của các thành viên có kiến thức uyen thâm (tích lũy kiến thức cho bản thân - hoặc cho bạn đọc nào quan tâm) mà thôi, chứ cũng không có ý gì khác.
Bài này nếu đổi lại đề là "Thống kê số lần xuất hiện của các số ( nằm trong 1 cột) với các số nằm trong nhiều chục, trăm, nghìn cột và mỗi cột chứa nhiều nghìn dòng (chục, trăm nghìn dòng< 1.048.576 dòng) " thì code trên có lẽ cũng vẫn test được, code vẫn chạy nhưng sẽ phải rất lâu mới cho ra kết quả.
 
Upvote 0
Cảm ơn Anh đã xem bài. Tôi đã nói là code rùa bò mà. Code đưa nên chủ yếu để hy vọng có được sự góp ý về thuật toán của các thành viên có kiến thức uyen thâm (tích lũy kiến thức cho bản thân - hoặc cho bạn đọc nào quan tâm) mà thôi, chứ cũng không có ý gì khác.
Bài này nếu đổi lại đề là "Thống kê số lần xuất hiện của các số ( nằm trong 1 cột) với các số nằm trong nhiều chục, trăm, nghìn cột và mỗi cột chứa nhiều nghìn dòng (chục, trăm nghìn dòng< 1.048.576 dòng) " thì code trên có lẽ cũng vẫn test được, code vẫn chạy nhưng sẽ phải rất lâu mới cho ra kết quả.
Đùa bạn chơi cho vui thôi.
Ý mình chỉ nói về cái thói quen phóng đại của mấy người hỏi bài.
 
Upvote 0
Khi mới biết power query thì sẽ làm được không bác?
Hỏi như vậy là không làm được gì cả.
Đầu tiên hết là phải biết:
- Power Query chỉ là một cách lọc dữ liệu và đưa vào Data Model.
- Nếu dữ liệu chứa trong Data Model thì nó sẽ làm được nhiều việc. Hầu hết các truy vấn trong Data Model được làm qua cỗ máy SQL Server Express cho nên nó rất hiệu quả, và có khả năng "cầm cương" được dữ liệu khủng. Triệu dòng là chuyện bình thường với nó.
- Dữ liệu chứa trong Data Model có thể được xào nấu bằng các hàm DAX. Các hàm này rất mạnh.

Google Sheets sỡ dĩ được bà con ca tụng là nhờ sanh sau đẻ muộn. Không phải hỗ trợ các phiên bản cũ cho nên tự nó đưa thẳng dữ liệu vào cái tương tự như Data Model (gú-gồ giữ kín, không hé răng cho biết nó là cái gì)
 
Upvote 0
Đùa bạn chơi cho vui thôi.
Ý mình chỉ nói về cái thói quen phóng đại của mấy người hỏi bài.
Mình không hề phóng đại, lý do là excel ko đủ sức chứa 1tr3 dòng, nên mình phải cắt thành 2 cột. Hài. Có thể mình trình bày hơi khó hiểu, nhưng xem file thì cũng đoán được.
 
Upvote 0
Mình không hề phóng đại, lý do là excel ko đủ sức chứa 1tr3 dòng, nên mình phải cắt thành 2 cột. Hài. Có thể mình trình bày hơi khó hiểu, nhưng xem file thì cũng đoán được.

Bạn lập cái topic mới.
Dữ liệu nhiều thì có thể chia ra nhiều files hoặc nhiều sheets (tốt nhất là nhiều file cùng cấu trúc).
Dùng Power Query xử lý được.
 
Upvote 0
Mình không hề phóng đại, lý do là excel ko đủ sức chứa 1tr3 dòng, nên mình phải cắt thành 2 cột. Hài. Có thể mình trình bày hơi khó hiểu, nhưng xem file thì cũng đoán được.
Tập tin chỉ là cái cần thêm. Mọi mô tả, giải thích phải có ngay trong bài viết. Taị sao? Vì người ta trước tiên phải đọc bài viết, thấy chủ đề thú vị và mình có thể giúp được thì mới tải tập tin về. Chả ai bỏ công ra tải tập tin về khi biết là mình không quan tâm hoặc khả năng không giúp được. Nhiệm vụ của bạn là phải trình bày dễ hiểu, và trình bày ngay trong bài viết. Nhiều người vô lý tới mức: "Em không biết diễn tả thế nào, anh chị xem file giúp em với.". Không biết nói cho người khác hiểu thì họ giúp bằng cách nào đây.

Nói: "Em có 1,3 triệu dữ liệu nên phải chia thành 2 cột (nhiều cột)" có khó hơn đâu mà bạn không nói như thế?

Bài #11 đã đưa ra giải pháp. Lờ bài đó đi thì trong tương lai ai còn muốn giúp bạn? Ít ra nếu chưa đúng yêu cầu thì nên nói vài lời để người ta biết mình có đọc. Còn nếu họ đã giúp hiệu quả thì nên nói lời cảm ơn.
 
Upvote 0
Mình không hề phóng đại, lý do là excel ko đủ sức chứa 1tr3 dòng, nên mình phải cắt thành 2 cột. Hài. Có thể mình trình bày hơi khó hiểu, nhưng xem file thì cũng đoán được.
Bạn hiểu thế nào dòng trong Excel?
Bạn đã thử code ỏ bài#11 và bài giải thích của tôi ở bài #15 chưa? Bạn có thể sửa code (for j= 1 to 2 thành For j=1 to nhiều cột )
Dữ liệu nhiều thì chạy hết nhiều thời gian xử lý, dữ liệu ít thì sẽ cho kết quả ngay.
 
Upvote 0
Tập tin chỉ là cái cần thêm. Mọi mô tả, giải thích phải có ngay trong bài viết. Taị sao? Vì người ta trước tiên phải đọc bài viết, thấy chủ đề thú vị và mình có thể giúp được thì mới tải tập tin về. Chả ai bỏ công ra tải tập tin về khi biết là mình không quan tâm hoặc khả năng không giúp được. Nhiệm vụ của bạn là phải trình bày dễ hiểu, và trình bày ngay trong bài viết. Nhiều người vô lý tới mức: "Em không biết diễn tả thế nào, anh chị xem file giúp em với.". Không biết nói cho người khác hiểu thì họ giúp bằng cách nào đây.

Nói: "Em có 1,3 triệu dữ liệu nên phải chia thành 2 cột (nhiều cột)" có khó hơn đâu mà bạn không nói như thế?

Bài #11 đã đưa ra giải pháp. Lờ bài đó đi thì trong tương lai ai còn muốn giúp bạn? Ít ra nếu chưa đúng yêu cầu thì nên nói vài lời để người ta biết mình có đọc. Còn nếu họ đã giúp hiệu quả thì nên nói lời cảm ơn.
Em hiểu là cần phải trình bày, và em có ghi là "2 cột đầu là dữ liệu gốc, giờ em cần đếm cột C xem có bao nhiêu lượt xuất hiện trong cả 2 cột A và B." . Em chỉ muốn tìm cách làm nhanh hơn với dữ liệu lớn nên đưa ra bài toán đó để hỏi mọi người xem có cách nào tốc độ nhanh nhất thôi.
Bài đã được tự động gộp:

Bạn hiểu thế nào dòng trong Excel?
Bạn đã thử code ỏ bài#11 và bài giải thích của tôi ở bài #15 chưa? Bạn có thể sửa code (for j= 1 to 2 thành For j=1 to nhiều cột )
Dữ liệu nhiều thì chạy hết nhiều thời gian xử lý, dữ liệu ít thì sẽ cho kết quả ngay.
Em cám ơn rất nhiều ạ, code chạy rất tốt.
 
Lần chỉnh sửa cuối:
Upvote 0
Em hiểu là cần phải trình bày, và em có ghi là "2 cột đầu là dữ liệu gốc, giờ em cần đếm cột C xem có bao nhiêu lượt xuất hiện trong cả 2 cột A và B." .
Tôi rất khó tính và thường tôi bắt phải mô tả cụ thể để người khác hiểu. Nhưng tôi không phải là người đeo bám từng câu từ. Con người nhiều khi viết sai do vô ý, do kém hiểu biết, do cẩu thả. Tôi không tủn mủn đến mức đôi co về sự vô lý khi mà trong thực tế không thể có sự vô lý đó. Vì chả ai có phiên bản Excel với 1,3 triệu dòng. Vậy người viết có thể nhầm về con số hoặc không nói rõ mà thôi. Tuy nhiên tôi ý thức cho bạn việc mô tả chính xác là cần thiết. Bởi không phải ai cũng như tôi. Có thể ai đó sẽ đôi co với bạn. Vì thế tốt nhất nên nói rõ, nói chính xác. Chỉ tốt cho bạn mà thôi.

Bạn đã nói về 2 cột? Nếu không tải tập tin về mà tôi cố tình đôi co với bạn thì tôi sẽ bĩu môi: Êêê, 2 cột và mỗi cột 1,3 triệu dòng? Có thể thế không? Có thể quá đi chứ.

Còn nói: "Em có 1,3 triệu dữ liệu nên phải chia thành 2 cột (nhiều cột)" thì chả khó hơn mà người khác không bám vào đâu được. :D
 
Upvote 0
Tôi rất khó tính và thường tôi bắt phải mô tả cụ thể để người khác hiểu. Nhưng tôi không phải là người đeo bám từng câu từ. Con người nhiều khi viết sai do vô ý, do kém hiểu biết, do cẩu thả. Tôi không tủn mủn đến mức đôi co về sự vô lý khi mà trong thực tế không thể có sự vô lý đó. Vì chả ai có phiên bản Excel với 1,3 triệu dòng. Vậy người viết có thể nhầm về con số hoặc không nói rõ mà thôi. Tuy nhiên tôi ý thức cho bạn việc mô tả chính xác là cần thiết. Bởi không phải ai cũng như tôi. Có thể ai đó sẽ đôi co với bạn. Vì thế tốt nhất nên nói rõ, nói chính xác. Chỉ tốt cho bạn mà thôi.

Bạn đã nói về 2 cột? Nếu không tải tập tin về mà tôi cố tình đôi co với bạn thì tôi sẽ bĩu môi: Êêê, 2 cột và mỗi cột 1,3 triệu dòng? Có thể thế không? Có thể quá đi chứ.

Còn nói: "Em có 1,3 triệu dữ liệu nên phải chia thành 2 cột (nhiều cột)" thì chả khó hơn mà người khác không bám vào đâu được. :D
Ok anh, em chấp nhận là mình trình bày chưa đủ ý. Em cũng ko muốn giải thích gì thêm vì cái vụ 1tr3 đó ko phải là cái ý chính em muốn đề cập. Em chỉ muốn hỏi xin cao kiến của các anh xem cách tốt nhất để tính toán dữ liệu lớn như vậy thì dùng hàm, code vba, dùng dictionary hay có thể đếm trong mảng... thì cách làm nào cho tốc độ nhanh nhất.
Như bài trước anh có nói đến Power Query và Data model, em nghĩ có thể đây mới là cách tốt nhất. Cám ơn anh rất nhiều vì những chia sẻ đó. Giờ em sẽ tìm hiểu thêm về Power Query.
 
Upvote 0

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

Back
Top Bottom