Trích lọc danh sách duy nhất trong danh sách có chứa dòng rỗng (1 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ô đó!
 
Trích lọc danh sách duy nhất trong danh sách có chứa dòng rổng

Cảm ơn bạn ndu96081631
user_offline.gif
thật nhiều. Nhờ công thức của bạn mà mình đã tiết kiệm rất nhiều thời gian để tính công (sản phẩm mà công nhân làm ra) cho công nhân. Một lần nữa xin cảm ơn.
 
SortMatrix

Các anh xem giúp em file lọc dữ liệu này với. Em dùng SortMatrix của anh gì đấy nhưng chưa cho kết quả chính xác theo mong muốn của em. Nhờ các anh giúp đỡ. Cảm ơn các anh.
 

File đính kèm

Lọc như vầy còn nhanh gọn hơn nữa:
PHP:
Sub Filter_Unique()
    Dim Src As Range, Des As Range
    Application.ScreenUpdating = False
    Set Src = Range("A5:A" & [A65536].End(xlUp).Row)
    [C5].CurrentRegion.ClearContents
    Src.AdvancedFilter Action:=2, CopyToRange:=[C5], Unique:=True
    Set Des = Range("C5:C" & [C65536].End(xlUp).Row)
    Des.Sort Key1:=Des(2), Order1:=1, Header:=1
    Application.ScreenUpdating = True
End Sub
Khỏi cần đặt name
 

File đính kèm

Các anh xem giúp em file lọc dữ liệu này với. Em dùng SortMatrix của anh gì đấy nhưng chưa cho kết quả chính xác theo mong muốn của em. Nhờ các anh giúp đỡ. Cảm ơn các anh.
Bạn làm giống như bài tôi vừa đưa lên (chỉ sửa lại 1 tí về vị trị các cell) là ra ngay kết quả như mong muốn!
PHP:
Sub Filter_Unique()
    Dim Src As Range, Des As Range
    Application.ScreenUpdating = False
    Set Src = Range("A1:A" & [A65536].End(xlUp).Row)
    [E1].CurrentRegion.ClearContents
    Src.AdvancedFilter Action:=2, CopyToRange:=[E1], Unique:=True
    Set Des = Range("E1:E" & [E65536].End(xlUp).Row)
    Des.Sort Key1:=Des(2), Order1:=1, Header:=1, DataOption1:=1
    Application.ScreenUpdating = True
End Sub
 

File đính kèm

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ô đó!

Gửi SA
tôi làm như bạn rùi mà vẫn không được, có gì xem lại cho tôi với nhé
Xin chân thành cảm ơn.}}}}}
 
Lần chỉnh sửa cuối:
Lọc như vầy còn nhanh gọn hơn nữa:
PHP:
Sub Filter_Unique()
    Dim Src As Range, Des As Range
    Application.ScreenUpdating = False
    Set Src = Range("A5:A" & [A65536].End(xlUp).Row)
    [C5].CurrentRegion.ClearContents
    Src.AdvancedFilter Action:=2, CopyToRange:=[C5], Unique:=True
    Set Des = Range("C5:C" & [C65536].End(xlUp).Row)
    Des.Sort Key1:=Des(2), Order1:=1, Header:=1
    Application.ScreenUpdating = True
End Sub
Khỏi cần đặt name

To ndu96081631
thực sự tôi đang cần cái này, thật may mà đọc được bài viết của bạn, nhưng tôi vẫn không hiểu hàm của bạn như thế nào nhỉ. tôi gà cái này lắm, nếu câu hỏi buồn cười thì đừng cười to quá nhé.ke ke
Chân thành cảm ơn. Đóng góp của các bạn rất có ích cho tôi
 
Lần chỉnh sửa cuối:
Có thể dùng lại biến thì viết như sau:
PHP:
Sub Filter_Unique()
    Dim Src As Range
    Application.ScreenUpdating = False
    Set Src = Range("A1:A" & [A65536].End(xlUp).Row)
    [E1].CurrentRegion.ClearContents
    Src.AdvancedFilter Action:=2, CopyToRange:=[E1], Unique:=True
    Set Src = Range("E1:E" & [E65536].End(xlUp).Row)
    Src.Sort Key1:=Src(2), Order1:=1, Header:=1, DataOption1:=1
    Application.ScreenUpdating = True
End Sub
Diễn giải đơn giản như sau:
Sub Filter_Unique() |
Dim Src As Range | Tạo biến Src với tính chất là Range Application.ScreenUpdating = False | Đặt thuộc tính nạp lên mà hình là False Set Src = Range("A1:A" & [A65536].End(xlUp).Row) | Nạp dữ liệu vùng là từ A1 đến hết rồi đặt nó cho biến Src
[E1].CurrentRegion.ClearContents | Thực hiện việc xóa dữ liệu cho vùng tình từ E1 Src.AdvancedFilter Action:=2, CopyToRange:=[E1], Unique:=True | Thực hiện lệnh lọc Advanced Filter cho vùng này và copy nó sang vị trí E1 Set Src = Range("E1:E" & [E65536].End(xlUp).Row) | Nạp lại vùng từ E1 đến hết cho biến Src để Sort dữ liệu.
Src.Sort Key1:=Src(2), Order1:=1, Header:=1, DataOption1:=1 | Thực hiện Sort dữ liệu tăng dần ( Order:=1; với 1 = xlAscending ), và bỏ dòng đầu ( Header:=1 )
Application.ScreenUpdating = True | Trả lại giá trị trên màn hình
End Sub
Thân.
 
Lần chỉnh sửa cuối:
Vầy mới thật là "cực ngắn" đây:
PHP:
Sub Filter_Unique()
  [E1].CurrentRegion.ClearContents
  Range([A1], [A65536].End(xlUp)).AdvancedFilter 2, , [E1], True
  [E1].CurrentRegion.Sort [E1], 1, Header:=1, DataOption1:=1
