minhcong.tckt
Thành viên thường trực




- Tham gia
- 13/4/11
- Bài viết
- 385
- Được thích
- 36
- Giới tính
- Nam




Em gửi file đính kèm, mong các anh chị trong diễn đàn giúp đỡ
Cột nhập dữ liệu: D, E
Đáp án mẫu tại cột J và K




Function GPE(Rng As Range, DK As Long)
Dim Arr, Res, i As Long, k As Long
Arr = Rng.Value
ReDim Res(1 To UBound(Arr, 1), 1 To 1)
With CreateObject("Scripting.Dictionary")
For i = 1 To UBound(Arr, 1)
If Arr(i, 2) = DK Then
If Not .Exists(Arr(i, 1)) Then
k = k + 1
.Add Arr(i, 1), k
Res(k, 1) = Arr(i, 1)
End If
End If
Next
End With
GPE = Res
End Function
Em chưa biết sử dụng "advanced filter" lắm, mong anh giúp đỡ thêm








Xem clip về advanced filter nhé.
[video=youtube;KXq-NHjy8cw]http://www.youtube.com/watch?v=KXq-NHjy8cw&feature=youtu.be[/video]
Bạn cứ thử đi rồi biết, muốn tiếp cân VBA thì cái đầu tiên đó là phải "dám thử, dám làm, làm sai thì sửa" cứ đoán rồi nghĩ trong khi có đủ công cụ thì ...Ẹc ẹcCông thức mảng như vậy, em sử dụng khoảng 3000 - 5000 dòng có chậm không ạ
Công thức mảng như vậy, em sử dụng khoảng 3000 - 5000 dòng có chậm không ạ

Nhìn vào clip mới dễ làm, nghe chỉ dẫn em làm hoài k ra.Xem clip về advanced filter nhé.
[video=youtube;KXq-NHjy8cw]http://www.youtube.com/watch?v=KXq-NHjy8cw&feature=youtu.be[/video]
nhưng hình như dữ liệu nhiều dòng quá mà dùng advanced filter cho kết quả không chính xác hay sao ấy anh ndu à.
em thử cái file này nó bị vậy đây. Bác thử xem thế nào
em thử cái file này nó bị vậy đây. Bác thử xem thế nào
anh cho em hỏi đoạn code này có nghĩa là gì vậy:Thêm 1 cái cho bạn dùng = ado.
[GPECODE=sql]Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Address = "$I$4" Then
Dim adoConn As Object, adoRs As Object
Set adoConn = CreateObject("ADODB.Connection")
Set adoRs = CreateObject("ADODB.Recordset")
With adoConn
.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=" & ThisWorkbook.FullName & _
";Extended Properties=""Excel 8.0;HDR=No;IMEX=1"";"
.Open
End With
With adoRs
.ActiveConnection = adoConn
.Open "select distinct f1 from [Sheet1$D5:E5000] where f2=" & Target.Value
End With
[H6:H65000].ClearContents
[H6].CopyFromRecordset adoRs
adoRs.Close: Set adoRs = Nothing
adoConn.Close: Set adoConn = Nothing
End If
End Sub
[/GPECODE]
anh cho em hỏi đoạn code này có nghĩa là gì vậy:
.Open "select distinct f1 from [Sheet1$D5:E5000] where f2=" & Target.Value
đặc biệt chổ f1 và f2 đó.
và thêm 1 điều nữa là nếu cột E điều kiện hiện tại giời qua cột f nữa thì nó có được hay không vậy.
cám ơn anh em, post file lên nhờ anh xem nhéĐầu tiên bạn xem đoạn chuổi kết nối có HDR=No thì điều kiện để chọn dữ liệu là không cần lấy dòng đầu tiên để làm tiêu đề cột. Nếu là Yes thì ngược lại. Tôi tạm gỉai thích 2 trường hợp này như sau:
Còn điều kiện lọc như thế nào thì bạn nên đưa file lên để dễ hình dung nhé.
- HDR=No: Vùng dữ liệu [Sheet1$D5:E5000]: Màu đỏ là tên sheet, màu xanh là vùng dữ liệu. Bạn thấy trong vùng dữ liệu có 2 cột D và E, thì ngầm định cột D là F1, E là F2. Nếu vùng dữ liệu có n cột thì sẽ có Fn tương ứng. Lưu ý là Fn<=255. Sau này truy vấn sẽ lấy tên cột là F1, F2...Fn
- HDR=Yes: Vùng dữ liệu [Sheet1$D4:E5000]: Màu đỏ là tên sheet, màu xanh là vùng dữ liệu. Bạn thấy trong vùng dữ liệu có 2 cột D và E, thì ngầm định cell D4 là tên cột thứ nhất ([Danh Sách Mẫu]), E4 là tên cột thứ 2 ([Điều Kiện]). Nếu vùng dữ liệu có n cột thì sẽ có Tên Cột n tương ứng. Lưu ý là Tên Cột n<=255. Sau này truy vấn sẽ lấy tên cột là ([Danh Sách Mẫu]), ([Điều Kiện])...




