Các câu hỏi về lọc ra danh sách duy nhất (loại bỏ dữ liệu trùng) (3 người xem)

Liên hệ QC

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

Lọc dữ liệu, lấy ra giá trị chưa có

Chào
Mình có thắc mấc muốn hỏi các huynh và các Tỷ
Mình đính kèm file danh sách chấm điểm.xls
trong sheet tính điểm mình đã có danh sách mã khách hàng (cột D-mã khách hàng là số-VD: 123456) đã được chấm điểm trong các ngày 30/06/07, 31/12/07 , 30/06/08, 30/09/08.
Trong các sheet còn lại có một số khách hàng chưa được tính điểm
tôi muốn lọc ra trong các sheet 30/06/07, 31/12/07 , 30/06/08, 30/09/08-các ngày đó có mã khách hàng nào chưa được tính điểm thì làm như thế nào(mã khách hàng nào đã có trong cột D của sheet "tính điểm" thì không lấy) .}}}}}
mong các huynh giúp đỡ!! (giá trị được lọc ra có thể nằm ở đâu cũng được,có thể là sheet mới)
Regards
Macarong
P/S : mình cần gấp lắm,ai có lời giải mình sẽ gặp nhau uống cà fê cho zui

hàm Vlookup dùng ở đây được không?
 

File đính kèm

Chỉnh sửa lần cuối bởi điều hành viên:
Chào
Mình có thắc mấc muốn hỏi các huynh và các Tỷ
Mình đính kèm file danh sách chấm điểm.xls
trong sheet tính điểm mình đã có danh sách mã khách hàng (cột D-mã khách hàng là số-VD: 123456) đã được chấm điểm trong các ngày 30/06/07, 31/12/07 , 30/06/08, 30/09/08.
Trong các sheet còn lại có một số khách hàng chưa được tính điểm
tôi muốn lọc ra trong các sheet 30/06/07, 31/12/07 , 30/06/08, 30/09/08-các ngày đó có mã khách hàng nào chưa được tính điểm thì làm như thế nào(mã khách hàng nào đã có trong cột D của sheet "tính điểm" thì không lấy) .}}}}}
mong các huynh giúp đỡ!! (giá trị được lọc ra có thể nằm ở đâu cũng được,có thể là sheet mới)
Regards
Macarong
P/S : mình cần gấp lắm,ai có lời giải mình sẽ gặp nhau uống cà fê cho zui

Theo tôi, bác nên copy tất cả danh sách khách hàng vào một sheet, viêc lọc sẽ đơn giản hơn. Bác xem thử file Dosnet làm cho bác (Không biết có được cafe ko đây }}}}})
 

File đính kèm