End Sub
Diển giãi:
- Dòng 1: Xóa sạch vùng dử liệu cột E trước khi lọc
- Dòng 2: Lọc duy nhất với dử liệu ở cột A, copy sang E1
- Dòng 3: Sort lại dử liệu sau khi lọc để loại bỏ các cell rổng
Đơn giản không? Tất cả đều tương đương với việc bạn làm bằng tay, dùng Advanced Filter và Sort (trên menu Data) ---> Chẳng qua ghi lại thành code cho nó tiện thôi
 
Lần chỉnh sửa cuối:
Xin gửi lên 1 lần rút gọn nữa! Mong rằng nó là cái "Không phải" cuối cùng! Hiii
PHP:
Sub Filter_Unique()
  [E1].CurrentRegion.ClearContents
  Range([A1], [A65536].End(xlUp)).AdvancedFilter 2, , [E1], 1
  [E1].CurrentRegion.Offset(1).Sort [E1], DataOption1:=1
End Sub
Thân.
 
Xin gửi lên 1 lần rút gọn nữa! Mong rằng nó là cái "Không phải" cuối cùng! Hiii
PHP:
Sub Filter_Unique()
  [E1].CurrentRegion.ClearContents
  Range([A1], [A65536].End(xlUp)).AdvancedFilter 2, , [E1], 1
  [E1].CurrentRegion.Offset(1).Sort [E1], DataOption1:=1
End Sub
Thân.
Uh... quả có ngắn hơn thật!
Giờ nhìn lại mấy code hồi trước mình viết sao nó... buồn cười quá ---> Dài nhằng và lượm thượm... viết dở ẹc mà mạnh dạn post ghê
Nhưng nếu không có "ngày trước" thì cũng sẽ không có "ngày nay" , đúng không?
Tự cười mình để tiếp tục học hỏi và tiến bộ!
Các bạn mới học cũng nên bắt tay vào ngay hôm nay đi (năm con Trâu, ta cày như Trâu càng tốt)
Hy vọng rằng sau khi các bạn xem qua bài viết Chập chững đến VBA! của sư phụ SA_DQ rồi vò đầu bứt tóc thì cũng đến 1 ngày nào đó các bạn sẽ tự cười mình như tôi đang cười chính tôi của "ngày trước" đây! (dù "ngày nay" chẳng giỏi giang gì nhưng cũng thấy bớt tệ hơn "ngày trước")
Tản mạn 1 chút
ndu
 
Lần chỉnh sửa cuối:
Em không nghĩ vậy!
Vì trên diễn đàn còn rất nhiều người đọc. Nếu ai cũng viết code cao siêu hết thì chẳng ai còn hiểu gì cả? Vậy diễn đàn của mình sẽ ở trên mây đó bác.
Em vẫn viết code đơn giản để mọi người mới bắt đầu còn biết đường mà làm theo nữa và học nữa.
Đâu ai cũng hiểu những code này đâu. Nếu vào mà bị quăng Bom liền thì hư đường hư muối hết.
Nếu cứ sau 1 bài bạn nâng dần code lên thì người ta sẽ học hỏi được biết là bao nhiêu.
Em và bác cùng tung hứng để đưa thành viên GPE lên tầm / tầm /tầm/... dưới mình là được. Hiii
Thân.
 
Lọc danh sách họ tên theo Phòng ban đơn vị

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


Chào Anh Tuấn !
Các anh có thể Hưỡng dân cách làm Lọc Danh sách họ và tên theo Từng Bộ phận phòng ban được không. Cụ thể em muốn làm như sau:
1/ Chẳng hạn khi ấn vào Phòng Kế toán thi hiện ra danh sách họ tên nhân viên phong kê toán

2/ Em muốn làm Họ một cột và tên môt cột . VD Nuyễn Văn Kiên thì Cột 1 là Nguyễn Văn và Cột 2 là Kiên
 

File đính kèm

Xin gửi lên 1 lần rút gọn nữa! Mong rằng nó là cái "Không phải" cuối cùng! Hiii
PHP:
Sub Filter_Unique()
  [E1].CurrentRegion.ClearContents
  Range([A1], [A65536].End(xlUp)).AdvancedFilter 2, , [E1], 1
  [E1].CurrentRegion.Offset(1).Sort [E1], DataOption1:=1
End Sub
Thân.

Tôi thử code này cho ví dụ trong file đính kèm tại bài 1 của anhtuan1066 nhưng không được ? Theo tôi thì do dòng lệnh thứ 2 cho danh sách lọc tại cột E vẫn có dòng rỗng vì vậy sử dụng CurrentRegion trong dòng lệnh thứ 3 sẽ không chọn được hết danh sách do đó khi Sort không loại được dòng trống. Không biết có phải như vậy không ? xem file đính kèm

Vì không phải ai cũng biết sửa code nên bạn nào biết cách tạo thêm Inputbox thì bổ sung để nhiều người có thể sử dụng được (người dùng khai báo vùng dữ liệu và vùng chứa kết quả vào Inputbox sao cho phù hợp với dữ liệu của mình)
 

File đính kèm

Cách thứ 1 có thể viết lại như vầy:
PHP:
Sub Loc_Po_pikachu()
    [E1].CurrentRegion.ClearContents
    Range([A1], [A65536].End(xlUp)).AdvancedFilter 2, , [E1], 1
    Range([E1], [E65536].End(xlUp)).Offset(1).Sort [E1], DataOption1:=1
End Sub