cám ơn anh em, post file lên nhờ anh xem nhé
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Address = "$K$4" Then
Dim adoConn As Object, adoRs As Object
Set adoConn = CreateObject("ADODB.Connection")
Set adoRs = CreateObject("ADODB.Recordset")
With adoConn
.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=" & ThisWorkbook.FullName & _
";Extended Properties=""Excel 8.0;HDR=No;IMEX=1"";"
.Open
End With
With adoRs
.ActiveConnection = adoConn
.Open "select distinct f1 from [Sheet1$D5:G5000] where f4=" & Target.Value
End With
[J6:H65000].ClearContents
[J6].CopyFromRecordset adoRs
adoRs.Close: Set adoRs = Nothing
adoConn.Close: Set adoConn = Nothing
End If
End Sub



Code này có thể viết gọn hơn đó.PHP:Private Sub Worksheet_Change(ByVal Target As Range) If Target.Address = "$K$4" Then Dim adoConn As Object, adoRs As Object Set adoConn = CreateObject("ADODB.Connection") Set adoRs = CreateObject("ADODB.Recordset") With adoConn .ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;" & _ "Data Source=" & ThisWorkbook.FullName & _ ";Extended Properties=""Excel 8.0;HDR=No;IMEX=1"";" .Open End With With adoRs .ActiveConnection = adoConn .Open "select distinct f1 from [Sheet1$D5:G5000] where f4=" & Target.Value End With [J6:H65000].ClearContents [J6].CopyFromRecordset adoRs adoRs.Close: Set adoRs = Nothing adoConn.Close: Set adoConn = Nothing End If End Sub
anh hải ơi, code của anh ok , nhưng có 1 điều nhờ anh sửa lại giúp vì nếu cột điều kiện là số thì đúng còn nếu dạng text thi code báo lỗiPHP:Private Sub Worksheet_Change(ByVal Target As Range) If Target.Address = "$K$4" Then Dim adoConn As Object, adoRs As Object Set adoConn = CreateObject("ADODB.Connection") Set adoRs = CreateObject("ADODB.Recordset") With adoConn .ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;" & _ "Data Source=" & ThisWorkbook.FullName & _ ";Extended Properties=""Excel 8.0;HDR=No;IMEX=1"";" .Open End With With adoRs .ActiveConnection = adoConn .Open "select distinct f1 from [Sheet1$D5:G5000] where f4=" & Target.Value End With [J6:H65000].ClearContents [J6].CopyFromRecordset adoRs adoRs.Close: Set adoRs = Nothing adoConn.Close: Set adoConn = Nothing End If End Sub




anh hải ơi, code của anh ok , nhưng có 1 điều nhờ anh sửa lại giúp vì nếu cột điều kiện là số thì đúng còn nếu dạng text thi code báo lỗi
Open "select distinct f1 from [Sheet1$D5:G5000] where f4=" & Target.Value
nhờ anh giúp em nhé
cám ơn anh
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Address = "$K$4" Then
Dim arr(), dk, i
dk = Target.Value
arr = Range("D5", [G65536].End(3)).Value
With CreateObject("scripting.dictionary")
For i = 1 To UBound(arr)
If arr(i, 4) = dk Then
If Not .exists(arr(i, 1)) Then
.Add (arr(i, 1)), ""
End If
End If
Next
[J6:J1000].ClearContents
If .Count = 0 Then End
[J6].Resize(.Count) = Application.Transpose(.keys)
End With
End If
End Sub
dạ tại em còn gà anh ơi, e không nghĩ đến được vậy. bớt nóng anh nhé. cám ơn anh nhiềuChứ mắc gì không xài VBA cho khỏe thân, bày đặt lọc bằng ADO cho khổ vậy? ADO kén dữ liệu lắm. Chỉ cần 1 cái khoảng trắng cũng chết.
Thay vì dùng ADO thì mình dùng VBA phổ thông cho nhẹ nhàng
Cũng nên biết người biết ta thì đở cực thân. Thậm chí chữ K phải viết hoa trong khi bắt sự kiện change bạn còn không biết mà muốn vọc ADO thì làm ăn gì nổi. Cho xin đi.
PHP:Private Sub Worksheet_Change(ByVal Target As Range) If Target.Address = "$K$4" Then Dim arr(), dk, i dk = Target.Value arr = Range("D5", [G65536].End(3)).Value With CreateObject("scripting.dictionary") For i = 1 To UBound(arr) If arr(i, 4) = dk Then If Not .exists(arr(i, 1)) Then .Add (arr(i, 1)), "" End If End If Next [J6:J1000].ClearContents If .Count = 0 Then End [J6].Resize(.Count) = Application.Transpose(.keys) End With End If End Sub



