Lọc dữ liệu ngày cuối cùng của mỗi tháng bằng VBA

Liên hệ QC

thao nguyen01

Thành viên thường trực
Tham gia
8/12/19
Bài viết
214
Được thích
25
Kính gửi anh/chị,
Em đang bị vướng vấn đề là: E muốn lọc dữ liệu ngày cuối cùng có dữ liệu theo mỗi tháng ạ. E có file data và kết quả mong muốn bên cạnh ạ. E làm hoài vẫn chưa ra ạ. Anh/chị xem giúp e ạ. E cảm ơn ạ.
 

File đính kèm

  • data01.xlsx
    8.7 KB · Đọc: 11
Lỡ có trường hợp cùng tháng khác năm thì làm thế nào tiếp hả bạn?
 
Upvote 0

File đính kèm

  • data01.xlsx
    8.9 KB · Đọc: 7
Upvote 0

File đính kèm

  • data01.xlsx
    12.4 KB · Đọc: 7
Upvote 0
Kính gửi anh/chị,
Em đang bị vướng vấn đề là: E muốn lọc dữ liệu ngày cuối cùng có dữ liệu theo mỗi tháng ạ. E có file data và kết quả mong muốn bên cạnh ạ. E làm hoài vẫn chưa ra ạ. Anh/chị xem giúp e ạ. E cảm ơn ạ.
Ví dụ cùng ngày cuối có 2 hay nhiều dòng dữ liệu thì sao hả bạn?
 
Upvote 0
Ví dụ cùng ngày cuối có 2 hay nhiều dòng dữ liệu thì sao hả bạn?

dạ, thường data đẩy vào theo ngày thường là chốt cuối ngày ạ. Nên e nghĩ hiện tại sẽ k trùng nếu cùng ngày ạ. Nếu sau này có trùng e sẽ thêm cột giờ kế bên cột ngày ạ. Lúc đó nếu cùng ngày, sẽ lấy giờ cuối ạ.
 
Upvote 0
dạ, thường data đẩy vào theo ngày thường là chốt cuối ngày ạ. Nên e nghĩ hiện tại sẽ k trùng nếu cùng ngày ạ. Nếu sau này có trùng e sẽ thêm cột giờ kế bên cột ngày ạ. Lúc đó nếu cùng ngày, sẽ lấy giờ cuối ạ.
Bạn chạy thử code sau nhé:

Mã:
Sub LayDL_HLMT()
    With CreateObject("ADODB.Connection")
        .Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & ThisWorkbook.FullName & ";Extended Properties=Excel 12.0"
        Sheet1.Range("J3").CopyFromRecordset .Execute("SELECT  a.*  FROM [Sheet1$A1:E60] as a INNER JOIN (SELECT Max([Ngày]) AS MaxNgay FROM [Sheet1$A1:E60] GROUP BY Month([Ngày]), Year([Ngày])) b ON a.Ngày = b.MaxNgay")
    End With
End Sub
 
Upvote 0
Bạn chạy thử code sau nhé:

Mã:
Sub LayDL_HLMT()
    With CreateObject("ADODB.Connection")
        .Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & ThisWorkbook.FullName & ";Extended Properties=Excel 12.0"
        Sheet1.Range("J3").CopyFromRecordset .Execute("SELECT  a.*  FROM [Sheet1$A1:E60] as a INNER JOIN (SELECT Max([Ngày]) AS MaxNgay FROM [Sheet1$A1:E60] GROUP BY Month([Ngày]), Year([Ngày])) b ON a.Ngày = b.MaxNgay")
    End With
End Sub
Anh ơi bạn đó cần là code VBA mà anh.Đây em thấy nó liên quan đến SQL à.
 
Upvote 0
Bạn chạy thử code sau nhé:

Mã:
Sub LayDL_HLMT()
    With CreateObject("ADODB.Connection")
        .Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & ThisWorkbook.FullName & ";Extended Properties=Excel 12.0"
        Sheet1.Range("J3").CopyFromRecordset .Execute("SELECT  a.*  FROM [Sheet1$A1:E60] as a INNER JOIN (SELECT Max([Ngày]) AS MaxNgay FROM [Sheet1$A1:E60] GROUP BY Month([Ngày]), Year([Ngày])) b ON a.Ngày = b.MaxNgay")
    End With
