Trích lọc danh sách duy nhất trong danh sách có chứa dòng rỗng (9 người xem)

Liên hệ QC

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

anhtuan1066

Thành viên gạo cội
Tham gia
10/3/07
Bài viết
5,802
Được thích
6,912
Như ta đã biết, để lấy dc danh sách duy nhất trong 1 danh sách có sẳn, người ta thường dùng Advanced Filter\Unique Only...
Thế nhưng tôi thí nghiệm và nhận xét rằng: Nếu danh sách có chứa dòng rổng thì danh sách dc trích ra cũng có chứa dòng rổng luôn...
Vậy xin hỏi các cao thủ giãi pháp nào để loại bỏ luôn các dòng rổng này
ANH TUẤN
 

File đính kèm

anhtuan1066 đã viết:
Như ta đã biết, để lấy dc danh sách duy nhất trong 1 danh sách có sẳn, người ta thường dùng Advanced Filter\Unique Only...
Thế nhưng tôi thí nghiệm và nhận xét rằng: Nếu danh sách có chứa dòng rổng thì danh sách dc trích ra cũng có chứa dòng rổng luôn...
Vậy xin hỏi các cao thủ giãi pháp nào để loại bỏ luôn các dòng rổng này
ANH TUẤN

Thế có được dùng hàm mảng của VBA không bác ???
Thân!
 
Tất nhiên cách gì tùy ý, vì tôi đang nói đến chức năng Advanced Filter mà...
Tôi đang nghĩ đến hướng Sort Non Blank qua cột phụ, rồi sẽ Filter theo cột phụ này.. cuối cùng xóa cột phụ đi...
Giã sử ta đã định nghĩa trong Define name cái danh sách gốc ấy là DS, thì tôi tạm thời đang làm như sau:
PHP:
Sub Filter_Unique()
    Application.ScreenUpdating = False
    Set DS = Range("DS")
    Set St = Cells(DS.Row, DS.Column + 2)
    Set DS1 = DS.Offset(0, 1)
    Set DS2 = DS.Offset(0, 2)
    DS2.ClearContents
    DS.AutoFilter Field:=1, Criteria1:="<>"
    DS.SpecialCells(xlCellTypeVisible).Copy
    DS1.PasteSpecial (xlPasteValues)
    Selection.AdvancedFilter Action:=xlFilterCopy, CopyToRange:=DS2, Unique:=True
    Selection.ClearContents
    DS2.Sort Key1:=St, Order1:=xlAscending, Header:=xlGuess
    St.Select
    Application.ScreenUpdating = True
End Sub
Nhưng thế dở quá... vì nếu người dùng ko biết tùy biến, lọc nhầm vào cột đang chứa dử liệu thì toi...
Bắp nghĩ thử xem có cách nào khác hơn ko?
ANH TUẤN
 
anhtuan1066 đã viết:
Tất nhiên cách gì tùy ý, vì tôi đang nói đến chức năng Advanced Filter mà...
Tôi đang nghĩ đến hướng Sort Non Blank qua cột phụ, rồi sẽ Filter theo cột phụ này.. cuối cùng xóa cột phụ đi...
Giã sử ta đã định nghĩa trong Define name cái danh sách gốc ấy là DS, thì tôi tạm thời đang làm như sau:
.............
Nhưng thế dở quá... vì nếu người dùng ko biết tùy biến, lọc nhầm vào cột đang chứa dử liệu thì toi...
ANH TUẤN

Thế thì a để hẳn kết quả sang sheet mới lun, như thế là tổng quan hơn vì thường --> mọi ng đều có nhu cầu giữ nguyên hiện trạng dữ liệu lại,
bb
 
Cảm ơn Tigertiger, cách ấy cũng dc... Nhưng liệu còn cách nào khác hơn nữa ko, ngoài cách dùng côt phụ
ANH TUẤN
 
anhtuan1066 đã viết:
Cảm ơn Tigertiger, cách ấy cũng dc... Nhưng liệu còn cách nào khác hơn nữa ko, ngoài cách dùng côt phụ
ANH TUẤN

Dùng mảng trong VBA, xửa lý xong chỉ cần trích xuất ra là xong.

Bác muốn trích xuất ra cột khác hay trên chính nó ??

Thân!
 
Nhở Bắp làm giùm cách ko dùng cột phụ nhé, miển trích sang hẳn 1 cột khác nằm trong sheet ấy hoặc sheet khác...
ANH TUẤN
 
