Gộp dữ liệu từ nhiều vùng ? (2 người xem)

Liên hệ QC

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

TrungChinhs

Thành viên tích cực
Tham gia
18/2/08
Bài viết
1,475
Được thích
2,469
Nghề nghiệp
Công chức
Nhờ các bạn viết giúp code lọc dữ liệu trong file đính kèm. Dữ liệu nguồn bên sheet Du lieu. Kết quả mong muốn như sheet Ket qua.
Thanks !
 

File đính kèm

Anh Nghĩa test cho em Code này nhé. Tks anh!
PHP:
Sub Tonghop()
Dim Arr, sArr
Dim dic As Object
Dim i, k, t As Integer
Arr = Sheet1.Range("C5:F" & Sheet1.[D65000].End(3).Row)
Set dic = CreateObject("Scripting.Dictionary")
ReDim sArr(1 To UBound(Arr, 1), 1 To 4)
' Gan item vao Dic
With dic
For i = 1 To UBound(Arr, 1)
    If Not .exists(Arr(i, 1)) And Arr(i, 1) <> "" Then
        k = k + 1
        .Add Arr(i, 1), k
    ElseIf .exists(Arr(i, 1)) Then
        Arr(i, 2) = 1
    End If
Next
End With
' thay the cot c = " " sang gia tri ben tren
For i = 1 To UBound(Arr, 1)
    If Arr(i, 1) = "" Then
        Arr(i, 1) = Arr(i - 1, 1)
    End If
Next
 ' trich loc
  For Each Item In dic.keys
    For i = 1 To UBound(Arr, 1)
        If Arr(i, 1) = Item And Arr(i, 2) <> 1 Then
            t = t + 1
            sArr(t, 1) = Arr(i, 1)
            sArr(t, 2) = Arr(i, 2)
            sArr(t, 3) = Arr(i, 3)
            sArr(t, 4) = Arr(i, 4)
        End If
    Next
Next
Sheet2.[f4].Resize(UBound(Arr, 1), 4) = sArr
End Sub
 
Upvote 0
Toàn là các ĐẠI CA xuất chiêu hết cả rồi, em làm sao có cơ hội đây?
Ẹc... Ẹc...

Hay tại quả này dễ quá! (nói trúng tim đen luôn)
ndu mà ra tay chắc còn cỡ 10 dòng là xong.
Hic, mà sao code mình đơn giản, dễ điều chỉnh vậy mà không được Nghĩa test nhỉ, "bùn" ghê
 
Upvote 0
Anh Nghĩa test cho em Code này nhé. Tks anh!
PHP:
Sub Tonghop()
Dim Arr, sArr
Dim dic As Object
Dim i, k, t As Integer
Arr = Sheet1.Range("C5:F" & Sheet1.[D65000].End(3).Row)
Set dic = CreateObject("Scripting.Dictionary")
ReDim sArr(1 To UBound(Arr, 1), 1 To 4)
' Gan item vao Dic
With dic
For i = 1 To UBound(Arr, 1)
    If Not .exists(Arr(i, 1)) And Arr(i, 1) <> "" Then
        k = k + 1
        .Add Arr(i, 1), k
    ElseIf .exists(Arr(i, 1)) Then
        Arr(i, 2) = 1
    End If
Next
End With
' thay the cot c = " " sang gia tri ben tren
For i = 1 To UBound(Arr, 1)
    If Arr(i, 1) = "" Then
        Arr(i, 1) = Arr(i - 1, 1)
    End If
Next
 ' trich loc
  For Each Item In dic.keys
    For i = 1 To UBound(Arr, 1)
        If Arr(i, 1) = Item And Arr(i, 2) <> 1 Then
            t = t + 1
            sArr(t, 1) = Arr(i, 1)
            sArr(t, 2) = Arr(i, 2)
            sArr(t, 3) = Arr(i, 3)
            sArr(t, 4) = Arr(i, 4)
        End If
    Next
Next
Sheet2.[f4].Resize(UBound(Arr, 1), 4) = sArr
End Sub

Mình test code của bạn thì phát hiện lỗi chỗ này
i= 1 thì i-1 sẽ =0 nên Arr(0,1) bị lỗi
Mã:
For i = 1 To UBound(Arr, 1)
    If Arr(i, 1) = "" Then
        Arr(i, 1) = Arr(i - 1, 1)
    End If