Nếu dùng Inputbox thì không biết là bác dùng bao nhiêu Inputbox nên em dùng cho 2 vị trí luôn.
PHP:
Sub Loc_Po_pikachu()
Dim vung1 As Range, vung2 As Range
Set vung1 = Application.InputBox("Chon vung du lieu: ", Type:=8)
Set vung2 = Application.InputBox("Chon vi tri luu du lieu: ", Type:=8)
    [vung2].CurrentRegion.ClearContents
    vung1.AdvancedFilter 2, , vung2, 1
    Range(vung2, Cells(65000, vung2.Column).End(xlUp)).Offset(1).Sort vung2, DataOption1:=1
End Sub

Hoặc có thể viết ngắn như vầy:
PHP:
Sub Loc_Po_pikachu()
With Application.InputBox("Chon vi tri luu du lieu: ", Type:=8)
    .CurrentRegion.ClearContents
    Application.InputBox("Chon vung du lieu: ", Type:=8).AdvancedFilter 2, , .Cells, 1
    Range(.Cells, Cells(65000, .Column).End(xlUp)).Offset(1).Sort .Cells, DataOption1:=1
End With
End Sub
Thân.
 
Lần chỉnh sửa cuối:
@ Po_Pikachu
mình đã chạy thử kết quả rất tốt nhưng khi nhấn nút Cancel thì báo lỗi, bạn kiểm tra và sửa giúp nhé
Cảm ơn!
 
Muốn Cancel thì thêm dòng On Error Resume Next vào là được.
PHP:
Sub Loc_Po_pikachu()
On Error Resume Next
With Application.InputBox("Chon vi tri luu du lieu: ", Type:=8)
    .CurrentRegion.ClearContents
    Application.InputBox("Chon vung du lieu: ", Type:=8).AdvancedFilter 2, , .Cells, 1
    Range(.Cells, Cells(65000, .Column).End(xlUp)).Offset(1).Sort .Cells, DataOption1:=1
End With
End Sub
Thân.
 
Trả về danh sách các phần tử duy nhất trong một dãy.

Đầu tiên cho em sorry anh Anhtuan1066 và các anh chị trong diễn đàn giải pháp excel trước nha.
Em có coi hướng dẫn cách post bài mới nhưng vẫn chưa hiểu "bạn click vào biểu tượng
newthread.gif
ở góc trái ở mỗi box", em tìm hoài nhưng vẫn không thấy biểu tượng đó ở đâu? phải vô đường dẫn nào? vì vậy em đành mượn nhờ bài của anh anhtuan1066 để hỏi bài toán excel em đang bị bí. Anh chị giúp dùm em với, em cám ơn!

Em tải bài này của anh Trần Thanh Phong tổng hợp và biên dịch (có tham khảo bài của chị handung trên GPE) - trang 27, nhưng khi e làm thì công thức không chạy được? em có gửi kèm file của em lập dựa theo công thức của anh Thanh Phong.
 

File đính kèm

Đầu tiên cho em sorry anh Anhtuan1066 và các anh chị trong diễn đàn giải pháp excel trước nha.
Em có coi hướng dẫn cách post bài mới nhưng vẫn chưa hiểu "bạn click vào biểu tượng
newthread.gif
ở góc trái ở mỗi box", em tìm hoài nhưng vẫn không thấy biểu tượng đó ở đâu? phải vô đường dẫn nào? vì vậy em đành mượn nhờ bài của anh anhtuan1066 để hỏi bài toán excel em đang bị bí. Anh chị giúp dùm em với, em cám ơn!

Em tải bài này của anh Trần Thanh Phong tổng hợp và biên dịch (có tham khảo bài của chị handung trên GPE) - trang 27, nhưng khi e làm thì công thức không chạy được? em có gửi kèm file của em lập dựa theo công thức của anh Thanh Phong.

Không biết bạn làm gì hình như là trích lọc ra ds duy nhất đúng không ?
Bạn đến đây tham khảo nhe .có nhiều lắm .đơn giản nhất là dùng Advanced Filter
Loc
Thân
 
Ham VLOOKUP voi Time gan nhat.xls - Giup minh voi

MOng anh giup giup minh voi nhe. Yeu cau minh co ghi trong file dinh kem
 

File đính kèm

MOng anh giup giup minh voi nhe. Yeu cau minh co ghi trong file dinh kem

Topic này đang bàn về trích lọc duy nhất!
Bài của bạn đã được trả lời tại đây: http://www.giaiphapexcel.com/forum/showthread.php?p=136250&posted=1#post136250

Sao bạn post bài nhiều chỗ vậy!?
Thêm nữa, nếu bạn không muốn bài của mình bị xóa thì cần viết bài với tiêu đề và nội dung có dấu tiếng Việt nhé!
 
Lần chỉnh sửa cuối:
Trả về danh sách các phần tử duy nhất trong một dãy.

Mình cảm ơn bạn đã chỉ cho mình, cách này mình thử rồi nhưng không được, chắc tại phần vùng trích lọc của mình có chứa công thức vì vậy nên mình muốn sử dụng cách trích lọc khác.
Mình không hiểu tại sao dù đã xóa công thức nhưng khi mình thử chèn dòng trống và thêm vào 1 số liệu không có trong ĐK trích nó vẫn hiểu và trích luôn phần dòng rỗng và số đó.
Mình gửi file đính kèm từ nãy đến giờ nhưng không được, mình sẽ gửi qua địa chỉ mail của bạn, bạn thông cảm nha.​
 
trả về danh sách các phần tử duy nhất trong dãy

anh, chị nào biết công thức trả về danh sách các phần tử duy nhất trong một dãy thì giúp em với, cảm ơn nhiu nhiu
 

File đính kèm