Tranh chổ của BAP cái, nha.

anhtuan1066 đã viết:
Nhở Bắp làm giùm cách ko dùng cột phụ nhé, miển trích sang hẳn 1 cột khác nằm trong sheet ấy hoặc sheet khác...
ANH TUẤN

PHP:
Option Explicit:                         Option Base 1
Function SortMatrix(Rng As Range, Optional Dess As Boolean)
 Dim Mang, Temp, iJ As Integer, iZ As Integer
 Mang = Rng
 SortMatrix = Rng.Rows.Count
 ReDim MDLieu(SortMatrix, 1)
1 '. Sap Xep Danh Sach'
 For iZ = 1 To SortMatrix
    For iJ = 1 To SortMatrix - 1
        Temp = Mang(iJ, 1)
        If Temp > Mang(iJ + 1, 1) Then
            Mang(iJ, 1) = Mang(iJ + 1, 1)
            Mang(iJ + 1, 1) = Temp
        End If
 Next iJ, iZ
2 '. Lap Danh Sach Duy Nhat'
 iZ = 0:                            Temp = ""
 For iJ = 1 To SortMatrix
    If Temp <> Mang(iJ, 1) Then
        iZ = 1 + iZ:                Temp = Mang(iJ, 1)
        MDLieu(iZ, 1) = Temp
    End If
 Next iJ
 For iJ = iZ + 1 To SortMatrix
    MDLieu(iJ, 1) = ""
 Next iJ
 SortMatrix = MDLieu
End Function
Cách dùng hàm mảng như sau:
VD ta có danh sách tên gồm hơn chục người, có trùng & cả ô trống tại cột 'B' từ B1:B30;
Quét chọn vùng tương ứng tại sheets đó hay sheets khác; nhập hàm trên & kết thúc bằng tổ hợp 3 phím như những hàm mảng khác của excel!
Kết quả cũng xếp trật tự cho chúng ta luôn!
 
SA_DQ đã viết:
PHP:
Option Explicit:                         Option Base 1
Function SortMatrix(Rng As Range, Optional Dess As Boolean)
 Dim Mang, Temp, iJ As Integer, iZ As Integer
 Mang = Rng
 SortMatrix = Rng.Rows.Count
 ReDim MDLieu(SortMatrix, 1)
1 '. Sap Xep Danh Sach'
 For iZ = 1 To SortMatrix
    For iJ = 1 To SortMatrix - 1
        Temp = Mang(iJ, 1)
        If Temp > Mang(iJ + 1, 1) Then
            Mang(iJ, 1) = Mang(iJ + 1, 1)
            Mang(iJ + 1, 1) = Temp
        End If
 Next iJ, iZ
2 '. Lap Danh Sach Duy Nhat'
 iZ = 0:                            Temp = ""
 For iJ = 1 To SortMatrix
    If Temp <> Mang(iJ, 1) Then
        iZ = 1 + iZ:                Temp = Mang(iJ, 1)
        MDLieu(iZ, 1) = Temp
    End If
 Next iJ
 For iJ = iZ + 1 To SortMatrix
    MDLieu(iJ, 1) = ""
 Next iJ
 SortMatrix = MDLieu
End Function
Cách dùng hàm mảng như sau:
VD ta có danh sách tên gồm hơn chục người, có trùng & cả ô trống tại cột 'B' từ B1:B30;
Quét chọn vùng tương ứng tại sheets đó hay sheets khác; nhập hàm trên & kết thúc bằng tổ hợp 3 phím như những hàm mảng khác của excel!
Kết quả cũng xếp trật tự cho chúng ta luôn!
Bác nhanh thật, cái SortMatrix của bác vẫn luôn khiến em khâm phục về giải thuật.
Của em thì cũng tương tự, nếu thêm thắt thì tạo thành 1 Sub để chỉ có giá trị thôi!!

Đây là File của Sa tiên sinh!

Bác anhtuan có thể theo dõi tại đây:
http://www.giaiphapexcel.com/forum/showthread.php?t=5350

Thân!
 

File đính kèm

Tôi xin tham gia một chút. Công nhận cách của bác SA_DQ rất hay. Tuy nhiên tôi cũng có thể lọc được danh sách bằng cách là sắp xếp nó lại rồi sau đó dung Advanced Filter. Không biết có đúng ý của bác anhtuan1066 không????
Trong file tôi gửi kèm, bác chọn vùng cần sắp xếp, sau đó nhấn nút Sắp xếp DS duy nhất là được.
 

