Đếm số phần tử (duy nhất) có trong Dropdown list khi AutoFilter (2 người xem)

Liên hệ QC

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

ndu96081631

Huyền thoại GPE
Thành viên BQT
Super Moderator
Tham gia
5/6/08
Bài viết
30,703
Được thích
53,958
- Giã sử tôi có vùng dử liệu A1:D20 (với dòng 1 là tiêu đề)
- Tôi AutoFilter cho vùng này và khi tôi bấm vào Dropdown button tại cột A thì sẽ nhìn thấy 1 danh sách duy nhất trong đó
Vậy xin hỏi:
Bằng cách nào có thể đếm được số lượng phần tử duy nhất trong Dropdown list ấy nếu như:
- Không dùng công thức đếm duy nhất (SUMPRODUCT(1/COUNTIF..... )
- Không dùng Advanced Filter để lọc ra 1 cột phụ
 
- Giã sử tôi có vùng dử liệu A1:D20 (với dòng 1 là tiêu đề)
- Tôi AutoFilter cho vùng này và khi tôi bấm vào Dropdown button tại cột A thì sẽ nhìn thấy 1 danh sách duy nhất trong đó
Vậy xin hỏi:
Bằng cách nào có thể đếm được số lượng phần tử duy nhất trong Dropdown list ấy nếu như:
- Không dùng công thức đếm duy nhất (SUMPRODUCT(1/COUNTIF..... )
- Không dùng Advanced Filter để lọc ra 1 cột phụ
Dùng hàm subtotal(3,...) được không.

Sorry, do không đọc kỹ yêu cầu, chắc phải dùng for each thôi. Cũng mệt nhỉ. Bác tự làm khó nữa.
 
Upvote 0
Dùng hàm subtotal(3,...) được không.
Được... nhưng dùng sao? ThuNghi cho xin code với

Ah... xin nói thêm ý đồ:
Ý tôi là muốn tạo 1 vòng lập For để Filter xuyên qua hết tất cả các Unique Record có trong 1 cột nào đó
Ví dụ:
- Cột A có A1 là tiêu đề
- Từ A2 đến A20 có giá trị là "A", "B", và "C" (các giá trị này đương nhiên bị trùng ở 1 vài cell nào đó)
- Tôi muốn tạo 1 vòng lập For để Filter xuyên qua các giá trị "A", "B" và "C" ... Có nghĩa là A2:A20 có tổng cộng 19 cells nhưng For chỉ làm việc 3 lần
Đại khái là vậy!
Xin các cao thủ chỉ giúp... Hiện giờ tôi phải làm bằng cách thông qua Advanced Filter lọc Unique Record Only ra 1 cột phụ rồi mới AutoFilter theo điều kiện của cột phụ này (dài dòng quá)
 
Chỉnh sửa lần cuối bởi điều hành viên:
Upvote 0
Ah... xin nói thêm ý đồ:
Ý tôi là muốn tạo 1 vòng lập For để Filter xuyên qua hết tất cả các Unique Record có trong 1 cột nào đó
Ví dụ:
- Cột A có A1 là tiêu đề
- Từ A2 đến A20 có giá trị là "A", "B", và "C" (các giá trị này đương nhiên bị trùng ở 1 vài cell nào đó)
- Tôi muốn tạo 1 vòng lập For để Filter xuyên qua các giá trị "A", "B" và "C" ... Có nghĩa là A2:A20 có tổng cộng 19 cells nhưng For chỉ làm việc 3 lần
Đại khái là vậy!
Xin các cao thủ chỉ giúp... Hiện giờ tôi phải làm bằng cách thông qua Advanced Filter lọc Unique Record Only ra 1 cột phụ rồi mới AutoFilter theo điều kiện của cột phụ này (dài dòng quá)
Hiểu như thế này có OK.
- Set MyRng= invisible
- If RyRng.rows.count>0 then
- MyRng=find(MyRng(1).....hiden=true (mỗi lần gặp Ai là hide sau đó tiếp tục)
- Set lại khi nào không còn cái gì hiện là OK.
 
Upvote 0
Câu hỏi của tôi có liên quan đến bài này:
http://www.giaiphapexcel.com/forum/showthread.php?t=15775
ThuNghi xem bài số #5 là hiểu liền... Bài đó tôi dùng Find
Giờ tôi đưa 1 giãi pháp khác dùng AutoFilter lên nha:
PHP:
Option Explicit
Sub Loc()
 Dim Rng As Range, Dk As Range, Clls As Range
 Dim i As Long
 [M4].CurrentRegion.ClearContents
 Set Rng = [B4].CurrentRegion
 Rng.Resize(, 1).AdvancedFilter 2, , [K4], True
 Set Dk = [K4].CurrentRegion
 With Rng
   Cells(4, 13).Resize(, .Columns.Count) = Rng.Resize(1).Value
   For Each Clls In Dk.Resize(, 1).Offset(1).SpecialCells(2, 23)
      .AutoFilter 1, Clls
      With .Offset(1).SpecialCells(12).Areas(1).Resize(1)
        Cells(5 + i, 13).Resize(, .Columns.Count) = .Value: i = i + 1
      End With
   Next
 End With
 Sheet1.AutoFilterMode = False
 Dk.Clear
End Sub
Bài này tôi phải dùng cột K làm cột phụ nên cãm thấy nó tệ quá... Chính vì lẽ đó mà tôi có ý tương: "Liệu có liệu AutoFilter xuyên qua tất cả các Record mà ta nhìn thấy khi bấm Dropdown list tại 1 cột không"
 

File đính kèm

Upvote 0
Ah... xin nói thêm ý đồ:
Ý tôi là muốn tạo 1 vòng lập For để Filter xuyên qua hết tất cả các Unique Record có trong 1 cột nào đó
Ví dụ:
- Cột A có A1 là tiêu đề
- Từ A2 đến A20 có giá trị là "A", "B", và "C" (các giá trị này đương nhiên bị trùng ở 1 vài cell nào đó)
- Tôi muốn tạo 1 vòng lập For để Filter xuyên qua các giá trị "A", "B" và "C" ... Có nghĩa là A2:A20 có tổng cộng 19 cells nhưng For chỉ làm việc 3 lần
Đại khái là vậy!
Xin các cao thủ chỉ giúp... Hiện giờ tôi phải làm bằng cách thông qua Advanced Filter lọc Unique Record Only ra 1 cột phụ rồi mới AutoFilter theo điều kiện của cột phụ này (dài dòng quá)

Nếu chỉ đếm số phần tử :

Bác thử xem nhé : Match nhanh không kém Find đâu

PHP:
Function SoPT(MangDL As Range) As Long
    On Error Resume Next
    Dim i As Long
    If MangDL.Rows.Count < 1 Then Exit Function
    For i = 1 To MangDL.Rows.Count
        If TimRow(MangDL(i), MangDL) = i Then SoPT = SoPT + 1
    Next
End Function


PHP:
Function TimRow(Ma As Variant, Mang As Range) As Long
    On Error Resume Next
    TimRow = WorksheetFunction.Match(Ma, Mang, 0)
End Function


Hai UDF này có thể gộp thành 1, tuy nhiên em muốn tách rời cho dễ xử lý.

Thân!
 

File đính kèm

Upvote 0
Nếu chỉ đếm số phần tử :

Bác thử xem nhé : Match nhanh không kém Find đâu

PHP:
Function SoPT(MangDL As Range) As Long
    On Error Resume Next
    Dim i As Long
    If MangDL.Rows.Count < 1 Then Exit Function
    For i = 1 To MangDL.Rows.Count
        If TimRow(MangDL(i), MangDL) = i Then SoPT = SoPT + 1
    Next
End Function
PHP:
Function TimRow(Ma As Variant, Mang As Range) As Long
    On Error Resume Next
    TimRow = WorksheetFunction.Match(Ma, Mang, 0)
End Function
Hai UDF này có thể gộp thành 1, tuy nhiên em muốn tách rời cho dễ xử lý.

Thân!
Cãm ơn Mr Okebab (hoàn toàn đồng ý dùng MATCH trong trường hợp này rất nhanh)
Thực tế lúc đầu tôi nghĩ có thể trong AutoFilter Method có chức năng đếm Unique gì đó (mà mình chưa biết cách viết code)... Và tôi suy luận rằng nếu như nó đếm được thì đương nhiên nó hoàn toàn có thể truy xuất xuyên qua từng phần tử ấy...
Nghĩ vậy nên tôi đã ghi chủ đề là: Đếm số phần tử (duy nhất) có trong Dropdown list khi AutoFilter
Thật ra mục đích cuối cùng không phải là ĐẾM mà là TRUY XUẤT (giống như cách làm trong file đính kèm)
Chẳng lẽ không có cách khác sao ta?
 
Upvote 0
ndu thử đoạn này xem có đúng ý không (tôi chỉ làm mỗi đoạn này thôi)?



PHP:
Dim Rng As Range, Dk As Range, Clls As Range
  Dim i As Long, n As Long
  Dim DiaChi(1 To 100) As Variant, GiaTri(1 To 100) As Variant
  Set Dk = [B4].CurrentRegion.Resize(, 1)
  Dk.AdvancedFilter 1, , , True
  n = 0
  'Doan nay la de xac dinh DiaChi va GiaTri loc :
  'Them vao DiaChi voi muc dich kiem tra, khong can thi bo di :
  For Each Clls In Dk.SpecialCells(xlCellTypeVisible)
      n = n + 1
      DiaChi(n) = Clls.Address
      GiaTri(n) = Clls
  Next
  'Doan duoi day la de kiem tra ket qua :
  For i = 1 To n  'n la so phan tu loc duoc
      MsgBox DiaChi(i)
      MsgBox GiaTri(i)
  Next i
 
Upvote 0
ndu thử đoạn này xem có đúng ý không (tôi chỉ làm mỗi đoạn này thôi)?



PHP:
Dim Rng As Range, Dk As Range, Clls As Range
  Dim i As Long, n As Long
  Dim DiaChi(1 To 100) As Variant, GiaTri(1 To 100) As Variant
  Set Dk = [B4].CurrentRegion.Resize(, 1)
  Dk.AdvancedFilter 1, , , True
  n = 0
  'Doan nay la de xac dinh DiaChi va GiaTri loc :
  'Them vao DiaChi voi muc dich kiem tra, khong can thi bo di :
  For Each Clls In Dk.SpecialCells(xlCellTypeVisible)
      n = n + 1
      DiaChi(n) = Clls.Address
      GiaTri(n) = Clls
  Next
  'Doan duoi day la de kiem tra ket qua :
  For i = 1 To n  'n la so phan tu loc duoc
      MsgBox DiaChi(i)
      MsgBox GiaTri(i)
  Next i
Ôi chao... tôi hiểu rồi... Cực kỳ tuyệt vời luôn!
Thì ra thuật toán nằm ở chổ Filter the list, in-place + Unique Records Only
Vậy thì cuối cùng đoạn code củ chuối dài lê thê kia có thể rút gọn lại thành:
PHP:
Option Explicit
Sub Loc()
 Dim Rng As Range
 [M4].CurrentRegion.ClearContents
 Set Rng = [B4].CurrentRegion
 Rng.Resize(, 1).AdvancedFilter 1, , , True
 Rng.SpecialCells(12).Copy Destination:=[M4]
 ActiveSheet.ShowAllData
End Sub
Vậy mà tôi đi giãi quyết lòng vòng.. NGU thật
Cãm ơn bạn rất nhiều
 

File đính kèm

Upvote 0
Vậy bác có cách nào lọc 1 mảng ảo không. Ví dụ mảng arr() có các giá trị như (1,2,3,2,3,4,7,8,1) Và kết quả cho ra mng() có giá trị là (1,2,3,4,7,8). Em đang cần. Thân.
 
Lần chỉnh sửa cuối:
Upvote 0
Vậy bác có cách nào lọc 1 mảng ảo không. Ví dụ mảng arr() có các giá trị như (1,2,3,2,3,4,7,8,1)
Và kết quả cho ra mng() có giá trị là (1,2,3,4,7,8).
Em đang cần.
Thân.
Cái này chắc phải nhở các cao thủ khác (tôi không rành về mãng)
Nhớ không lầm nó đã có trên diển đàn rồi... Bạn tìm thử xem
 
Upvote 0
Em tìm thấy mảng thì nhiều nhưng chưa thấy có bài nào viết về lọc nghiệm duy nhất trong mảng cả! Bác tìm dùm em đi. Thân.
 
Lần chỉnh sửa cuối:
Upvote 0
Lọc duy nhất trên 1 field

Ôi chao... tôi hiểu rồi... Cực kỳ tuyệt vời luôn!
Thì ra thuật toán nằm ở chổ Filter the list, in-place + Unique Records Only
Vậy thì cuối cùng đoạn code củ chuối dài lê thê kia có thể rút gọn lại thành:
PHP:
Option Explicit
Sub Loc()
 Dim Rng As Range
 [M4].CurrentRegion.ClearContents
 Set Rng = [B4].CurrentRegion
 Rng.Resize(, 1).AdvancedFilter 1, , , True
 Rng.SpecialCells(12).Copy Destination:=[M4]
 ActiveSheet.ShowAllData
End Sub
Vậy mà tôi đi giãi quyết lòng vòng.. NGU thật
Cãm ơn bạn rất nhiều


Cho tôi hỏi: Tại sao phải mất công lọc in-place, rồi lại mất công Copy??? Sao không lọc và copy 1 lần luôn thể? Bạn xem đoạn mã lọc lấy danh sách duy nhất trên 1 field của tôi có thể dùng được không nhé:

PHP:
Sub advFilter()
Dim ra As Range, sh As Worksheet
Dim addr
Dim ro As Long
    On Error Resume Next
    Set ra = Selection
    If ra.Cells.Count = 1 Then
        Set ra = Range(ra.End(xlUp), ra.End(xlDown))
    End If
    Set addr = Application.InputBox(prompt:="Chon vung chua du lieu loc", Title:="Copy Data", Type:=8)
    Application.ScreenUpdating = False
    ra.AdvancedFilter Action:=xlFilterCopy, CopyToRange:=addr, Unique:=True
    ra.Parent.AutoFilterMode = False
    Application.ScreenUpdating = True
 
End Sub

-hvl-
 
Lần chỉnh sửa cuối:
Upvote 0
Cho tôi hỏi: Tại sao phải mất công lọc in-place, rồi lại mất công Copy??? Sao không lọc và copy 1 lần luôn thể? Bạn xem đoạn mã lọc lấy danh sách duy nhất trên 1 field của tôi có thể dùng được không nhé:

PHP:
Sub advFilter()
Dim ra As Range, sh As Worksheet
Dim addr
Dim ro As Long
    On Error Resume Next
    Set ra = Selection
    If ra.Cells.Count = 1 Then
        Set ra = Range(ra.End(xlUp), ra.End(xlDown))
    End If
    Set addr = Application.InputBox(prompt:="Chon vung chua du lieu loc", Title:="Copy Data", Type:=8)
    Application.ScreenUpdating = False
    ra.AdvancedFilter Action:=xlFilterCopy, CopyToRange:=addr, Unique:=True
    ra.Parent.AutoFilterMode = False
    Application.ScreenUpdating = True
 
End Sub
-hvl-
Hình như không được!
Yêu cầu bài toán trên là:
- Giã sử vùng dử liệu là B4:H30
- Tìm trong cột đầu tiên (cột B) rồi lấy ra những phần tử duy nhất cùng tất cả các dử liệu khác cùng dòng với nó sang 1 nơi khác
Nghĩa là gần giống với Advanced Filter\Unique Only chứ không phải vậy!
Ví dụ:
- Cột B có các dử liệu là 1, 2 và 3 nằm lộn xộn từ B4 đến B30
- Yêu cầu lấy 3 dòng bất kỳ với cột đầu có chứa 1, 2 và 3
- Copy nó sang nơi khác
Vậy cuối cùng thì kết quả thu được chỉ có 3 dòng
Bạn điền code của mình vào file tôi rồi chạy 2 code ---> So sánh kết quả tự nhiên hiểu được yêu cầu ngay!
Tóm lại: Chỉ lọc duy nhất trên 1 cột nào đó (chứ không phải lọc duy nhất cả bãng)
 
Upvote 0
To: Po_Pikachu,

Em chịu khó Google với Unique array + VBA

Em sẽ tìm được nhiều lắm.

Lê Văn Duyệt
 
Upvote 0
Em nghĩ là bác muốn em tìm hai trang này! Nhưng không biết làm với hàm mảng cũng được chứ bác? http://my.opera.com/levanduyet/blog/show.dml/1773594 http://www.webketoan.vn/forum/showthread.php?t=11792 Cảm ơn bác nha! Thân. Nhưng code này thật là không biết dùng làm sao nhỉ? Có vài tham số bác đặt biến khó hiểu quá?
PHP:
Option Explicit  Sub RemoveDuplicates()     Dim AllCells As Range, Cell As Range     Dim NoDupes As New Collection     Dim i As Integer, j As Integer     Dim Swap1, Swap2, Item     ' Các pha^`n tu+? trong khoa?ng A1:A11    Set AllCells = Range("A1:A11")     ' Đây chính là phần kỹ thuật mà tôi giải thích ở trên    On Error Resume Next     For Each Cell In AllCells        NoDupes.Add Cell.Value, CStr(Cell.Value)        ' Chú ý: thông số thứ hai của phương thức trên phải là dạng chuổi    Next Cell     ' Bẫy lỗi    On Error GoTo 0     ' Sắp xếp tập hợp trước khi đưa vào ListBox    For i = 1 To NoDupes.Count - 1        For j = i + 1 To NoDupes.Count           If NoDupes(i) > NoDupes(j) Then              Swap1 = NoDupes(i)              Swap2 = NoDupes(j)              NoDupes.Add Swap1, before:=j              NoDupes.Add Swap2, before:=i              NoDupes.Remove i + 1              NoDupes.Remove j + 1           End If        Next j     Next i     ' Đưa các phần tử đã sắp xếp vào ListBox    For Each Item In NoDupes        UserForm1.ListBox1.AddItem Item     Next Item     ' Cho hiện form người dùng    UserForm1.Show  End Sub
 
Lần chỉnh sửa cuối:
Upvote 0
Gửi thử 1 hàm lọc mảng, Po_Pikachu xem sao nhé:

PHP:
Function arrFilter(ParamArray ra()) As Variant
Const hvl = "hvl"
Dim i As Long, c As Long, uB As Long
Dim ar(), kq()
Dim st As Variant, s As Variant
    
    ReDim ar(1 To 1)
    ' DDo.c du+~ lie^.u tu+` range va`o bie^'n ma?ng
    For i = LBound(ra) To UBound(ra)
        If TypeName(ra(i)) = "Range" Then
            uB = UBound(ar)
            k = IIf(uB = 1, 0, uB)
            c = ra(i).Cells.Count
            ReDim Preserve ar(1 To (k + c))
            For j = 1 To c
                ar(k + j) = ra(i).Cells(j)
            Next
        End If
    Next
            uB = UBound(ar)
            ReDim kq(1 To uB)
            n = 0
            For i = 1 To uB - 1
                If ar(i) <> hvl Then
                    n = n + 1
                    kq(n) = ar(i)
                    For j = i + 1 To uB
                        If ar(j) = ar(i) Then ar(j) = hvl
                    Next
                End If
            Next
    ReDim Preserve kq(1 To n)
    arrFilter = kq
            
End Function

-hvl-
 
Upvote 0
Vì là hàm cho ra kết quả là 1 mảng, cho nên muốn dùng trong sheet thì phải nhập hàm theo kiểu mảng (Ctrl-Shift-Enter)
Nếu dùng để khai thác công việc thì cách dùng là:

dim a as Variant
a= arrFilter(range)
sau đó có thể dùng như kiểu: a(1) để lấy phần tử thứ 1...

-hvl-
 
Upvote 0
Cảm ơn bạn nhiều nha! Dùng trong code thì chạy tốt. Còn Ctr - Shift - Enter thì nó chạy không đúng, nó chỉ ra số đầu tiên thôi. Thân.
 
Lần chỉnh sửa cuối:
Upvote 0
Cảm ơn bạn nhiều nha!
Dùng trong code thì chạy tốt. Còn Ctr - Shift - Enter thì nó chạy không đúng, nó chỉ ra số đầu tiên thôi.
Thân.

Mảng có bao nhiêu phần tử thì bạn phải chọn bấy nhiêu phần tử (hoặc nhiếu hơn), nhập công thức vào ô đầu tiên và nhấn Ctrl + Alt + Enter
Việc lọc và sắp xếp theo mảng thì SA tiên sinh có những giải thuật cực hay, ngắn gọn. Bạn nên tìm hiểu nhé.

Thân!
 
Upvote 0
Web KT

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

Back
Top Bottom