anh, chị nào biết công thức trả về danh sách các phần tử duy nhất trong một dãy thì giúp em với, cảm ơn nhiu nhiu
Dạng bài này nếu dữ liệu nhiều mà dùng công thức thì máy chạy mệt mỏi lắm, làm thử cho bạn thôi nhé
Tình cờ đọc được cái thằng New Collection, chẳng hiểu mô tê chi, mò mẫm một hồi thấy nó lọc duy nhất rất nhanh, dữ liệu như trong bài mình thử với 45.000 dòng nó chạy có nửa giây
Mã:
Public Sub loc()
    Dim Vung, Mg(), Ll As New Collection, Cll As Range, i As Long
    Set Vung = Range([c10], [c50000].End(xlUp))
    Range("D:D").Clear
    On Error Resume Next
        For Each Cll In Vung
            Ll.Add Cll.Value, CStr(Cll.Value)
        Next
            ReDim Mg(Ll.Count - 1)
                For i = 1 To Ll.Count
                    Mg(i - 1) = Ll(i)
                Next i
[d10].Resize(Ll.Count) = Application.WorksheetFunction.Transpose(Mg)
End Sub
Các bạn thử xóa hết công thức & name, thêm vài chục ngàn dòng rồi chạy thử code
Vẫn hổng hiểu
Híc
 

File đính kèm

Dạng bài này nếu dữ liệu nhiều mà dùng công thức thì máy chạy mệt mỏi lắm, làm thử cho bạn thôi nhé
Tình cờ đọc được cái thằng New Collection, chẳng hiểu mô tê chi, mò mẫm một hồi thấy nó lọc duy nhất rất nhanh, dữ liệu như trong bài mình thử với 45.000 dòng nó chạy có nửa giây
Mã:
Public Sub loc()
    Dim Vung, Mg(), Ll As New Collection, Cll As Range, i As Long
    Set Vung = Range([c10], [c50000].End(xlUp))
    Range("D:D").Clear
    On Error Resume Next
        For Each Cll In Vung
            Ll.Add Cll.Value, CStr(Cll.Value)
        Next
            ReDim Mg(Ll.Count - 1)
                For i = 1 To Ll.Count
                    Mg(i - 1) = Ll(i)
                Next i
[d10].Resize(Ll.Count) = Application.WorksheetFunction.Transpose(Mg)
End Sub
Các bạn thử xóa hết công thức & name, thêm vài chục ngàn dòng rồi chạy thử code
Vẫn hổng hiểu
Híc
Anh cogia này vận dụng nhanh ghê. Cám ơn Anh.
Em làm thêm để nghiên cứu thử Dic và new Collection và AdFi nhé.
Dùng Dic
PHP:
Sub locDic()
Dim T
T = Timer
Dim Vung, Mg(), Arr(), i As Long
Dim Dic As Object
Set Dic = CreateObject("Scripting.Dictionary")
Set Vung = Range([c10], [c65000].End(xlUp))
Arr = Vung.Value
Range("E:E").Clear
For i = 1 To UBound(Arr)
  If Not Dic.exists(Arr(i, 1)) Then
    Dic.Add Arr(i, 1), ""
  End If
Next
  Mg = Dic.keys
[E10].Resize(Dic.Count) = Application.WorksheetFunction.Transpose(Mg)
[a2] = Timer - T
End Sub
Dùng AdFi
PHP:
Sub locAdFi()
Dim T
T = Timer
    Dim Vung As Range
    Set Vung = Range([c9], [c65000].End(xlUp))
    Range("F:F").Clear
    Vung.AdvancedFilter Action:=xlFilterCopy, CopyToRange:=Range( _
        "F9"), Unique:=True
[a3] = Timer - T
End Sub
Em đã thử với 60.000 dòng. Dic là nhanh nhất. Anh kiểm tra giúp em.
 
Dạng bài này nếu dữ liệu nhiều mà dùng công thức thì máy chạy mệt mỏi lắm, làm thử cho bạn thôi nhé
Tình cờ đọc được cái thằng New Collection, chẳng hiểu mô tê chi, mò mẫm một hồi thấy nó lọc duy nhất rất nhanh, dữ liệu như trong bài mình thử với 45.000 dòng nó chạy có nửa giây
Mã:
Public Sub loc()
    Dim Vung, Mg(), Ll As New Collection, Cll As Range, i As Long
    Set Vung = Range([c10], [c50000].End(xlUp))
    Range("D:D").Clear
    On Error Resume Next
        For Each Cll In Vung
            Ll.Add Cll.Value, CStr(Cll.Value)
        Next
            ReDim Mg(Ll.Count - 1)
                For i = 1 To Ll.Count
                    Mg(i - 1) = Ll(i)
                Next i
[d10].Resize(Ll.Count) = Application.WorksheetFunction.Transpose(Mg)
End Sub
Các bạn thử xóa hết công thức & name, thêm vài chục ngàn dòng rồi chạy thử code
Vẫn hổng hiểu
Híc
Anh dùng Collection thế này thì có thể thi đấu tốc độ với Dictionary của ThuNghi đấy:
PHP:
Sub Loc()
  Dim Arr(), TmpArr, Item, iCount As Long, Dur As Double
  Dur = Timer
  With Range([C10], [C65536].End(xlUp))
    TmpArr = .Value
    ReDim Arr(1 To .Count)
  End With
  Range("D:D").Clear
  On Error Resume Next
  With New Collection
    For Each Item In TmpArr
      iCount = .Count
      .Add Item, CStr(Item)
      If iCount <> .Count Then Arr(.Count) = Item
    Next
    Range("D10").Resize(.Count) = WorksheetFunction.Transpose(Arr)
  End With
  MsgBox Format(Timer - Dur, "0.000000")