File đính kèm

minhlev đã viết:
Tôi xin tham gia một chút. Công nhận cách của bác SA_DQ rất hay. Tuy nhiên tôi cũng có thể lọc được danh sách bằng cách là sắp xếp nó lại rồi sau đó dung Advanced Filter. Không biết có đúng ý của bác anhtuan1066 không????
Trong file tôi gửi kèm, bác chọn vùng cần sắp xếp, sau đó nhấn nút Sắp xếp DS duy nhất là được.

  1. Việc làm = VBA thì có rất nhiều cách, có thể bằng Function hoặc Sub, vì vậy không ngạc nhiên khi sẽ có nhiều lời giải khác nhau.
  2. Chạy File của bác thì phải đặt con trỏ ở đâu vậy ??? Thấy lỗi báo nhiều quá nên . . sợ!!
  3. Mà tại sao lại phải xóa name đi nhỉ ??? Nếu muốn xóa các name do AF tạo ra thì phải chỉ đích danh chứ.
  4. Hình như là bác xóa đi dữ liệu và ghi đè lên chính vùng dữ liệu phải không ?? Nếu vậy thì hơi . . mạnh tay đấy.
  5. Còn có cả cách : Nếu ta sợ phải đụng chạm đến Sheet Dữ liệu, ta có thể tạo ra 1 sheet mới, xử lý xong thì xóa nó đi. Nhìn chung có rất nhiều mà.
Mấy lời mạo muội!
Thân!
 
Nếu không muốn thay đổi dữ liệu gốc (không sort dl gốc) bắt buộc phải dùng cột phụ. Có 2 cách như các bạn đã gợi ý:
1. Copy dl gốc sang sheet mới > sort > advanced filter > xóa cột sort. Cách này viết code dễ vì không ảnh hưởng đến dl gốc. Người viết tự quyết định vị trí copy và afilter trên sheet mới.

2. Copy dl gốc sang 1 cột phụ > sort cột phụ > advanced filter > xóa cột phụ. Cách này phải kiểm tra chặt chẽ việc chọn vi trí cột phụ, vị trí afilter không trùng nhau làm mất dữ liệu.

anhtuan chỉ cần chọn vùng dữ liệu cần afilter (chỉ 1 cột, 2 cột trở lên không làm)

Cách 1:
Mã:
[COLOR=black]Sub MyFilterSheet()
On Error Resume Next
Dim Rng As Range, CellCopy As Range, Cell01 As Range, CellTo As Range[/COLOR]
 
[COLOR=blue]'Kiểm tra vùng dữ liệu phải 1 cột[/COLOR][COLOR=black]
If Selection.Columns.Count > 1 Then
  MsgBox "Ban chon vung du lieu 2 cot. Ket thuc", , "Advanced Filter"
  Exit Sub
End If[/COLOR]
 
[COLOR=blue]'Copy sang sheet mới[/COLOR]
[COLOR=black]Selection.Copy[/COLOR]
[COLOR=black]Sheets.Add[/COLOR]
[COLOR=black]Cells(1, 2).Select
ActiveSheet.Paste
Set Rng = Selection
Set Cell01 = Rng.Item(1)[/COLOR]
 
[COLOR=blue]'Sort
[/COLOR][COLOR=black]Rng.Sort Key1:=Cell01, Order1:=xlAscending, Header:=xlNo[/COLOR]
[COLOR=black][/COLOR] 
[COLOR=black][COLOR=blue]'Advanced Filter[/COLOR]
Rng.AdvancedFilter Action:=xlFilterCopy, CopyToRange:=Cells(1, 1), Unique:=True[/COLOR]
 
[COLOR=blue]'Xóa dữ liệu tạm[/COLOR][COLOR=black]
Rng.ClearContents
Cells(1, 1).Select
End Sub
[/COLOR]


Cách 2:
Mã:
[COLOR=black]Sub MyFilter()
On Error Resume Next
Dim Rng As Range, CellCopy As Range, Cell01 As Range, CellTo As Range[/COLOR]
 
[COLOR=blue]'Kiểm tra vùng dữ liệu phải 1 cột[/COLOR][COLOR=black]
If Selection.Columns.Count > 1 Then
  MsgBox "Ban chon vung du lieu 2 cot. Ket thuc", , "Advanced Filter"
  Exit Sub