Next
 
Upvote 0
Vừa hết giờ làm viết vội quá còn lỗi em xin sửa lại chút
Mã:
Sub Tonghop()
Dim Arr, sArr
Dim dic As Object
Dim i, k, t As Integer
Arr = Sheet1.Range("C5:F" & Sheet1.[D65000].End(3).Row)
Set dic = CreateObject("Scripting.Dictionary")
ReDim sArr(1 To UBound(Arr, 1), 1 To 4)
' Gan item vao Dic
With dic
For i = 1 To UBound(Arr, 1)
    If Not .exists(Arr(i, 1)) And Arr(i, 1) <> "" Then
        k = k + 1
        .Add Arr(i, 1), k
    ElseIf .exists(Arr(i, 1)) Then
        Arr(i, 2) = 1
    End If
Next
End With
' thay the cot c = " " sang gia tri ben tren
For i = 1 To UBound(Arr, 1)
    If Arr(i, 1) = "" Then
        Arr(i, 1) = Arr(i - 1, 1)
    End If
Next
'---  trich Loc
  For Each Item In dic.keys
    For i = 1 To UBound(Arr, 1)
        If Arr(i, 1) = Item And Arr(i, 2) = "" Then
            t = t + 1
            sArr(t, 1) = Arr(i, 1)
        ElseIf Arr(i, 1) = Item And Arr(i, 2) <> 1 Then
            t = t + 1
            sArr(t, 2) = Arr(i, 2)
            sArr(t, 3) = Arr(i, 3)
            sArr(t, 4) = Arr(i, 4)
        End If
    Next
Next
Sheet2.[f4].Resize(UBound(Arr, 1), 4) = sArr
End Sub

Mình test code của bạn thì phát hiện lỗi chỗ này
i= 1 thì i-1 sẽ =0 nên Arr(0,1) bị lỗi
Dạ mảng bắt đầu từ "Cà Văn Bó" với ô D5 = "" như vậy khi thay thế giá trị "" dưới "Cà Văn Bó"....bằng "Cà Văn Bó" mới được, như vậy code trên không sai, nếu sai khi và chỉ khi không tồn tại "Cà Văn Bó" đầu tiên (cái này có thể bắt lỗi)
 
Upvote 0
Hay tại quả này dễ quá! (nói trúng tim đen luôn)
ndu mà ra tay chắc còn cỡ 10 dòng là xong.
Hic, mà sao code mình đơn giản, dễ điều chỉnh vậy mà không được Nghĩa test nhỉ, "bùn" ghê

Bây giờ em test giúp Anh nhé!