Text thì cho nó dấu nháy đơn bao quanh là ok thôi.anh hải ơi, code của anh ok , nhưng có 1 điều nhờ anh sửa lại giúp vì nếu cột điều kiện là số thì đúng còn nếu dạng text thi code báo lỗi
Open "select distinct f1 from [Sheet1$D5:G5000] where f4=" & Target.Value
nhờ anh giúp em nhé
cám ơn anh
Open "select distinct f1 from [Sheet1$D5:G5000] where f4='" & Target.Value & "'"
em cũng làm đúng như anh nhung vẫn lỗi anh àText thì cho nó dấu nháy đơn bao quanh là ok thôi.




Với dữ liệu đơn giản thì có thể tham khảo code này rồi tuỳ biếnem cũng làm đúng như anh nhung vẫn lỗi anh à
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Address = "$K$4" Then
[J6:J1000].ClearContents
With Range("G5", [G65536].End(3))
.AutoFilter 1, Target
.Offset(, -3).SpecialCells(12).Copy [J6]
.AutoFilter
End With
Range("J6", [J65536].End(3)).RemoveDuplicates 1
End If
End Sub
cám ơn anh quang hảiVới dữ liệu đơn giản thì có thể tham khảo code này rồi tuỳ biến
PHP:Private Sub Worksheet_Change(ByVal Target As Range) If Target.Address = "$K$4" Then [J6:J1000].ClearContents With Range("G5", [G65536].End(3)) .AutoFilter 1, Target .Offset(, -3).SpecialCells(12).Copy [J6] .AutoFilter End With Range("J6", [J65536].End(3)).RemoveDuplicates 1 End If End Sub
Nếu phải FILTER thì mình thích Advanced Filter hơn:Với dữ liệu đơn giản thì có thể tham khảo code này rồi tuỳ biến
PHP:Private Sub Worksheet_Change(ByVal Target As Range) If Target.Address = "$K$4" Then [J6:J1000].ClearContents With Range("G5", [G65536].End(3)) .AutoFilter 1, Target .Offset(, -3).SpecialCells(12).Copy [J6] .AutoFilter End With Range("J6", [J65536].End(3)).RemoveDuplicates 1 End If End Sub
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Address = "$K$4" Then
[IV1] = [G4]: [IV2] = Target.Value: [J5] = [D4]
[D4:G1000].AdvancedFilter 2, [IV1:IV2], [J5], True
[IV1:IV2].ClearContents
End If
End Sub
anh ơi code của anh thì ok nhưng vẫn còn lỗi này anh ah. ví dụ trong bảng điều kiện có chữ a, và a1 thi luc chọn a thì nó cho ra cả a1 luôn vậy nhờ anh xem lại đoạn này giúp em nhéNếu phải FILTER thì mình thích Advanced Filter hơn:
Mã:Private Sub Worksheet_Change(ByVal Target As Range) If Target.Address = "$K$4" Then [IV1] = [G4]: [IV2] = Target.Value: [J5] = [D4] [D4:G1000].AdvancedFilter 2, [IV1:IV2], [J5], True [IV1:IV2].ClearContents End If End Sub
anh ơi code của anh thì ok nhưng vẫn còn lỗi này anh ah. ví dụ trong bảng điều kiện có chữ a, và a1 thi luc chọn a thì nó cho ra cả a1 luôn vậy nhờ anh xem lại đoạn này giúp em nhé
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Address = "$K$4" Then
[IV1] = [G4]: [COLOR=#ff0000][IV2] = "'=" & Target.Value[/COLOR]: [J5] = [D4]
[D4:G1000].AdvancedFilter 2, [IV1:IV2], [J5], True
[IV1:IV2].ClearContents
End If
End Sub
đúng rồi đó anh, cám ơn anh nhìu nhìuBạn cho file có dữ liệu tổng quát lên đi. Ai mà biết dữ liệu thật còn có trường hợp nào nữa chứ
-----------------
Tạm thời thì sửa thành vầy:
Chỗ màu đỏ là chỗ sửa lạiMã:Private Sub Worksheet_Change(ByVal Target As Range) If Target.Address = "$K$4" Then [IV1] = [G4]: [COLOR=#ff0000][IV2] = "'=" & Target.Value[/COLOR]: [J5] = [D4] [D4:G1000].AdvancedFilter 2, [IV1:IV2], [J5], True [IV1:IV2].ClearContents End If End Sub