End Sub
Tốc độ của Dictionary có nhanh nhưng cũng chỉ nhỉnh hơn tí thôi:
- Với dữ liệu của tác giả, ta copy ra 60,000 dòng thì code dùng Collection ra kết quả trong vòng 0.26s, còn Dictionary ra kết quả trong vòng 0.23s
- Với dữ liệu 60,000 dòng KHÔNG TRÙNG, code dùng Collection ra kết quả trong vòng 0.57s, còn Dictionary ra kết quả trong vòng 0.53s
-------------------------
Dữ liệu càng ít trùng thì code càng chậm và ngược lại ---> Với Collection, ta phải dùng tí "mẹo" ---> Tham khảo thêm tại đây:
http://www.giaiphapexcel.com/forum/showthread.php?27286-T%E1%BA%A1o-d%C3%A3y-s%E1%BB%91-ng%E1%BA%ABu-nhi%C3%AAn-kh%C3%B4ng-tr%C3%B9ng/page3
 
anh, chị nào biết công thức trả về danh sách các phần tử duy nhất trong một dãy thì giúp em với, cảm ơn nhiu nhiu

Thử dùng cái code tự chế xem có được không nhé

Private Sub CommandButton1_Click()
Sheets("sheet1").Range("C9:C60000").Copy
ActiveSheet.Range("E9").Select
Selection.PasteSpecial Paste:=xlPasteValues
ActiveSheet.Range("E9:E60000").RemoveDuplicates Columns:=1
ActiveSheet.Range("E9").Select
End Sub

các bác thunghi-concogia-ndu... có đi qua thấy sai chổ nào thì chỉ giúp em nhé
 

File đính kèm

Lần chỉnh sửa cuối:
Thử dùng cái code tự chế xem có được không nhé

Private Sub CommandButton1_Click()
Sheets("sheet1").Range("C9:C60000").Copy
ActiveSheet.Range("E9").Select
Selection.PasteSpecial Paste:=xlPasteValues
ActiveSheet.Range("E9:E60000").RemoveDuplicates Columns:=1
ActiveSheet.Range("E9").Select
End Sub

các bác thunghi-concogia-ndu... có đi qua thấy sai chổ nào thì chỉ giúp em nhé
Sai thì không... nhưng RemoveDuplicates chỉ dùng được với version từ 2007 trở đi ---> Excel 2003 trở xuống sẽ báo lỗi!
Lưu ý rằng cho dù ta đang sở hửu bộ Office 2007 đi nữa thì khi đụng đến chuyện LỌC DUY NHẤT cũng nên dùng AdvancedFilter ----> RemoveDuplicates chỉ dùng trong trường hợp LỌC TẠI CHỔ mà thôi, tức là XÓA DỮ LIỆU TRÙNG, không phải là LỌC SANG NƠI KHÁC
Nếu muốn dùng công cụ có sẳn, tôi đề xuất code thế này:
PHP:
Private Sub CommandButton1_Click()
  Range("E:E").Clear
  Range("C9:C60000").AdvancedFilter 2, , [E9], True
End Sub
Sẽ dùng được trên Excel 2003 và cả Excel 2007
Nói thêm: Tuy code có gọn nhưng tốc độ cũng không thế nhanh bằng với Dictionary và Collection đâu
 
sai thì không... Nhưng removeduplicates chỉ dùng được với version từ 2007 trở đi ---> excel 2003 trở xuống sẽ báo lỗi!
Lưu ý rằng cho dù ta đang sở hửu bộ office 2007 đi nữa thì khi đụng đến chuyện lọc duy nhất cũng nên dùng advancedfilter ----> removeduplicates chỉ dùng trong trường hợp lọc tại chổ mà thôi, tức là xóa dữ liệu trùng, không phải là lọc sang nơi khác
nếu muốn dùng công cụ có sẳn, tôi đề xuất code thế này:
PHP:
private sub commandbutton1_click()
range("e:e").clear
range("c9:c60000").advancedfilter 2, , [e9], true
end sub
sẽ dùng được trên excel 2003 và cả excel 2007
nói thêm: Tuy code có gọn nhưng tốc độ cũng không thế nhanh bằng với dictionary và collection đâu
hì i . Do em đang mày mò để tự học vba mà không có đến lớp nào cả
thấy bài #1 cuả bác tuấn yêu cầu bèn tìm cách nghiên cứu
nhưng thấy bác thu nghi nói nếu mới bập bẹ vào vba thì không nên dùng newcolection và dic. Nên dùng code có sẵn và chỉ nghiên cứu để tự học mà thôi
(CODE CỦA BÁC EM COPY VỀ THÌ KHÔNG CHẠY BÁC ƠI)
(bác ở biên hoà mà sao gặp bác khó quá, có phải bác đang làm ở gỗ tân mai không ?)
 
Lần chỉnh sửa cuối:
hì i . Do em đang mày mò để tự học vba mà không có đến lớp nào cả
thấy bài #1 cuả bác tuấn yêu cầu bèn tìm cách nghiên cứu
nhưng thấy bác thu nghi nói nếu mới bập bẹ vào vba thì không nên dùng newcolection và dic. Nên dùng code có sẵn và chỉ nghiên cứu để tự học mà thôi
ThuNghi nói đúng đây! Nêu mới tập tành thì nên dùng phương pháp Record macro thu lại những thao tác mà ta đã làm, sau đó vào chỉnh lại code
Để code gọn hơn, ta sẽ xóa bớt những chổ có Select hoặc Selection. Ví dụ thế này:
Mã:
Range("E9:E100").Select
Selection.Copy
Range("F9").Select
ActiveSheet.Paste
Đoạn này ta sẽ rút gọn thành:
Mã:
Range("E9:E100").Copy Range("F9")
----------------------------------------------------------
(bác ở biên hoà mà sao gặp bác khó quá, có phải bác đang làm ở gỗ tân mai không ?)
Tôi làm ở cty ChangShin bạn à (nhà cũng gần đó) ---> Muốn gì cứ nhắn tin riêng nhé!
 