End If[/COLOR]
 
[COLOR=blue]'Nhập và kiểm tra cột phụ[/COLOR][COLOR=black]
Set CellCopy = Application.InputBox("Dung chuot chon o copy", "Advanced Filter", , , , , , 8)
If Err.Number > 0 Then
  MsgBox "Ban khong chon o copy", , "Advanced Filter"
  Exit Sub
ElseIf CellCopy.Count > 1 Then
  MsgBox "Ban chon nhieu o copy. Ket thuc", , "Advanced Filter"
  Exit Sub
ElseIf CellCopy.Column = Selection.Column Then
  MsgBox "Ban chon trung cot du lieu. Ket thuc", , "Advanced Filter"
  Exit Sub
End If[/COLOR]
 
[COLOR=blue]'Nhập và kiểm tra cột ghi advanced filter[/COLOR][COLOR=black]
Set CellTo = Application.InputBox("Dung chuot chon o Filter (cot Fiter se bi xoa du lieu)", "Advanced Filter", , , , , , 8)
If Err.Number > 0 Then
  MsgBox "Ban khong chon o ghi Filter. Ket thuc", , "Advanced Filter"
  Exit Sub
ElseIf CellTo.Count > 1 Then
  MsgBox "Ban chon nhieu o, khong ghi Filter. Ket thuc", , "Advanced Filter"
  Exit Sub
ElseIf CellCopy.Column = CellTo.Column Or CellTo.Column = Selection.Column Then
  MsgBox "Ban chon trung cot du lieu hoac cot copy. Ket thuc", , "Advanced Filter"
  Exit Sub
End If[/COLOR]
 
[COLOR=blue]'Copy sang cột phụ[/COLOR][COLOR=black]
Selection.Copy
CellCopy.Select
ActiveSheet.Paste
Set Rng = Selection
Set Cell01 = Rng.Item(1)[/COLOR]
 
[COLOR=blue]'Sort
[/COLOR][COLOR=black]Rng.Sort Key1:=Cell01, Order1:=xlAscending, Header:=xlNo[/COLOR]
[COLOR=black][/COLOR] 
[COLOR=black][COLOR=blue]'Advanced Filter[/COLOR]
CellTo.EntireColumn.ClearContents
Rng.AdvancedFilter Action:=xlFilterCopy, CopyToRange:=CellTo, Unique:=True[/COLOR]
 
[COLOR=blue]'Xóa dữ liệu tạm[/COLOR][COLOR=black]
Rng.ClearContents
CellTo.Select
End Sub
[/COLOR]
 

File đính kèm

Nếu không muốn thay đổi dữ liệu gốc (không sort dl gốc) bắt buộc phải dùng cột phụ. Có 2 cách như các bạn đã gợi ý:
1. Copy dl gốc sang sheet mới > sort > advanced filter > xóa cột sort. Cách này viết code dễ vì không ảnh hưởng đến dl gốc. Người viết tự quyết định vị trí copy và afilter trên sheet mới.

2. Copy dl gốc sang 1 cột phụ > sort cột phụ > advanced filter > xóa cột phụ. Cách này phải kiểm tra chặt chẽ việc chọn vi trí cột phụ, vị trí afilter không trùng nhau làm mất dữ liệu.
Cách của mình là sắp xếp trong biến mảng mà!
Nó chưa thuộc loại bạn đã liệt kê (?)

Lai.jpg
 
phamduylong đã viết:
Nếu không muốn thay đổi dữ liệu gốc (không sort dl gốc) bắt buộc phải dùng cột phụ. Có 2 cách như các bạn đã gợi ý:
1. Copy dl gốc sang sheet mới > sort > advanced filter > xóa cột sort. Cách này viết code dễ vì không ảnh hưởng đến dl gốc. Người viết tự quyết định vị trí copy và afilter trên sheet mới.

2. Copy dl gốc sang 1 cột phụ > sort cột phụ > advanced filter > xóa cột phụ. Cách này phải kiểm tra chặt chẽ việc chọn vi trí cột phụ, vị trí afilter không trùng nhau làm mất dữ liệu.

anhtuan chỉ cần chọn vùng dữ liệu cần afilter (chỉ 1 cột, 2 cột trở lên không làm)