Cám ơn Dosnet, vẫn chưa được, ví dụ vẫn chưa lọc ra ngày 30/06/07 có khách hàng nào chưa chấm điểm.
mục đích là tìm trong các sheet ngày đó có ai chưa được có trong sheet "tinh diem" ,mỗi sheet sẽ có 1 danh sách tương ứng(danh sách các KH chưa có trong'tinh diem")
 
Lần chỉnh sửa cuối:
vậy không giá trị nào đã trùng thì không muốn xất hiện thì dùng như thế nào?
vi du A B C A D F E A C F ,muốn lọc ra chỉ có B D E thì làm sao?
 
Mục đích là tìm trong các sheet ngày đó có ai chưa được có trong sheet "tinh diem" ,mỗi sheet sẽ có 1 danh sách tương ứng(danh sách các KH chưa có trong'tinh diem")

Chúng ta phải tìm theo mã khách hàng (MKH) từ các sheets tương ứng; nhưng MKH bên [Tinh Diem] chỉ là các số 6 chữ số; còn các sheets còn lại có MKH đến > 7 ký số; Tìm sao đây bạn?!
 
Cám ơn Dosnet, vẫn chưa được, ví dụ vẫn chưa lọc ra ngày 30/06/07 có khách hàng nào chưa chấm điểm.
mục đích là tìm trong các sheet ngày đó có ai chưa được có trong sheet "tinh diem" ,mỗi sheet sẽ có 1 danh sách tương ứng(danh sách các KH chưa có trong'tinh diem")
Thực ra Dosnet đã gộp 3 sheet vào một sheet LOC cho bác rồi, nếu thích làm riêng từng sheet thì đơn giản thôi.
- Ngoài việc phát hiện ra mã khách hàng (lúc thì 4,5,6 số) như bác ChanhTQ@ nói, Dosnet nhận thấy trong các sheet yêu cầu chấm điểm có rất nhiều mã trùng nhau, hầu hết là trùng từ 2 đến 3 lần trong một danh sách.
- Nếu đơn giản chỉ là việc phát hiện ra khách hàng nào chưa được tính điểm, ta nên dùng Conditinonal Formating để đánh dấu
- Bác giải thích việc không thống nhất và trùng quá nhiều mã khách hàng trong danh sách, Dosnet sẽ làm giúp bác, lọc cũng được mà đánh dấu cũng được. Thân !
 
Bạn thử xài macro sau:

vậy không giá trị nào đã trùng thì không muốn xuất hiện thì dùng như thế nào?
vi du A B C A D F E A C F ,muốn lọc ra chỉ có B D E thì làm sao?

PHP:
Option Explicit
Sub OnlyOne()
 Dim eRw As Long, Ff As Long:               Dim myAdd As String
 Dim Rng As Range, sRng As Range
 eRw = [A65500].End(xlUp).Row:            ReDim DaCo(2 To eRw) As Boolean
 For Ff = 2 To eRw
    Set Rng = Range("A" & Ff + 1 & ":A" & eRw)
    If Not DaCo(Ff) Then
        Set sRng = Rng.Find(what:=Cells(Ff, "A"), LookIn:=xlFormulas, lookat:=xlWhole)
        If Not sRng Is Nothing Then
            myAdd = sRng.Address
            If DaCo(sRng.Row) = False Then
                Do
                    DaCo(sRng.Row) = True
                    Set sRng = Rng.FindNext(sRng)
                Loop While Not sRng Is Nothing And sRng.Address <> myAdd
            End If
        Else
            [c65500].End(xlUp).Offset(1) = Cells(Ff, "A").Value
    End If:         End If
 Next Ff
End Sub
 
PHP:
Option Explicit
Sub OnlyOne()
 Dim eRw As Long, Ff As Long:               Dim myAdd As String
 Dim Rng As Range, sRng As Range
 eRw = [A65500].End(xlUp).Row:            ReDim DaCo(2 To eRw) As Boolean
 For Ff = 2 To eRw
    Set Rng = Range("A" & Ff + 1 & ":A" & eRw)
    If Not DaCo(Ff) Then
        Set sRng = Rng.Find(what:=Cells(Ff, "A"), LookIn:=xlFormulas, lookat:=xlWhole)
        If Not sRng Is Nothing Then
            myAdd = sRng.Address
            If DaCo(sRng.Row) = False Then
                Do
                    DaCo(sRng.Row) = True
                    Set sRng = Rng.FindNext(sRng)
                Loop While Not sRng Is Nothing And sRng.Address <> myAdd
            End If
        Else
            [c65500].End(xlUp).Offset(1) = Cells(Ff, "A").Value
    End If:         End If
 Next Ff
End Sub
Còn em thì khoái dùng COUNTIF trong trường hợp này hơn:
PHP:
Sub OnlyOne()
  Dim Clls As Range
  With Range([A2], [A65536].End(xlUp))
    For Each Clls In .SpecialCells(2, 23)
      If WorksheetFunction.CountIf(.Cells, Clls) = 1 Then
        [C65536].End(xlUp).Offset(1) = Clls
      End If
    Next
  End With
End Sub
 
From http://scriptorium.serve-it.nl/categories.php?eid=1&cid=11

1. Sử dụng Collection:

Mã:
Sub FilterUniqueNumbers()
    Dim rngYourrange As Range
    Dim rngCell As Range
    Dim colUniqueNumbers As New Collection
    Dim i As Integer

    ' Set the range that you want to filter for unique numbers
    Set rngYourrange = Worksheets(1).Range("A1:A10")

    ' Store the unique range values in the collection object. Note we use the
    ' range value converted to a string as the key value.
    On Error Resume Next
    For Each rngCell In rngYourrange
        colUniqueNumbers.Add rngCell.Value, CStr(rngCell.Value)
    Next rngCell

    ' Write each item from the collection object to column B in worksheet 1.
    For i = 1 To colUniqueNumbers.Count
        Worksheets(1).Cells(i, 2).Value = colUniqueNumbers(i)
    Next i
End Sub

2. Dùng AdvancedFilter:

Mã:
Sub FilterUniqueNumbers2()
    Dim rngDuplicates As Range
    Dim rngDestination As Range
    Dim rngCriteria As Range
    
    ' Filter entire column A, or use Range("A1:A10") or something to check only 10 rows.
    Set rngDuplicates = ThisWorkbook.Worksheets(1).Range("A:A")


    Set rngDestination = ThisWorkbook.Worksheets(1).Range("B1")
    Set rngCriteria = ThisWorkbook.Worksheets(1).Range("C1:C5")

    rngDuplicates.AdvancedFilter Action:=xlFilterCopy, CriteriaRange:=rngCriteria, _
            CopyToRange:=rngDestination, Unique:=True
End Sub

3. Dùng scripting.dictionary:

Mã:
Sub FilterUniqueNumbers3()
    Dim vValue As Variant, vVals As Variant
    Dim myRange As Range
    Dim i As Long
    Dim dArr() As Double
    Dim oDic As Object
    
    Set myRange = Worksheets(1).Range("A1:A10")

    'The Dictionary object is always present in Windows so it can always be created
    Set oDic = CreateObject("scripting.dictionary")
    oDic.comparemode = vbTextCompare

    'Read the values from a range into vVals
    vVals = myRange.Value

    'ReDim dArr and make it two dimensional by adding the second argument 1 To 1
    'otherwise you can't dump it in a worksheet later.
    ReDim dArr(UBound(vVals) - 1, 1 To 1)
    
    For Each vValue In vVals
        'Note the use of the Dictionary object to exclude double values
        If Not IsEmpty(vValue) And Not oDic.exists(vValue) Then
            dArr(i, 1) = vValue
            oDic.Add vValue, Nothing
            i = i + 1
        End If
    Next vValue

    'Free memory by removing the Dictionary object and vVals from memory
    Set oDic = Nothing
    Erase vVals

    'Remove old data
    myRange.Clear

    'Dump dArr values in worksheet
    myRange.Resize(i).Value = dArr
End Sub

4. Viết Class module:

Mã:
Sub ExtractItems()

    Dim clsExtract As CUniqueItems
    Dim rngSel As Range, rngTar As Range
   
    Set clsExtract = New CUniqueItems
    Set rngSel = Selection
    Set rngTar = ThisWorkbook.Sheets("Sheet2").Range("A1")
   
    clsExtract.TheSelection = rngSel
    clsExtract.Target = rngTar
    clsExtract.ExtractUniques
   
End Sub

Option Explicit

' Class constants
Private Const msTAB As String = vbTab

' Class variables
Private mrSelection As Range
Private mrTarget As Range

' Class Properties
'   Selection
Property Get TheSelection() As Range
    Set TheSelection = mrSelection
End Property
Property Let TheSelection(rng As Range)
    Set mrSelection = rng
End Property

'   Target
Property Get Target() As Range
    Set targert = mrTarget
End Property
Property Let Target(rng As Range)
    ' The target can only be one cell, so if more than
    ' one cell is chosen, set the range to the
    ' upper leftmost cell.
    If rng.Count&gt; 1 Then
        Set mrTarget = rng.Cells(1, 1)
    Else
        Set mrTarget = rng
    End If
End Property

' Class methods

Sub ExtractUniques()
   
    ' Variable declarations
    Dim rngCell As Range
    Dim col As Collection
    Dim iColCnt As Integer, i As Integer
    Dim vValue As Variant
   
    ' Create a new collection.
    Set col = New Collection
   
    ' Get the number of columns in the range
    iColCnt = mrSelection.Columns.Count
    ' If the column count is greater than 1, resize it to 1 column.
    If iColCnt&gt; 1 Then Set mrSelection = mrSelection.Resize(, 1)
   
    ' Turn off updating.
    Application.ScreenUpdating = False

    ' Add each unique item to the collection.
    For Each rngCell In mrSelection.Cells
        vValue = ""
        ' If the column count is great than one, add the whole
        ' row of data in teh selected range. We'll split it out
        ' later.
        If iColCnt&gt; 1 Then
            For i = 0 To iColCnt - 1
                ' Add all the data from the selected rows to the variable,
                ' separating them by a tab.
                vValue = vValue &amp; rngCell.Offset(0, i).Value &amp; msTAB
            Next i
        Else
            vValue = rngCell.Value
        End If
        ' Temporarily turn off error handling.
        On Error Resume Next
        ' Add to the collection.
        col.Add CStr(vValue), CStr(vValue)
        ' Turn error handling back on.
        On Error GoTo 0
    Next rngCell
   
    ' Write the data back out to the target.
    i = 1
    For i = 1 To col.Count
        mrTarget.Offset(i - 1, 0).Value = col(i)
    Next i
   
    ' If the selection column count is greater than 1,
    ' then convert the output text to multiple columns
    ' using text to columns.
    If iColCnt&gt; 1 Then
        mrTarget.Parent.Activate
        mrTarget.Select
        Range(Selection, Selection.Offset(col.Count - 1, 0)).Select
        Selection.TextToColumns Destination:=Range(Selection.Address), DataType:=xlDelimited, _
            TextQualifier:=xlDoubleQuote, ConsecutiveDelimiter:=False, Tab:=True, _
            Semicolon:=False, Comma:=False, Space:=False, Other:=False
    End If
   
    ' Turn on updating and kill the collection object.
    Application.ScreenUpdating = True
    Set col = Nothing
       
End Sub

5. Sử dụng Array:

Mã:
Sub enkel()
  Dim sq As Variant
  Dim j As Long
 
  If Selection.Columns.Count = 1 Then
    sq = Application.WorksheetFunction.Transpose(Selection.SpecialCells(xlCellTypeConstants))
    For j = 1 To UBound(sq)
      sq=split(replace("|" &amp; join(sq,"|") &amp; "|","|" &amp; sq(j) &amp; "|","") &amp; "|" &amp; sq(j),"|")
    Next
    Sheets(1).[K1].Resize(UBound(sq) + 1) = Application.WorksheetFunction.Transpose(sq)
  End If
End Sub

Lê Văn Duyệt
 
Ko biết đã có ai làm cuộc thí nghiệm xem thử trong tất cả các phương pháp lọc duy nhất thì phương pháp nào là nhanh nhất ko?
(cho đến hiện nay tôi chỉ biết Advanced Filter xem chừng là .. cực mạnh, ko biết còn món nào khác hơn nó ko nhỉ?)
 
To AnhTuan1066

Còn em thì khoái dùng COUNTIF trong trường hợp này hơn:
PHP:
Sub OnlyOne()
  Dim Clls As Range
  With Range([A2], [A65536].End(xlUp))
    For Each Clls In .SpecialCells(2, 23)
      If WorksheetFunction.CountIf(.Cells, Clls) = 1 Then
        [C65536].End(xlUp).Offset(1) = Clls
      End If
    Next
  End With
End Sub
Bình thường thì code của bạn nhanh gấp đôi của mình! Một khi rất ít ký tự trong cột trùng nhau
Nhưng trong trường hợp rất nhiều các ký tự lặp lại nhiều lần, thì code của mình với FINDNEXT & biến loại trừ tỏ ra nước rút gấp 7 lần của bạn kia đó!
 
Trích lọc danh sách duy nhất cho Validaton

Em có vấn đề này từ lâu muốn hỏi +-+-+-+.
Có cách nào đưa một danh sách duy nhất vào validation không các anh ?
Không dùng cột phụ & ko VBA .
em có kẻm File ví dụ ,nhưng đang dùng cột phụ .
File này em tìm trong loạt bài viết của anh Ndu;;;;;;;;;;; hi hi
Em cám ơn.
 

File đính kèm

Em có vấn đề này từ lâu muốn hỏi +-+-+-+.
Có cách nào đưa một danh sách duy nhất vào validation không các anh ?
Không dùng cột phụ & ko VBA .
em có kẻm File ví dụ ,nhưng đang dùng cột phụ .
File này em tìm trong loạt bài viết của anh Ndu;;;;;;;;;;; hi hi
Em cám ơn.
Có thể trả lời bạn ngay là KHÔNG CÓ CÁCH
Validation chỉ chấp nhận List là 1 VÙNG CÓ THẬT trên bảng tính ---> Không chấp nhận Range do công thức "chế tác" ra
---> Tuy nhiên cái file của bạn có thể chỉnh lại còn 1 cột phụ thì được
 

File đính kèm

Lần chỉnh sửa cuối:
Theo ý của bạn ko dùng cột phụ là sao?(có phải cột chứa dữ liệu, từ cột đó bạn đặt tên cho nó, sau đó cột đó được dùng để lấy nội dung của nó hiện trong list các giá trị mà bạn lấy trong cell mà bạn muốn validation hả?)
Nếu như vậy thì rất khó. vì phải có một nguồn nào đó bạn mới lấy được list chứ, nếu ko dùng list chỉ dùng để nhập các điều kiện logic (vd< 5 chẳng hạn)
 
Em có vấn đề này từ lâu muốn hỏi +-+-+-+.
Có cách nào đưa một danh sách duy nhất vào validation không các anh ?
Không dùng cột phụ & ko VBA .
em có kẻm File ví dụ ,nhưng đang dùng cột phụ .
File này em tìm trong loạt bài viết của anh Ndu;;;;;;;;;;; hi hi
Em cám ơn.

Xem có vừa ý không? (1 cột phụ)
 

File đính kèm

Lần chỉnh sửa cuối:
Theo ý của bạn ko dùng cột phụ là sao?(có phải cột chứa dữ liệu, từ cột đó bạn đặt tên cho nó, sau đó cột đó được dùng để lấy nội dung của nó hiện trong list các giá trị mà bạn lấy trong cell mà bạn muốn validation hả?)
Nếu như vậy thì rất khó. vì phải có một nguồn nào đó bạn mới lấy được list chứ, nếu ko dùng list chỉ dùng để nhập các điều kiện logic (vd< 5 chẳng hạn)

Dùng cột phụ thì mình nghỉ ra ,củng sử dụng cách trích lọc duy nhất rồi đưa vào list .
Mình nghỉ tại mình làm ko được thôi ,chứ với các Pro thì sẽ làm được hi hi
Cám ơn bạn nhe .
 
Mình làm thế này không cần dùng cột phụ, tuy nhiên phai nhập thủ công. Với danh sách dài như của bạn cũng khá vất vả đấy. Chỉ đơn giản là trong mục source nhập dự liệu đầu vào các dữ liệu ngăn cách nhau bởi dấu ,
 
Lần chỉnh sửa cuối:
Mình làm thế này không cần dùng cột phụ, tuy nhiên phai nhập thủ công. Với danh sách dài như của bạn cũng khá vất vả đấy. Chỉ đơn giản là trong mục source nhập dự liệu đầu vào các dữ liệu ngăn cách nhau bởi dấu ,
Cách này không được, vì nếu nhập trực tiếp, Excel chỉ cho phép nhập với số lượng ký tự có hạn mà thôi
 
Mình làm thế này không cần dùng cột phụ, tuy nhiên phai nhập thủ công. Với danh sách dài như của bạn cũng khá vất vả đấy. Chỉ đơn giản là trong mục source nhập dự liệu đầu vào các dữ liệu ngăn cách nhau bởi dấu ,

Cái này thì nói chi ,nếu dử liệu nhiều quá thì củng bó tay .Mình hỏi coi có cách nào tối ưu hơn ko thôi ,Cái này dùng cột phụ như các anh ndu,anh boyxin là ok rồi .
 
Cái này thì nói chi ,nếu dử liệu nhiều quá thì củng bó tay .Mình hỏi coi có cách nào tối ưu hơn ko thôi ,Cái này dùng cột phụ như các anh ndu,anh boyxin là ok rồi .
Khẳng định với bạn rằng: Cho đến thời điểm hiện nay, với Office hiện nay là KHÔNG CÓ CÁCH NÀO KHÁC... kể cả VBA (nếu không dùng cột phụ)
Vì bản chất của Validation nó vậy, chỉ "công nhận" 1 List có thật
Hy vọng các Version sau này, 2010 hoặc trên nữa sẽ đáp ứng yêu cầu của bạn
Ẹc... Ẹc...
(cái này đã từng thử và đã từng hỏi trên diển đàn lâu lắm rồi)
 
Web KT

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

Back
Top Bottom