ThuNghi nói đúng đây! Nêu mới tập tành thì nên dùng phương pháp Record macro thu lại những thao tác mà ta đã làm, sau đó vào chỉnh lại code
Để code gọn hơn, ta sẽ xóa bớt những chổ có Select hoặc Selection. Ví dụ thế này:
Mã:
Range("E9:E100").Select
Selection.Copy
Range("F9").Select
ActiveSheet.Paste
Đoạn này ta sẽ rút gọn thành:
Mã:
Range("E9:E100").Copy Range("F9")
----------------------------------------------------------
CẢM ƠN NDU ĐÃ CHỈ GIÁO
XEM DỮ LIỆU CỦA TÁC GIẢ KHÔNG CÓ CT NÊN TÔI RÚT GỌN NHƯ SAU
COPY SANG SHEET KHÁC
PHP:
Private Sub CommandButton1_Click()
Sheets("sheet1").Range("C9:C60000").Copy Sheets("sheet2").Range("E9")
Sheets("sheet2").Range("E8:E60000").RemoveDuplicates Columns:=1
End Sub
 
COPY TRONG SHEET
 
Private Sub CommandButton1_Click()
Sheets("sheet1").Range("C9:C60000").Copy Range("E9")
ActiveSheet.Range("E8:E60000").RemoveDuplicates Columns:=1
End Sub
 
Lần chỉnh sửa cuối:
Tôi có cách để lọc danh sách duy nhất đơn giản-Xin mọi người tham khảo
VDụ :
Có danh sách Công ty A, Cty B, CtyC ..........Cty X Với số dòng 100 .
Để lọc ra danh sách duy nhất ta có thể dùng Hàm IF.
Giả sử Fiels Tên Công ty là A1-Công ty A bắt đầu danh sách là từ A2 đến A10 (Danh sách này đã được sắp xếp trong khung Lits theo thứ tự) công ty B từ A11 đến A20 tương tự các cty khác tiếp theo.....
Tại B2 ta Viết Công thức Sau =IF(A2=A1,0,1) như vậy các giá trị duy nhất sẽ nhận giá trị là 1 ta chỉ cần lọc theo Điều kiện là 1 sẽ ra ngay.
Xin cảm ơn.
Doviethung
 
Tôi có cách để lọc danh sách duy nhất đơn giản-Xin mọi người tham khảo
VDụ :
Có danh sách Công ty A, Cty B, CtyC ..........Cty X Với số dòng 100 .
Để lọc ra danh sách duy nhất ta có thể dùng Hàm IF.
Giả sử Fiels Tên Công ty là A1-Công ty A bắt đầu danh sách là từ A2 đến A10 (Danh sách này đã được sắp xếp trong khung Lits theo thứ tự) công ty B từ A11 đến A20 tương tự các cty khác tiếp theo.....
Tại B2 ta Viết Công thức Sau =IF(A2=A1,0,1) như vậy các giá trị duy nhất sẽ nhận giá trị là 1 ta chỉ cần lọc theo Điều kiện là 1 sẽ ra ngay.
Xin cảm ơn.
Doviethung
Cám ơn bạn đã chia sẻ. Cách này tôi làm trước đây, nhưng bây giờ ít dùng. Trên thực tế, danh sách công ty có khi xếp lộn xộn, nếu thế bạn phải sort lại trước khi áp dụng công thức. Hiện nay, trên diễn đàn có rất nhiều giải pháp về vấn đề này, tôi chia sẻ 1 công thức tôi cho là ngắn và dễ áp dụng.
Giả sử từ A2:A100 là danh sách các công ty sắp xếp lộn xộn. Ta sẽ trích lọc danh sách duy nhất tại cột B.Tại B2 bạn sẽ nhập công thức mảng sau:
Mã:
=INDEX($A$2:$A$100,MATCH(0,COUNTIF($B$1:B1,$A$2:$A$100),0))
Kết thúc bằng Ctrl-Shift-Enter.
Copy xuống đến khi báo lỗi.
 
Nếu dùng hàm để tạo mã lọc duy nhất thì tôi thường làm như sau: tại B2 nhập =COUNTIF(A$2:A2;A2) Fill xuống rồi Autofilter 1

Với =IF(A2=A1,0,1) thì dữ liệu như dưới đây lọc sẽ không đúng... ẹc...ẹc...
A
A
B
C
C
B
A
A
B
C
 
Lần chỉnh sửa cuối:
Lọc như vầy còn nhanh gọn hơn nữa:
PHP:
Sub Filter_Unique()
    Dim Src As Range, Des As Range
    Application.ScreenUpdating = False
    Set Src = Range("A5:A" & [A65536].End(xlUp).Row)
    [C5].CurrentRegion.ClearContents
    Src.AdvancedFilter Action:=2, CopyToRange:=[C5], Unique:=True
    Set Des = Range("C5:C" & [C65536].End(xlUp).Row)
    Des.Sort Key1:=Des(2), Order1:=1, Header:=1
    Application.ScreenUpdating = True
End Sub
Khỏi cần đặt name
Mừng quá, các bài toán khác em tìm trên diễn đàn từ sáng có vẻ như quá sức của em, bây giờ mới tìm ra được chủ đề này. Em nghĩ chủ đề này là một trong số các chủ đề rất phù hợp cho những người bắt đầu tìm tòi về VBA như em. Đa tạ các anh, chị, các thày nhiều.
 
Mình cũng có một bài toán muốn hỏi. Vấn đề khá giống vấn đề bạn tuan anh nêu ra nhưng phức tạp hơn. Đó là mình có khoảng 100 workshoot dữ liệu bên trong bị trộn lẫn các cột và dòng với nhau, nếu bỏ merge cell thì các ô sẽ có khoảng trống cả cột và cả dòng. Mình muốn trích lọc dữ liệu ra để xử lý. Không biết có cách nào không các bạn nhỉ?
Xin nhờ các pro xử lý giúp mình với, thank các bạn!
 
