Lọc danh sách duy nhất cho từng cột riêng rẽ (8 người xem)

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

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

Thầy ndu code của em vẫn còn sai tung tóe. Thầy thử xem có được ko?
 

File đính kèm

Thầy ndu code của em vẫn còn sai tung tóe. Thầy thử xem có được ko?

Bạn xem lại qua chút . Code này khi bấm run lần đầu cho kết quả đúng, bấm lần tiếp theo dữ liệu bị mất rồi cứ bấm là mất dần mất dần, đến khi chi còn lại hàng đầu tiên
 
Thầy ndu code của em vẫn còn sai tung tóe. Thầy thử xem có được ko?

Sửa code của bạn:
Mã:
Sub Button5_Click()
  Dim a, tmp
  Dim i As Long, ii As Long, n As Long
  Dim rng As Range, dic As Object
  Set rng = ActiveSheet.UsedRange
  With rng
    For i = 1 To .Columns.Count
      a = .Columns(i).Value
      If IsArray(a) Then
        [COLOR=#ff0000]Set dic = CreateObject("Scripting.Dictionary")
        dic.CompareMode = vbTextCompare[/COLOR]
        ReDim b(1 To UBound(a), 1 To 1)
       [COLOR=#ff0000] n = 0[/COLOR]
        For ii = 1 To UBound(a)
          tmp = CStr(a(ii, 1))
          If Len(tmp) Then
            If Not dic.Exists(tmp) Then
              n = n + 1
              dic.Add tmp, n
              b(n, 1) = tmp
            End If
          End If
        Next
        If n Then .Columns(i).Value = b
      End If
    Next
  End With
End Sub
 
Vậy thì bạn vui lòng đưa dữ liệu gần giống thật nhất lên đây, nêu rõ kết quả lọc đặt tại đâu nhé!
Bởi với dữ liệu đơn sơ như ở bài 2 thì tôi tin chắc rằng sau khi viết code xong, bạn ráp vào file thật không được lại chạy lên hỏi tiếp cho mà coi
Em gửi file mẫu đây ạ, dữ liệu không chính xác nhưng kiểu dữ liệu thì đúng ạ.
Thầy xem giúp em với ạ.
 

File đính kèm

Em cảm ơn thầy file chuẩn rồi ạ. Em thật sự xúc động
 
Sửa code của bạn:
Mã:
Sub Button5_Click()
  Dim a, tmp
  Dim i As Long, ii As Long, n As Long
  Dim rng As Range, dic As Object
  Set rng = ActiveSheet.UsedRange
  With rng
    For i = 1 To .Columns.Count
      a = .Columns(i).Value
      If IsArray(a) Then
        [COLOR=#ff0000]Set dic = CreateObject("Scripting.Dictionary")
        dic.CompareMode = vbTextCompare[/COLOR]
        ReDim b(1 To UBound(a), 1 To 1)
       [COLOR=#ff0000] n = 0[/COLOR]
        For ii = 1 To UBound(a)
          tmp = CStr(a(ii, 1))
          If Len(tmp) Then
            If Not dic.Exists(tmp) Then
              n = n + 1
              dic.Add tmp, n
              b(n, 1) = tmp
            End If
          End If
        Next
        If n Then .Columns(i).Value = b
      End If
    Next
  End With
End Sub
Em mới thử có bao nhiêu cột được hết
dòng sau khả năng của em chưa hiểu tới...Nếu được xin anh chỉ dùm

dic.CompareMode = vbTextCompare

Em cảm ơn
 
Em gửi file mẫu đây ạ, dữ liệu không chính xác nhưng kiểu dữ liệu thì đúng ạ.
Thầy xem giúp em với ạ.

Thấy chưa! Dữ liệu mới đưa lên chẳng giống chút nào so với yêu cầu ban đầu
Bài này mà làm cũng không phải chuyện dễ đâu à nghen
Mời các cao thủ thử sức
-----------------------
Nói thêm: Trong file của bạn, tại cell B70 tôi thấy bạn ghi:
Lọc hết Cod và Qty Exp của ngày thường
Nhưng khu vực lọc ra kết quả bạn cho sẵn 10 dòng. Sao bạn biết chắc kết quả chỉ 10 dòng? Lỡ kết quả 20 dòng thì sao?
 
-----------------------
Nói thêm: Trong file của bạn, tại cell B70 tôi thấy bạn ghi:

Nhưng khu vực lọc ra kết quả bạn cho sẵn 10 dòng. Sao bạn biết chắc kết quả chỉ 10 dòng? Lỡ kết quả 20 dòng thì sao?

Vâng, theo đặc thù công việc thì số dòng kết quả chỉ chừng đó là đủ rồi thầy ạ. Mỗi cá nhân và mỗi bộ phận đảm nhận một số lượng mã, và các mã này lại có thể được phân loại ra theo các sheet nữa, nên 10 dòng là ok rồi ạ.
 
Thấy chưa! Dữ liệu mới đưa lên chẳng giống chút nào so với yêu cầu ban đầu
Bài này mà làm cũng không phải chuyện dễ đâu à nghen
Mời các cao thủ thử sức
-----------------------
Nói thêm: Trong file của bạn, tại cell B70 tôi thấy bạn ghi:

Nhưng khu vực lọc ra kết quả bạn cho sẵn 10 dòng. Sao bạn biết chắc kết quả chỉ 10 dòng? Lỡ kết quả 20 dòng thì sao?

tính đi rồi mà nghe thầy NDU quảng cáo dữ quá , quay lại đu dây tí . hi hi
Mã:
Public Sub hello()
Dim rgName As String, arr As Variant, Dic As Object, tempKey As Variant
Dim r As Long, c As Long, preDay As Byte, dArr As Variant, arRow(1 To 4) As Long
Set Dic = CreateObject("Scripting.Dictionary")
With Sheet18
    rgName = .Range("B10").CurrentRegion.Address
    arr = .Range("C10" & Mid(rgName, InStr(rgName, ":"))).Value
    ReDim dArr(1 To 40, 1 To UBound(arr, 2) - 1)
    For c = 2 To UBound(arr, 2) Step 1
        arr(1, c) = IIf(Len(arr(1, c)) > 0, Weekday(arr(1, c), vbMonday), preDay)
        preDay = arr(1, c)
        arRow(1) = 0: arRow(2) = 10: arRow(3) = 20: arRow(4) = 30
        Dic.RemoveAll
        For r = 3 To UBound(arr) Step 1
            If Len(arr(r, c)) > 0 Then
                tempKey = arr(r, 1) & ";" & arr(r, c)
                If Not Dic.exists(tempKey) Then
                    Dic(tempKey) = 1
                    If arr(r, 1) = "Exp" Then
                        If arr(1, c) < 6 Then
                            arRow(1) = WorksheetFunction.Min(arRow(1) + 1, 10)
                            dArr(arRow(1), c - 1) = arr(r, c)
                        End If
                    ElseIf arr(r, 1) = "Imp" Then
                        If arr(1, c) < 6 Then
                            arRow(2) = WorksheetFunction.Min(arRow(2) + 1, 20)
                            dArr(arRow(2), c - 1) = arr(r, c)
                        ElseIf arr(1, c) = 6 Then
                            arRow(3) = WorksheetFunction.Min(arRow(3) + 1, 30)
                            dArr(arRow(3), c - 1) = arr(r, c)
                        Else
                            arRow(4) = WorksheetFunction.Min(arRow(4) + 1, 40)
                            dArr(arRow(4), c - 1) = arr(r, c)
                        End If
                    End If
                End If
            End If
        Next
    Next
    .Range("D" & .Range("D" & Mid(rgName, InStrRev(rgName, "$") + 1)).End(xlDown).Row + 1) _
                .Resize(40, UBound(dArr, 2)).Value = dArr
End With
End Sub
 
=
dòng sau khả năng của em chưa hiểu tới...Nếu được xin anh chỉ dùm

dic.CompareMode = vbTextCompare

Em cảm ơn

Không biết có thể thí nghiệm:
Mã:
Sub Test_1()
  Dim dic As Object
  Set dic = CreateObject("Scripting.Dictionary")
  dic.Add "a", ""
  dic.Add "A", ""
End Sub
Mã:
Sub Test_2()
  Dim dic As Object
  Set dic = CreateObject("Scripting.Dictionary")
  [COLOR=#ff0000]dic.CompareMode = vbTextCompare[/COLOR]
  dic.Add "a", ""
  dic.Add "A", ""
End Sub
Test_2vbTextCompareTest_1 không có. Chạy thử 2 Sub và so sánh. Đọc kỹ thông báo lỗi nếu có
Nói thêm: Sub Test_1 không ghi Compare kiểu nào thì ngầm hiểu là dic.CompareMode = vbBinaryCompare
 
tính đi rồi mà nghe thầy NDU quảng cáo dữ quá , quay lại đu dây tí . hi hi
Mã:
Public Sub hello()
Dim rgName As String, arr As Variant, Dic As Object, tempKey As Variant
Dim r As Long, c As Long, preDay As Byte, dArr As Variant, arRow(1 To 4) As Long
Set Dic = CreateObject("Scripting.Dictionary")
With Sheet18
    rgName = .Range("B10").CurrentRegion.Address
    arr = .Range("C10" & Mid(rgName, InStr(rgName, ":"))).Value
    ReDim dArr(1 To 40, 1 To UBound(arr, 2) - 1)
    For c = 2 To UBound(arr, 2) Step 1
        arr(1, c) = IIf(Len(arr(1, c)) > 0, Weekday(arr(1, c), vbMonday), preDay)
        preDay = arr(1, c)
        arRow(1) = 0: arRow(2) = 10: arRow(3) = 20: arRow(4) = 30
        Dic.RemoveAll
        For r = 3 To UBound(arr) Step 1
            If Len(arr(r, c)) > 0 Then
                tempKey = arr(r, 1) & ";" & arr(r, c)
                If Not Dic.exists(tempKey) Then
                    Dic(tempKey) = 1
                    If arr(r, 1) = "Exp" Then
                        If arr(1, c) < 6 Then
                            arRow(1) = WorksheetFunction.Min(arRow(1) + 1, 10)
                            dArr(arRow(1), c - 1) = arr(r, c)
                        End If
                    ElseIf arr(r, 1) = "Imp" Then
                        If arr(1, c) < 6 Then
                            arRow(2) = WorksheetFunction.Min(arRow(2) + 1, 20)
                            dArr(arRow(2), c - 1) = arr(r, c)
                        ElseIf arr(1, c) = 6 Then
                            arRow(3) = WorksheetFunction.Min(arRow(3) + 1, 30)
                            dArr(arRow(3), c - 1) = arr(r, c)
                        Else
                            arRow(4) = WorksheetFunction.Min(arRow(4) + 1, 40)
                            dArr(arRow(4), c - 1) = arr(r, c)
                        End If
                    End If
                End If
            End If
        Next
    Next
    .Range("D" & .Range("D" & Mid(rgName, InStrRev(rgName, "$") + 1)).End(xlDown).Row + 1) _
                .Resize(40, UBound(dArr, 2)).Value = dArr
End With
End Sub
Thanks bác, chuẩn rồi bác ơi. Nhưng e có thắc mắc chút là sao nó lại có cái dòng ô mang giá trị 118 ở bên cột Cod như hình thế ah? Bác xem bỏ giúp em với.
exl01.png
E hơi tham lam chút :
Bác có thể giúp e làm cho cái macro nó tụ chạy mà ko cần phải ấn Alt+F8 -> Run không ạ?

Bác hộ e chỉnh sột Qty ko phải là list duy nhất mà là total của từng mã ở cột Cod bên cạnh.

E thấy code của bác chạy rất nhanh. Các bác giúp e với nhé. Cảm ơn các bác nhiều ạ.
 
Lần chỉnh sửa cuối:
Thanks bác, chuẩn rồi bác ơi. Nhưng e có thắc mắc chút là sao nó lại có cái dòng ô mang giá trị 118 ở bên cột Cod như hình thế ah? Bác xem bỏ giúp em với.
View attachment 147440
E hơi tham lam chút :
Bác có thể giúp e làm cho cái macro nó tụ chạy mà ko cần phải ấn Alt+F8 -> Run không ạ?

Bác hộ e chỉnh sột Qty ko phải là list duy nhất mà là total của từng mã ở cột Cod bên cạnh.

E thấy code của bác chạy rất nhanh. Các bác giúp e với nhé. Cảm ơn các bác nhiều ạ.

mình bị dị ứng với các thể loại cứ làm xong là bên kia thay đổi yêu cầu . nên trong vài ngày tới mình không làm đâu . bạn cứ yên tâm mà chờ thành viên khác
 
mình bị dị ứng với các thể loại cứ làm xong là bên kia thay đổi yêu cầu . nên trong vài ngày tới mình không làm đâu . bạn cứ yên tâm mà chờ thành viên khác

Rất xin lỗi vì đã phiền bạn. Thực ra cái này không phải là thay đổi yêu cầu, có lẽ là do lúc đầu mình diễn đạt chưa cặn kẽ và rõ ràng. Mong bạn bỏ quá cho.

Dù sao cũng rất cám ơn sự nhiệt tình của bạn.Nếu không phiền bạn xem giúp mình tại sao lại có số 96 như trong hình với nhé.

Trân trọng!
 
Còn vấn đề tự chạy macro, mình đã xử lý được rồi , có thể dùng code gọi nó ra lúc mở hoặc đóng file :)
 
Thanks bác, chuẩn rồi bác ơi. Nhưng e có thắc mắc chút là sao nó lại có cái dòng ô mang giá trị 118 ở bên cột Cod như hình thế ah? ....
Cái này là do xác định mảng arr sai.
mấy số đó chính là số ở dòng Summary by Day

nếu bảng tính không thay đổi về KT thì bạn có thể thay :
PHP:
arr = .Range("C10" & Mid(rgName, InStr(rgName, ":"))).Value
thành :
PHP:
arr = .Range("C10:LA65").value
 
Cái này là do xác định mảng arr sai.
mấy số đó chính là số ở dòng Summary by Day

nếu bảng tính không thay đổi về KT thì bạn có thể thay :
PHP:
arr = .Range("C10" & Mid(rgName, InStr(rgName, ":"))).Value
thành :
PHP:
arr = .Range("C10:LA65").value
Chuẩn rồi bạn ơi. Thanks bạn nhé.

Bạn có thể giúp mình chỉnh lại code chút xíu được ko? Bỏ dữ liệu bên cột số đi để mình đưa công thức tính tổng từng code bên cạnh vào. nếu bạn sửa được code để nó tự tính tổng luôn thì đẹp quá.
 
tính đi rồi mà nghe thầy NDU quảng cáo dữ quá , quay lại đu dây tí . hi hi
Mã:
Public Sub hello()
Dim rgName As String, arr As Variant, Dic As Object, tempKey As Variant
Dim r As Long, c As Long, preDay As Byte, dArr As Variant, arRow(1 To 4) As Long
Set Dic = CreateObject("Scripting.Dictionary")
With [COLOR=#ff0000]Sheet18[/COLOR]
    rgName = .Range("B10").CurrentRegion.Address
    arr = .Range("C10" & Mid(rgName, InStr(rgName, ":"))).Value
    ReDim dArr(1 To 40, 1 To UBound(arr, 2) - 1)
    For c = 2 To UBound(arr, 2) Step 1
        arr(1, c) = IIf(Len(arr(1, c)) > 0, Weekday(arr(1, c), vbMonday), preDay)
        preDay = arr(1, c)
        arRow(1) = 0: arRow(2) = 10: arRow(3) = 20: arRow(4) = 30
        Dic.RemoveAll
        For r = 3 To UBound(arr) Step 1
            If Len(arr(r, c)) > 0 Then
                tempKey = arr(r, 1) & ";" & arr(r, c)
                If Not Dic.exists(tempKey) Then
                    Dic(tempKey) = 1
                    If arr(r, 1) = "Exp" Then
                        If arr(1, c) < 6 Then
                            arRow(1) = WorksheetFunction.Min(arRow(1) + 1, 10)
                            dArr(arRow(1), c - 1) = arr(r, c)
                        End If
                    ElseIf arr(r, 1) = "Imp" Then
                        If arr(1, c) < 6 Then
                            arRow(2) = WorksheetFunction.Min(arRow(2) + 1, 20)
                            dArr(arRow(2), c - 1) = arr(r, c)
                        ElseIf arr(1, c) = 6 Then
                            arRow(3) = WorksheetFunction.Min(arRow(3) + 1, 30)
                            dArr(arRow(3), c - 1) = arr(r, c)
                        Else
                            arRow(4) = WorksheetFunction.Min(arRow(4) + 1, 40)
                            dArr(arRow(4), c - 1) = arr(r, c)
                        End If
                    End If
                End If
            End If
        Next
    Next
    .Range("D" & .Range("D" & Mid(rgName, InStrRev(rgName, "$") + 1)).End(xlDown).Row + 1) _
                .Resize(40, UBound(dArr, 2)).Value = dArr
End With
End Sub

Có bác nào thử code này với file có nhiều sheet chưa ạ? mình làm trên 1 sheet thì ok. Nhưng trên nhiều sheet thì không chạy được.
Có lẽ là do dòng này (mình đoán vậy) mà ko biết sửa thế nào.

Mong các bạn chỉ giúp.
 
Lần chỉnh sửa cuối:
Có bác nào thử code này với file có nhiều sheet chưa ạ? mình làm trên 1 sheet thì ok. Nhưng trên nhiều sheet thì không chạy được.
Có lẽ là do dòng này (mình đoán vậy) mà ko biết sửa thế nào.

Mong các bạn chỉ giúp.

Có thể sửa thành : With ActiveSheet

còn cái này là tổng thế nào ?
Bạn có thể giúp mình chỉnh lại code chút xíu được ko? Bỏ dữ liệu bên cột số đi để mình đưa công thức tính tổng từng code bên cạnh vào. nếu bạn sửa được code để nó tự tính tổng luôn thì đẹp quá.
 
Thanks bạn.

Mình up file dữ liệu mẫu, đã qua tính toán theo cách thủ công ( chưa áp code vào). Mình đã chú thích thêm trong đó rồi nhé.
Ý bạn là các mã cùng cột mà trùng nhau thì sum lại với nhau.
vậy thì sửa code lại thành thế này xem sao:
HTML:
Public Sub hello()
Dim arr As Variant, Dic As Object, tempKey As Variant
Dim r As Long, c As Long, preDay As Byte, dArr As Variant, arRow(1 To 4) As Long
Set Dic = CreateObject("Scripting.Dictionary")
With ActiveSheet
    arr = .Range("C10:LA65").Value
    ReDim dArr(1 To 40, 1 To UBound(arr, 2) - 1)
    For c = 2 To UBound(arr, 2) Step 2
        arr(1, c) = IIf(Len(arr(1, c)) > 0, Weekday(arr(1, c), vbMonday), preDay)
        preDay = arr(1, c)
        arRow(1) = 0: arRow(2) = 10: arRow(3) = 20: arRow(4) = 30
        Dic.RemoveAll
        For r = 3 To UBound(arr) Step 1
            If Len(arr(r, c)) > 0 Then
                tempKey = arr(r, 1) & ";" & arr(r, c)
                If Not Dic.exists(tempKey) Then
                          If arr(r, 1) = "Exp" Then
                                If arr(1, c) < 6 Then
                                    arRow(1) = WorksheetFunction.Min(arRow(1) + 1, 10)
                                    Dic.Add tempKey, arRow(1)
                                    dArr(arRow(1), c - 1) = arr(r, c)
                                    dArr(arRow(1), c) = arr(r, c + 1)
                                End If
                            ElseIf arr(r, 1) = "Imp" Then
                                If arr(1, c) < 6 Then
                                    arRow(2) = WorksheetFunction.Min(arRow(2) + 1, 20)
                                    Dic.Add tempKey, arRow(2)
                                    dArr(arRow(2), c - 1) = arr(r, c)
                                    dArr(arRow(2), c) = arr(r, c + 1)
                                ElseIf arr(1, c) = 6 Then
                                    arRow(3) = WorksheetFunction.Min(arRow(3) + 1, 30)
                                    Dic.Add tempKey, arRow(3)
                                    dArr(arRow(3), c - 1) = arr(r, c)
                                    dArr(arRow(3), c) = arr(r, c + 1)
                                Else
                                    arRow(4) = WorksheetFunction.Min(arRow(4) + 1, 40)
                                    Dic.Add tempKey, arRow(4)
                                    dArr(arRow(4), c - 1) = arr(r, c)
                                    dArr(arRow(4), c) = arr(r, c + 1)
                                End If
                            End If
                     Else
                     dArr(Dic.Item(tempKey), c) = dArr(Dic.Item(tempKey), c) + arr(r, c + 1)
                End If
            End If
        Next
    Next
    .Range("D70:LA109") = dArr
End With
End Sub
 
Web KT

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

Back
Top Bottom