End Sub
Bạn chạy thử code sau nhé:
Dạ, Thầy @Hai Lúa Miền Tây hướng dẫn giúp e SELECT a.* FROM, e chưa hiểu a.* ạ? E cảm ơn Thầy nhiều ạ
 
Chỉnh sửa lần cuối bởi điều hành viên:
Upvote 0
Bạn thử dùng Pivottabe coi có ổn không
Pivot là đồ của Excel, lỗi thời rồi.

Theo quan niệm của GPE, Excel là bảng tính mở rộng (spreadsheet). Sử dụng công cụ có sẵn của Excel là bó buộc mình trong điều lệ của bảng tính.

Phát sần mới của GPE là dùng VBA.
Tất cả công việc được đưa vào VBA. Các sheets của workbook chỉ là nơi chứa dữ liệu đầu vào và các kiều cách đầu ra.
 
Upvote 0
Dạ. E cảm ơn Thầy ạ.
Dạ. Thầy @Hai Lúa Miền Tây cho e hỏi select a.*from lấy từ sql chỗ nào ạ. Và ý nghĩa nó là gì ạ. E có tìm trên mạng nhưng e k thấy chỉ cách sử dụng ạ. Lúc nào e cũng để select a.*from đúng k ạ? Thầy hướng dẫn e với ạ. E nên tìm tài liệu ở đâu ạ. Code của Thầy e đọc chỉ k hiểu chỗ đó ạ. E cảm ơn Thầy.
 
Lần chỉnh sửa cuối:
Upvote 0
Dạ. E cảm ơn Thầy ạ.
Dạ. Thầy @Hai Lúa Miền Tây cho e hỏi select a.*from lấy từ sql chỗ nào ạ. Và ý nghĩa nó là gì ạ. E có tìm trên mạng nhưng e k thấy chỉ cách sử dụng ạ. Lúc nào e cũng để select a.*from đúng k ạ? Thầy hướng dẫn e với ạ. E nên tìm tài liệu ở đâu ạ. Code của Thầy e đọc chỉ k hiểu chỗ đó ạ. E cảm ơn Thầy.
Rich (BB code):
SELECT a.*
FROM   [Sheet1$A1:E60] a
       INNER JOIN (SELECT Max([Ngày]) AS MaxNgay
                   FROM   [Sheet1$A1:E60]
                   GROUP  BY Month([Ngày]),
                             Year([Ngày])) b
               ON a.[Ngày] = b.MaxNgay

a là đặt tên lại cho bảng dữ liệu [Sheet1$A1:E60]. a.* là lấy tất cả các cột dữ liệu của bảng a, tức là [Sheet1$A1:E60]. Tương tự b thì bạn từ từ nghiệm ra nhé.
 
Upvote 0
Rich (BB code):
SELECT a.*
FROM   [Sheet1$A1:E60] a
       INNER JOIN (SELECT Max([Ngày]) AS MaxNgay
                   FROM   [Sheet1$A1:E60]
                   GROUP  BY Month([Ngày]),
                             Year([Ngày])) b
               ON a.[Ngày] = b.MaxNgay

a là đặt tên lại cho bảng dữ liệu [Sheet1$A1:E60]. a.* là lấy tất cả các cột dữ liệu của bảng a, tức là [Sheet1$A1:E60]. Tương tự b thì bạn từ từ nghiệm ra nhé.

Dạ, e hiểu rồi ạ. E cảm ơn Thầy @Hai Lúa Miền Tây nhiều ạ.
 