Vầy mới thật là "cực ngắn" đây:
PHP:
Sub Filter_Unique()
  [E1].CurrentRegion.ClearContents
  Range([A1], [A65536].End(xlUp)).AdvancedFilter 2, , [E1], True
  [E1].CurrentRegion.Sort [E1], 1, Header:=1, DataOption1:=1
End Sub
Diển giãi:
- Dòng 1: Xóa sạch vùng dử liệu cột E trước khi lọc
- Dòng 2: Lọc duy nhất với dử liệu ở cột A, copy sang E1
- Dòng 3: Sort lại dử liệu sau khi lọc để loại bỏ các cell rổng
Đơn giản không? Tất cả đều tương đương với việc bạn làm bằng tay, dùng Advanced Filter và Sort (trên menu Data) ---> Chẳng qua ghi lại thành code cho nó tiện thôi

Bài này dùng VBA thì quả là có rất nhiều cách, ngoài cách trên em rất thích làm theo công thức, nhờ thày giúp cho cách viết Name điều kiện (tức là cụ thể hóa bước đánh dấu các dữ liệu cần lọc) viết thế nào ah?
 
Bài này dùng VBA thì quả là có rất nhiều cách, ngoài cách trên em rất thích làm theo công thức, nhờ thày giúp cho cách viết Name điều kiện (tức là cụ thể hóa bước đánh dấu các dữ liệu cần lọc) viết thế nào ah?

Thì làm như #53 và thêm If để không lấy các số >1
Ví dụ: =IF(COUNTIF($A$2:A2;A2)=1;"x";"")
 
Có thể dùng lại biến thì viết như sau:
PHP:
Sub Filter_Unique()
    Dim Src As Range
    Application.ScreenUpdating = False
    Set Src = Range("A1:A" & [A65536].End(xlUp).Row)
    [E1].CurrentRegion.ClearContents
    Src.AdvancedFilter Action:=2, CopyToRange:=[E1], Unique:=True
    Set Src = Range("E1:E" & [E65536].End(xlUp).Row)
    Src.Sort Key1:=Src(2), Order1:=1, Header:=1, DataOption1:=1
    Application.ScreenUpdating = True
End Sub
Diễn giải đơn giản như sau:
Sub Filter_Unique() |
Dim Src As Range | Tạo biến Src với tính chất là Range Application.ScreenUpdating = False | Đặt thuộc tính nạp lên mà hình là False Set Src = Range("A1:A" & [A65536].End(xlUp).Row) | Nạp dữ liệu vùng là từ A1 đến hết rồi đặt nó cho biến Src
[E1].CurrentRegion.ClearContents| Thực hiện việc xóa dữ liệu cho vùng tình từ E1 Src.AdvancedFilter Action:=2, CopyToRange:=[E1], Unique:=True | Thực hiện lệnh lọc Advanced Filter cho vùng này và copy nó sang vị trí E1 Set Src = Range("E1:E" & [E65536].End(xlUp).Row) | Nạp lại vùng từ E1 đến hết cho biến Src để Sort dữ liệu.
Src.Sort Key1:=Src(2), Order1:=1, Header:=1, DataOption1:=1 | Thực hiện Sort dữ liệu tăng dần ( Order:=1; với 1 = xlAscending ), và bỏ dòng đầu ( Header:=1 )
Application.ScreenUpdating = True | Trả lại giá trị trên màn hình
End Sub
Thân.

Bác cho em hỏi nếu chỉ muốn xóa Cột E thôi thì sửa code như thế nào
Vì các cột khác em có công thức ko muốn xóa
 
Cảm ơn Bác nhiều, code của Bác làm file excel của em nhẹ hẳn đi, trước em dùng công thức nó nặng quá Chúc bác sức khỏe và thành đạt
 
Code này đúng là làm cho file của em nhẹ đi rất nhiều, thanks bác
 
Vầy mới thật là "cực ngắn" đây:
PHP:
Sub Filter_Unique()
  [E1].CurrentRegion.ClearContents
  Range([A1], [A65536].End(xlUp)).AdvancedFilter 2, , [E1], True
  [E1].CurrentRegion.Sort [E1], 1, Header:=1, DataOption1:=1
End Sub
Chảo bác
Em cảm ơn bác về những hướng dẫn của chủ đề này. Em cũng làm thử như hướng dẫn, kết hợp với record marco để ra Code. Em không hiểu sao nó vẫn chưa lọc được danh sách duy nhất.
Ngoài ra vùng dữ liệu để lọc em không muốn "tham lam" lấy cả cột mà muốn chọn lựa thì thế nào ạ?

Mong được giúp đỡ

Link tải file: https://dl.dropbox.com/s/09oke3h6ss74scg/XuatNhapTon.xls?dl=1
 
Vầy mới thật là "cực ngắn" đây:
PHP:
Sub Filter_Unique()
  [E1].CurrentRegion.ClearContents
  Range([A1], [A65536].End(xlUp)).AdvancedFilter 2, , [E1], True
  [E1].CurrentRegion.Sort [E1], 1, Header:=1, DataOption1:=1
End Sub
Chảo bác
Em cảm ơn bác về những hướng dẫn của chủ đề này. Em cũng làm thử như hướng dẫn, kết hợp với record marco để ra Code. Em không hiểu sao nó vẫn chưa lọc được danh sách duy nhất.
Ngoài ra vùng dữ liệu để lọc em không muốn "tham lam" lấy cả cột mà muốn chọn lựa thì thế nào ạ?

Mong được giúp đỡ