Thêm một cái nữa cho đông vui:
Mã:
[B]Option Base 1[/B]
Option Explicit
Sub test()
    Dim arrDulieu(), arrKetqua(), DicHoTen, i, k, j, jj, ten
    Set DicHoTen = CreateObject("Scripting.Dictionary")
    [COLOR=#ff0000]Sheets("Du lieu").Select[/COLOR]
    [COLOR=#ff0000]arrDulieu = Sheets("Du lieu").Range([D5], [D65536].End(xlUp)).Offset(, -2).Resize(, 5).Value[/COLOR]
    [B]ReDim arrKetqua(UBound(arrDulieu, 1), 5)[/B]
    For i = 1 To UBound(arrDulieu, 1)
        If arrDulieu(i, 1) > 0 Then
            If Not DicHoTen.Exists(arrDulieu(i, 2)) Then
                j = j + 1: k = k + 1: jj = j
                DicHoTen.Add arrDulieu(i, 2), jj
                arrKetqua(k, 2) = arrDulieu(i, 2)
            End If
            ten = arrDulieu(i, 2)
        Else
            k = k + 1
            jj = DicHoTen.Item(ten)
            arrKetqua(k, 3) = arrDulieu(i, 3)
            arrKetqua(k, 4) = arrDulieu(i, 4)
            arrKetqua(k, 5) = arrDulieu(i, 5)
        End If
        arrKetqua(k, 1) = jj
    Next
[COLOR=#ff0000]    Sheets("Ket qua").Select
    With Range("A23")
        .Resize(k, 5).Value = arrKetqua
        .Resize(k, 5).Sort Range("A23"), 1
        .Resize(k).ClearContents
    End With[/COLOR]
End Sub

Đầu tiên Anh đã chọn Option Base 1 nói nôm na là bắt đầu số thứ tự của mảng lấy từ 1 (nếu thay 1 là 0 thì bắt đầu từ 0). Nhìn vào đó ta biết anh sẽ ghi ReDim arrKetqua(UBound(arrDulieu, 1), 5), nếu ta không đặt nó thì ta cũng có thể ghi ReDim arrKetqua(1 To UBound(arrDulieu, 1), 1 To 5), chỉ nói rộng ra thôi, cái này cũng chẳng ảnh hưởng gì đến code của Anh.

Cách mà code anh chạy dựa vào mục tên và mục số thứ tự để tìm chi tiết, sau đó gán mỗi mục tương ứng với một số thứ tự, rồi sắp xếp lại theo số thứ tự đã gán, cuối cùng xóa đi cột thứ tự.

Theo yêu cầu của chủ topic thì như vậy đã đạt đúng yêu cầu. Tuy nhiên, nếu như chủ topic lại thêm yêu cầu về số thứ tự của một mục, chắc code của anh hơi khó chỉnh sửa lại.

Về thời gian đã test trên 27,000 dòng đã có tốc độ 1.39s, như vậy cũng khá nhanh.

Về thuật toán em xin mạn phép bàn một chút:

Để giảm thời gian chạy ít nhiều trên code, người ta hiếm sử dụng SheetX.Select mà tham chiếu ngay trên địa chỉ Range luôn:

Thay vì:

Mã:
    [COLOR=#ff0000]Sheets("Du lieu").Select[/COLOR]
    arrDulieu = Sheets("Du lieu").Range([D5], [D65536].End(xlUp)).Offset(, -2).Resize(, 5).Value

và:
Mã:
    [COLOR=#ff0000]Sheets("Ket qua").Select[/COLOR]
    With Range("A4")
        .Resize(k, 5).Value = arrKetqua
        .Resize(k, 5).Sort Range("A4"), 1
        .Resize(k).ClearContents
    End With

Thì nên chỉnh lại như vầy:

Mã:
arrDulieu = Range([COLOR=#0000ff]Sheets("Du lieu")[/COLOR].[D5], [COLOR=#0000ff]Sheets("Du lieu")[/COLOR].[D65536].End(xlUp)).Offset(, -2).Resize(, 5).Value

và như vầy:

Mã:
    With Sheets("Ket qua").Range("A4")
        .Resize(k, 5).Value = arrKetqua
        .Resize(k, 5).Sort Range("A4"), 1
        .Resize(k).ClearContents
    End With

Nói chung code của Anh cũng cho tốc độ nhanh và cũng đã đúng yêu cầu của tác giả topic này. Một số ý kiến của em là vậy.
 
Lần chỉnh sửa cuối:
Upvote 0
Với bài này anh em nào có thể giải ra kết quả theo yêu cầu của tác giả mà không dùng dictionary. Chỉ là vui chơi thôi chứ em không dám có ý thách đố nha các anh. Vì cũng khá lâu rồi mới có 1 bài hấp dẫn thế này.
 
Lần chỉnh sửa cuối:
Upvote 0
Vừa hết giờ làm viết vội quá còn lỗi em xin sửa lại chút
Mã:
Sub Tonghop()
Dim Arr, sArr
Dim dic As Object
Dim i, k, t As Integer
Arr = Sheet1.Range("C5:F" & Sheet1.[D65000].End(3).Row)
Set dic = CreateObject("Scripting.Dictionary")
ReDim sArr(1 To UBound(Arr, 1), 1 To 4)
' Gan item vao Dic
With dic
For i = 1 To UBound(Arr, 1)
    If Not .exists(Arr(i, 1)) And Arr(i, 1) <> "" Then
        k = k + 1
        .Add Arr(i, 1), k
    ElseIf .exists(Arr(i, 1)) Then
        Arr(i, 2) = 1
    End If
Next
End With
' thay the cot c = " " sang gia tri ben tren
For i = 1 To UBound(Arr, 1)
    If Arr(i, 1) = "" Then
        Arr(i, 1) = Arr(i - 1, 1)
    End If
Next
'---  trich Loc
  For Each Item In dic.keys
    For i = 1 To UBound(Arr, 1)
        If Arr(i, 1) = Item And Arr(i, 2) = "" Then
            t = t + 1
            sArr(t, 1) = Arr(i, 1)
        ElseIf Arr(i, 1) = Item And Arr(i, 2) <> 1 Then
            t = t + 1
            sArr(t, 2) = Arr(i, 2)
            sArr(t, 3) = Arr(i, 3)
            sArr(t, 4) = Arr(i, 4)
        End If
    Next
Next
Sheet2.[f4].Resize(UBound(Arr, 1), 4) = sArr
End Sub


Dạ mảng bắt đầu từ "Cà Văn Bó" với ô D5 = "" như vậy khi thay thế giá trị "" dưới "Cà Văn Bó"....bằng "Cà Văn Bó" mới được, như vậy code trên không sai, nếu sai khi và chỉ khi không tồn tại "Cà Văn Bó" đầu tiên (cái này có thể bắt lỗi)

Bạn QuangHai đã nói đúng, hình như bạn chưa sửa được vấn đề này:

Mã:
' thay the cot c = " " sang gia tri ben tren
For i = 1 To UBound(Arr, 1)
    If Arr(i, 1) = "" Then
        Arr(i, 1) = Arr(i - 1, 1)
    End If
Next

Về nguyên tắc, với i = 1 mà Arr(i - 1, 1) thì code này đã bị lỗi ngay "vòng giữ xe" rồi! Nên code này chỉ cần sửa lại đơn giản như sau:

Mã:
For i = [COLOR=#ff0000][B]2[/B][/COLOR] To UBound(Arr, 1)
    If Arr(i, 1) = "" Then
        Arr(i, 1) = Arr(i - 1, 1)
    End If
Next

Về thời gian test thử trên 27000 dòng với 3 lần chạy thử (sau khi sửa lại 1 thành 2) thì thời gian chạy khoảng 1.6s.
 
Upvote 0
Với bài này anh em nào có thể giải ra kết quả theo yêu cầu của tác giả mà không dùng dictionary. Chỉ là vui chơi thôi chứ em không dám có ý thách đố nha các anh. Vì cũng khá lâu rồi mới có 1 bài hấp dẫn thế này.

Vấn đề này chỉ có chép ra một cột phụ rồi sort lại theo thứ tự, từ đó lọc trên mảng thôi. Không biết QuangHai có còn cách nào khác không?
 
Upvote 0
Vấn đề này chỉ có chép ra một cột phụ rồi sort lại theo thứ tự, từ đó lọc trên mảng thôi. Không biết QuangHai có còn cách nào khác không?
Mình giải thế này, xử lý tại vùng dữ liệu gốc luôn. Tuy có hơi chậm hơn cách có dictionary nhưng cũng không nhiều lắm

PHP:
Sub Tonghop_No_Dic()
Dim dl(), i As Long, kq(), j As Long, k As Long, n As Long
With Sheets("Du lieu")
   dl = .Range(.[C5], .[D65536].End(3).Offset(, 2)).Value
   For i = 2 To UBound(dl)
      If dl(i, 1) = "" Then dl(i, 1) = dl(i - 1, 1)
   Next
   .[C5].Resize(UBound(dl), 4) = dl
   .Range(.[C5], .[D65536].End(3).Offset(, 2)).Sort key1:=.[C3]
   dl = .Range(.[C5], .[D65536].End(3).Offset(, 2)).Value
   For i = UBound(dl) To 2 Step -1
      If dl(i, 1) = dl(i - 1, 1) Then dl(i, 1) = Empty
   Next
   .[C5].Resize(UBound(dl), 4) = dl
   ReDim kq(1 To UBound(dl), 1 To 5)
   For i = 1 To UBound(dl)
      If dl(i, 1) <> "" Or dl(i, 2) <> "" Then
         k = k + 1
         If dl(i, 2) = "" Then
            n = n + 1: kq(k, 1) = n
         End If
         For j = 2 To 5
            kq(k, j) = dl(i, j - 1)
         Next
      End If
   Next
   .[B5].Resize(UBound(dl), 5) = kq
End With
End Sub
 
Upvote 0
Mình giải thế này, xử lý tại vùng dữ liệu gốc luôn. Tuy có hơi chậm hơn cách có dictionary nhưng cũng không nhiều lắm

Mã:
Sub Tonghop_No_Dic()
Dim dl(), i As Long, kq(), j As Long, k As Long, n As Long
With Sheets("Du lieu")
   dl = .Range(.[C5], .[D65536].End(3).Offset(, 2)).Value
   For i = 2 To UBound(dl)
      If dl(i, 1) = "" Then dl(i, 1) = dl(i - 1, 1)
   Next
   .[C5].Resize(UBound(dl), 4) = dl
   [COLOR=#ff0000][B].Range(.[C5], .[D65536].End(3).Offset(, 2)).Sort key1:=.[C3][/B][/COLOR]
   dl = .Range(.[C5], .[D65536].End(3).Offset(, 2)).Value
   For i = UBound(dl) To 2 Step -1
      If dl(i, 1) = dl(i - 1, 1) Then dl(i, 1) = Empty
   Next
   .[C5].Resize(UBound(dl), 4) = dl
   ReDim kq(1 To UBound(dl), 1 To 5)
   For i = 1 To UBound(dl)
      If dl(i, 1) <> "" Or dl(i, 2) <> "" Then
         k = k + 1
         If dl(i, 2) = "" Then
            n = n + 1: kq(k, 1) = n
         End If
         For j = 2 To 5
            kq(k, j) = dl(i, j - 1)
         Next
      End If
   Next
   .[B5].Resize(UBound(dl), 5) = kq
End With
End Sub

Mình đã nói rồi, không dùng Sort thì không giải quyết được vấn đề về lọc duy nhất đâu!
 
Upvote 0
Rất vui mừng vì bài mình cuôí cùng cũng được "chấm", cảm ơn Hoàng Trọng Nghĩa. Bây giờ cứ xem như mình là trò đang lên thớt và phản biện nhé.


Bây giờ em test giúp Anh nhé!
Đầu tiên Anh đã chọn Option Base 1 nói nôm na là bắt đầu số thứ tự của mảng lấy từ 1 (nếu thay 1 là 0 thì bắt đầu từ 0). Nhìn vào đó ta biết anh sẽ ghi ReDim arrKetqua(UBound(arrDulieu, 1), 5), nếu ta không đặt nó thì ta cũng có thể ghi ReDim arrKetqua(1 To UBound(arrDulieu, 1), 1 To 5), chỉ nói rộng ra thôi, cái này cũng chẳng ảnh hưởng gì đến code của Anh.
Cái này chỉ là thói quen thôi (mình thống nhất với ... mình vậy rồi), để đề phòng bất trắc xảy ra, vì trong module của mình nhiều khi không phải là một mảng mà có thể nhiều mảng nên trên đầu module nào có mảng mình luôn dể câu Option Base 1. Vì vậy, có khi trước một mảng mình khai báo là ReDim arrABC(1 To 10, 1 To 5) nhưng trên đầu module của mình vẫn có câu Option Base 1 do quên không xóa nhưng vô hại.


Theo yêu cầu của chủ topic thì như vậy đã đạt đúng yêu cầu. Tuy nhiên, nếu như chủ topic lại thêm yêu cầu về số thứ tự của một mục, chắc code của anh hơi khó chỉnh sửa lại.
Nếu muốn có STT thì có nhiều cách, nhưng làm sao không phải thêm vòng lặp nữa để khổi ảnh hưởng tốc độ. Không gì khó cả, đã có vòng lặp sẵn rồi, tạo thêm một mảng một cột lấy STT đồng thời với việc tạo mảng kết quả khi chạy vòng lặp đó. Có mảng TT rồi, khi gán mảng kết quả và sort xong ta gán mảng này luôn. Mình thích thuật toán này vì chỉ dùng có một vòng lăp cho cả sub.

Về thuật toán em xin mạn phép bàn một chút:

Để giảm thời gian chạy ít nhiều trên code, người ta hiếm sử dụng SheetX.
Select mà tham chiếu ngay trên địa chỉ Range luôn
Ờ, cũng là do thói quen thôi, khi code ít di chuyển qua lại giữa các Sheet thì mình luôn làm vậy để dùng cho các câu lệnh khác luôn, ở đây chỉ có hai lần chọn Sheet nên mình nghĩ là không sao.
 
Upvote 0
Rất vui mừng vì bài mình cuôí cùng cũng được "chấm", cảm ơn Hoàng Trọng Nghĩa. Bây giờ cứ xem như mình là trò đang lên thớt và phản biện nhé.


Cái này chỉ là thói quen thôi (mình thống nhất với ... mình vậy rồi), để đề phòng bất trắc xảy ra, vì trong module của mình nhiều khi không phải là một mảng mà có thể nhiều mảng nên trên đầu module nào có mảng mình luôn dể câu Option Base 1. Vì vậy, có khi trước một mảng mình khai báo là ReDim arrABC(1 To 10, 1 To 5) nhưng trên đầu module của mình vẫn có câu Option Base 1 do quên không xóa nhưng vô hại.

Nếu muốn có STT thì có nhiều cách, nhưng làm sao không phải thêm vòng lặp nữa để khổi ảnh hưởng tốc độ. Không gì khó cả, đã có vòng lặp sẵn rồi, tạo thêm một mảng một cột lấy STT đồng thời với việc tạo mảng kết quả khi chạy vòng lặp đó. Có mảng TT rồi, khi gán mảng kết quả và sort xong ta gán mảng này luôn. Mình thích thuật toán này vì chỉ dùng có một vòng lăp cho cả sub.

Ờ, cũng là do thói quen thôi, khi code ít di chuyển qua lại giữa các Sheet thì mình luôn làm vậy để dùng cho các câu lệnh khác luôn, ở đây chỉ có hai lần chọn Sheet nên mình nghĩ là không sao.

Khi chọn qua một sheet khác, nếu sheet này có đặt 2 sự kiện:

PHP:
Private Sub Worksheet_Activate()

End Sub

Private Sub Worksheet_Deactivate()

End Sub

Thì các sự kiện này sẽ chạy, chắc anh không muốn chúng nó chạy khi anh đang chạy code chứ? Vì vậy tốt hơn hết ta đừng Select sheet gì cả.
 
Upvote 0
Mình đã nói rồi, không dùng Sort thì không giải quyết được vấn đề về lọc duy nhất đâu!
Vậy là như thế nào anh Nghĩa, nếu tác động trục tiếp trên cell thì vẫn có cách trích lọc duy nhất mà.
PHP:
Sub Th()
Dim Arr, Dl
Dim i, k As Integer
With Sheet1
Dl = .Range("c5:f" & [f65536].End(xlUp).Row)
ReDim Arr(1 To UBound(Dl), 1 To 4)
For i = 1 To [f65536].End(xlUp).Row
    If Cells(i + 2, 3) <> "" And Application.WorksheetFunction.CountIf(Range(Cells(5, 3), Cells(i + 2, 3)), Cells(i + 2, 3)) = 1 Then
                k = k + 1
                Arr(k, 1) = Cells(i + 2, 3)
    End If
Next
End With
End Sub
 
Upvote 0
Vậy là như thế nào anh Nghĩa, nếu tác động trục tiếp trên cell thì vẫn có cách trích lọc duy nhất mà.
PHP:
Sub Th()
Dim Arr, Dl
Dim i, k As Integer
With Sheet1
Dl = .Range("c5:f" & [f65536].End(xlUp).Row)
ReDim Arr(1 To UBound(Dl), 1 To 4)
For i = 1 To [f65536].End(xlUp).Row
    If Cells(i + 2, 3) <> "" And Application.WorksheetFunction.CountIf(Range(Cells(5, 3), Cells(i + 2, 3)), Cells(i + 2, 3)) = 1 Then
                k = k + 1
                Arr(k, 1) = Cells(i + 2, 3)
    End If
Next
End With
End Sub
Đúng rồi, còn thêm phương án dùng advancefilter trích lọc duy nhất và sau đó có thể không dùng Dic.
 
Upvote 0
Mình đã nói rồi, không dùng Sort thì không giải quyết được vấn đề về lọc duy nhất đâu!
Híc, cái này hình như không chính xác lắm, lúc trước chưa biết sử dụng em "Đít To" thì cũng có cả đống cách giải quyết duy nhất cơ mà
Với đề bài này, nếu không cho sử dụng Dic, Sort, Mảng, Bộ Lọc vẫn có thể giải quyết được ( dĩ nhiên code nó rườm ra & tốc độ thì "xi-ma-chao", hihi)
Trong bài chỉ là một trong nhiều cách giải xử lý hoàn toàn trên sheet ( cứ Ạc, Ạc mãi cũng chán)
Híc
 

File đính kèm

Upvote 0
Bây giờ, trên file này tôi gửi lên, bạn nào Không dùng Dictionary, không dùng AvancedFilter chỉ xử lý trên mảng thì đưa lên phương án.

Cách của tôi:

PHP:
Sub HTN_UniqueOnly_Sort()
    Dim h As Long, i As Long, r As Long
    Dim sArray, UnqArr, sItem As String
    With Sheet1.Range("BB1:BB60")
        .Value = Sheet1.Range("A1:A60").Value
        .Sort Sheet1.[BB1], 1
         sArray = .Value
        .Clear
    End With
    i = UBound(sArray, 1): r = 0: sItem = ""
    ReDim UnqArr(1 To i, 1 To 1)
    For h = 1 To i
        If sArray(h, 1) <> "" And sArray(h, 1) <> sItem Then
            r = r + 1
            UnqArr(r, 1) = sArray(h, 1)
        End If
        sItem = sArray(h, 1)
    Next
    Sheet1.Range("J3").Resize(r).Value = UnqArr
End Sub
 

File đính kèm

Upvote 0
Bây giờ, trên file này tôi gửi lên, bạn nào Không dùng Dictionary, không dùng AvancedFilter chỉ xử lý trên mảng thì đưa lên phương án.

Cách của tôi:

PHP:
Sub HTN_UniqueOnly_Sort()
    Dim h As Long, i As Long, r As Long
    Dim sArray, UnqArr, sItem As String
    With Sheet1.Range("BB1:BB60")
        .Value = Sheet1.Range("A1:A60").Value
        .Sort Sheet1.[BB1], 1
         sArray = .Value
        .Clear
    End With
    i = UBound(sArray, 1): r = 0: sItem = ""
    ReDim UnqArr(1 To i, 1 To 1)
    For h = 1 To i
        If sArray(h, 1) <> "" And sArray(h, 1) <> sItem Then
            r = r + 1
            UnqArr(r, 1) = sArray(h, 1)
        End If
        sItem = sArray(h, 1)
    Next
    Sheet1.Range("J3").Resize(r).Value = UnqArr
End Sub

Hic anh Nghĩa ơi bài toán này mình xử lý không tới 10 dòng lệnh đấy nhé
Chắc anh không nhớ là những chiêu này mình học của anh đấy.

Mã:
Sub loc_khong_trung_quanghai()
Dim dl(), tim As Object, i As Long
dl = Range([A1], [a65536].End(3)).Value
For i = 1 To UBound(dl)
   Set tim = Range("J:J").Find(dl(i, 1))
   If tim Is Nothing Then [J65536].End(3).Offset(1) = dl(i, 1)
Next
End Sub
 
Lần chỉnh sửa cuối:
Upvote 0
Một cách nữa
Mã:
Public Sub DuyNhat()
    Dim Vung, Kq, Cll, Tach
    Vung = Range([A1], [A10000].End(xlUp))
        For Each Cll In Vung
            If Cll <> "" Then
                If InStr(1, Kq, Cll) = 0 Then Kq = Kq & Cll & ","
            End If
        Next Cll
    Tach = Split(Kq, ",")
[B1].Resize(UBound(Tach)) = Application.WorksheetFunction.Transpose(Tach)
End Sub
Híc, Dzui
 
Upvote 0
Một cách nữa
Mã:
Public Sub DuyNhat()
    Dim Vung, Kq, Cll, Tach
    Vung = Range([A1], [A10000].End(xlUp))
        For Each Cll In Vung
            If Cll <> "" Then
                If InStr(1, Kq, Cll) = 0 Then Kq = Kq & Cll & ","
            End If
        Next Cll
    Tach = Split(Kq, ",")
[B1].Resize(UBound(Tach)) = Application.WorksheetFunction.Transpose(Tach)
End Sub
Híc, Dzui

Cách của anh Cò thật độc đáo, nhưng chưa đúng anh ơi. Giả sử có Chuỗi Hoàng Trọng nằm khoảng giữa trong vùng dữ liệu thì code anh tèo rồi.. hic
 
Upvote 0
Web KT

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

Back
Top Bottom