Upvote 0
Nó nằm ở cái ngữ pháp (syntax) lệnh Select và mệnh đề From
From Bảng As tên_đặt
Bảng
là tên thật của bảng. tên_đặt là tên mình đặt lại để sử dụng (trong phạm vi lệnh Select). Từ khoá As là nhiệm ý, tức là có thì dễ trông nhưng không có thì trình dịch SQL cũng tự hiểu.
Có nhiều lý do để đặt lại tên. Phần lớn các trường hợp là do cần thu ngắn tên quá dài, và các trường hợp bị trùng tên.
 
Upvote 0
Dạ, nếu trùng tháng nhưng khác năm thì sẽ lấy theo năm và lấy tháng tương ứng ạ. E đính kèm file ạ. Anh xem giúp e ạ. E cảm ơn ạ
Bạn thử.
Mã:
Sub laydulieu()
    Dim arr, i As Long, a As Long, dk As String, dic As Object, kq, b As Long, c
    Set dic = CreateObject("scripting.dictionary")
    With Sheets("sheet1")
         arr = .Range("A2:E9").Value
         ReDim kq(1 To UBound(arr), 1 To 5)
         For i = 1 To UBound(arr)
             dk = Month(arr(i, 1)) & "#" & Year(arr(i, 1))
             If Not dic.exists(dk) Then
                a = a + 1
                dic.Add dk, a
                kq(a, 1) = arr(i, 1)
                kq(a, 2) = arr(i, 2)
                kq(a, 3) = arr(i, 3)
                kq(a, 4) = arr(i, 4)
                kq(a, 5) = arr(i, 5)
             Else
                b = dic.Item(dk)
                If Day(kq(b, 1)) < Day(arr(i, 1)) Then
                    kq(b, 1) = arr(i, 1)
                    kq(b, 2) = arr(i, 2)
                    kq(b, 3) = arr(i, 3)
                    kq(b, 4) = arr(i, 4)
                    kq(b, 5) = arr(i, 5)
                End If
            End If
       Next i
       .Range("o3").Resize(a, 5).Value = kq
  End With
End Sub
 
Upvote 0
Nó nằm ở cái ngữ pháp (syntax) lệnh Select và mệnh đề From
From Bảng As tên_đặt
Bảng
là tên thật của bảng. tên_đặt là tên mình đặt lại để sử dụng (trong phạm vi lệnh Select). Từ khoá As là nhiệm ý, tức là có thì dễ trông nhưng không có thì trình dịch SQL cũng tự hiểu.
Có nhiều lý do để đặt lại tên. Phần lớn các trường hợp là do cần thu ngắn tên quá dài, và các trường hợp bị trùng tên.
Dạ, e cảm ơn anh nhiều ạ.
Bài đã được tự động gộp:

Bạn thử.
Mã:
Sub laydulieu()
    Dim arr, i As Long, a As Long, dk As String, dic As Object, kq, b As Long, c
    Set dic = CreateObject("scripting.dictionary")
    With Sheets("sheet1")
         arr = .Range("A2:E9").Value
         ReDim kq(1 To UBound(arr), 1 To 5)
         For i = 1 To UBound(arr)
             dk = Month(arr(i, 1)) & "#" & Year(arr(i, 1))
             If Not dic.exists(dk) Then
                a = a + 1
                dic.Add dk, a
                kq(a, 1) = arr(i, 1)
                kq(a, 2) = arr(i, 2)
                kq(a, 3) = arr(i, 3)
                kq(a, 4) = arr(i, 4)
                kq(a, 5) = arr(i, 5)
             Else
                b = dic.Item(dk)
                If Day(kq(b, 1)) < Day(arr(i, 1)) Then
                    kq(b, 1) = arr(i, 1)
                    kq(b, 2) = arr(i, 2)
                    kq(b, 3) = arr(i, 3)
                    kq(b, 4) = arr(i, 4)
                    kq(b, 5) = arr(i, 5)
                End If
            End If
       Next i
       .Range("o3").Resize(a, 5).Value = kq
  End With
End Sub

Dạ, e cảm ơn anh @snow25 nhiều lắm ạ. Hôm qua e nghĩ chưa ra cách này. E cảm ơn anh ạ. Hi
 
Upvote 0
Web KT
Back
Top Bottom