Link tải file: https://dl.dropbox.com/s/09oke3h6ss74scg/XuatNhapTon.xls?dl=1

Điều kiện để dùng Advanced Filter là DỮ LIỆU PHẢI CÓ TIÊU ĐỀ
Nếu bạn cố tình chọn vùng dữ liệu không bao gồm tiêu đề thì Excel sẽ tự lấy cell đầu làm tiêu đề ---> dẫn đến cái tiêu đề (giả mạo) này có thể bị trùng với 1 em nào đó
Code sửa lại:
Mã:
Sub Unique()
  Sheets("Nhap").Range("D17:D1100").AdvancedFilter 2, , Sheets("TonKho").Range("C5"), True
End Sub
 
Vầy mới thật là "cực ngắn" đây:
PHP:
Sub Filter_Unique()
  [E1].CurrentRegion.ClearContents
  Range([A1], [A65536].End(xlUp)).AdvancedFilter 2, , [E1], True
  [E1].CurrentRegion.Sort [E1], 1, Header:=1, DataOption1:=1
End Sub
Chảo bác
Em cảm ơn bác về những hướng dẫn của chủ đề này. Em cũng làm thử như hướng dẫn, kết hợp với record marco để ra Code. Em không hiểu sao nó vẫn chưa lọc được danh sách duy nhất.
Ngoài ra vùng dữ liệu để lọc em không muốn "tham lam" lấy cả cột mà muốn chọn lựa thì thế nào ạ?

Mong được giúp đỡ

Link tải file: https://dl.dropbox.com/s/09oke3h6ss74scg/XuatNhapTon.xls?dl=1

Nếu vậy bạn nên dùng Dictionary thì ngon lành mà. Cũng ngắn gọn mà.
Hoặc xử theo kiểu bình dân là sau khi lọc xong xóa nội dung E1 đi, hoặc cut từ E2 đến dòng cuối cột E dán đè lên E1
 
Lần chỉnh sửa cuối:
Code sửa lại:
Mã:
Sub Unique()
  Sheets("Nhap").Range("D17:D1100").AdvancedFilter 2, , Sheets("TonKho").Range("C5"), True
End Sub

Em dùng code trên của bác thay cho
Mã:
 Sheets("Nhap").Range("D18:D1100").AdvancedFilter Action:=xlFilterCopy, CopyToRange:=Range("C6"), Unique:=True
thì thấy: 1. Lần đầu báo lỗi như hình gửi kèm. 2. Chạy lần 2 thì không báo lỗi nhưng trong sheet TonKho các dữ liệu trong sheet bị xóa sạch trước khi danh sách lọc xuât hiện. Ẹc ẹc
 

File đính kèm

  • untitled.JPG
    untitled.JPG
    12 KB · Đọc: 105
Em dùng code trên của bác thay cho
Mã:
 Sheets("Nhap").Range("D18:D1100").AdvancedFilter Action:=xlFilterCopy, CopyToRange:=Range("C6"), Unique:=True
thì thấy: 1. Lần đầu báo lỗi như hình gửi kèm. 2. Chạy lần 2 thì không báo lỗi nhưng trong sheet TonKho các dữ liệu trong sheet bị xóa sạch trước khi danh sách lọc xuât hiện. Ẹc ẹc

Đoán: Nếu bạn dùng thêm đoạn [C6].CurrentRegion.Sort [C6], 1, Header:=0, DataOption1:=1 thì dữ liệu của bạn sẽ... tè lè luôn (và báo lỗi)
Muốn sort thì phải vầy:
Mã:
Sub Unique()
  With Sheets("TonKho")
    Sheets("Nhap").Range("D17:D1100").AdvancedFilter 2, , .Range("C5"), True
    .Range("A6:N1000").Sort .[C6], 1, Header:=0
  End With
End Sub
 
Lần chỉnh sửa cuối:
Đoán: Nếu bạn dùng thêm đoạn [C6].CurrentRegion.Sort [C6], 1, Header:=0, DataOption1:=1 thì dữ liệu của bạn sẽ... tè lè luôn (và báo lỗi)
Muốn sort thì phải vầy:
Mã:
Sub Unique()
  With Sheets("TonKho")
    Sheets("Nhap").Range("D17:D1100").AdvancedFilter 2, , .Range("C5"), True
    .Range("A6:N1000").Sort .[C6], 1, Header:=0
  End With
End Sub

Đúng như bác "đọc vị". Do em cố cài cắm code để sort nên nó báo lỗi thế dù chả có ô nào được Merge (nếu có em cũng chủ động Unmerge)
Em rất thích cách bác giải thích ý nghĩa của từng dòng lệnh hay mã lệnh (dù nó rất đơn giản).
 
Xác định bằng công thức mảng

Em xin góp thêm 1 cách

PHP:
=Sheet1!$A$3:$A$100
PHP:
DK=IF(IF(ISERROR((MATCH(DL,DL,0)=ROW(INDIRECT("$1:"&ROWS(DL))))*(DL<>"")),0,(MATCH(DL,DL,0)=ROW(INDIRECT("$1:"&ROWS(DL))))*(DL<>"")),ROW(INDIRECT("$1:"&ROWS(DL))),"")

Công thức xác định:

PHP:
=IF(ROWS($1:1)<=COUNT(DK),INDEX(DL,SMALL(DK,ROWS($1:1))),"")
 

File đính kèm

Giúp tạo danh sách ngày tháng duy nhất!

Gửi các bạn trên GPE!

Mình có 2 danh sách ngày tháng nằm ở sheet1 và sheet2, mình muốn từ 2 danh sách đó tạo ra 1 danh sách ngày tháng duy nhất tại sheet3.

Mong các bạn giúp đỡ!
 

File đính kèm

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

Back
Top Bottom