Cảm ơn bác nhiều!
  1. Xóa dữ liệu tạm bác nên xóa cả Sheet mới được tao ra nhé
  2. Còn cách khác là chỉ cần dùng hàm của bác SA, sau đó copy dán giá trị lên là xong, mọi thứ xử lý trong VBA rồi. Một Sub nhỏ là đủ thôi.
Thân!
 
Cảm ơn tất cả mọi người... ko ngờ sôi nổi ghê!
Với Anh SA_DQ: Trong hàm của anh thấy có dùng Option Dess, ko biết nó dùng làm gì? Vì em xem code mà ko thấy chổ nào nói về nó cả (trừ dòng khai báo đầu code)
Với bạn minhlev và thầy Long: thì tôi vẫn đang làm theo cách ấy nhưng đang muốn tìm hiểu xem liệu có cách nào ko đụng chạm vì vào dử liệu gốc cũng như dùng cột phụ
Với Bắp: Có lý lắm, biến công thức thành Value, đở nặng máy
ANH TUẤN
 
anhtuan1066 đã viết:
Cảm ơn tất cả mọi người... ko ngờ sôi nổi ghê!
Với Anh SA_DQ: Trong hàm của anh thấy có dùng Option Dess, ko biết nó dùng làm gì? Vì em xem code mà ko thấy chổ nào nói về nó cả (trừ dòng khai báo đầu code)
Với bạn minhlev và thầy Long: thì tôi vẫn đang làm theo cách ấy nhưng đang muốn tìm hiểu xem liệu có cách nào ko đụng chạm vì vào dử liệu gốc cũng như dùng cột phụ
Với Bắp: Có lý lắm, biến công thức thành Value, đở nặng máy
ANH TUẤN
Vâng, cảm ơn bác nhiều!!

Thực ra với cách dùng như hàm thì ta còn có thể biến hàm thành sub, khi đã xử lý trong VBA rồi thì việc còn lại của SUB là add các giá trị của mảng vào cột tương ứng thôi.
Nhưng dù sao thì cứ dùng hàm sau đó copy - paste value thì đơn giản hơn nhiều.


Thân!
 
Cảm ơn tất cả mọi người...
Với Anh SA_DQ: Trong hàm của anh thấy có dùng Option Dess, ko biết nó dùng làm gì? Vì em xem code mà ko thấy chổ nào nói về nó cả (trừ dòng khai báo đầu code)
. . . ANH TUẤN
Mã:
[B]Function SortMatrix(Rng As Range, Optional Dess As Boolean)[/B]
Dess chưa dùng vì chưa viết xong phần xếp ngược (từ lớn đến bé)
Hay AnhTuấn with our thử sức xem sao.
Flower2.jpg
. . . . .
 
Lần chỉnh sửa cuối:
SortMatrix

Cho em hoi cai nay ti. Sau khi SortMatrix thi chi duoc 27 dòng thôi. Nếu thêm thì ko được. Anh có thể giúp em với được ko? Cảm ơn anh rất nhiều nhiều...
 
Bài toán này sẽ trở nên đơn giãn hơn với code:
PHP:
Option Explicit
Sub Loc()
  Application.ScreenUpdating = False
  Dim DS1 As Range, DS2 As Range
  Dim Er As Long
  Dim Luu As Variant
  Er = [A65536].End(xlUp).Row
  Set DS1 = Range("A5:A" & Er)
  Luu = DS1.Value
  DS1.Sort Key1:=[A6], Order1:=1, Header:=1
  Set DS2 = [A5].CurrentRegion
  DS2.AdvancedFilter Action:=2, CopyToRange:=[G5], Unique:=True
  DS1.Value = Luu
  Set DS1 = Nothing
  Set DS2 = Nothing
  Application.ScreenUpdating = True
End Sub
Dựa vào gợi ý Sort của Minhlev
 

File đính kèm

Cho em hỏi cái này tí. Sau khi SortMatrix thi chi duoc 27 dòng thôi. Nếu thêm thì ko được. Anh có thể giúp em với được ko? Cảm ơn anh rất nhiều nhiều...
1*/ Sao lười quá zậy không biết!
2*/ Mình đoán rằng bạn chưa quen xài hàm mảng; Muốn thêm bớt thì phải xóa nguyên mảng cũ đi; chọn vùng khác bự hơn & nhập hàm vô đó!
 
Web KT

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

Trả lời
42
Đọc
17K
Back
Top Bottom