thao nguyen01
Thành viên thường trực
- Tham gia
- 8/12/19
- Bài viết
- 241
- Được thích
- 30
Code làm gì cho mệt người hả bạn!
Sub loc()
Dim i, j, App
Set App = Application.WorksheetFunction
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
For i = 2 To Range("A65536").End(xlUp).Row
If App.CountIfs(Range("D:D"), Cells(i, 1).Value, Range("E:E"), Cells(i, 2).Value) = 1 Then
j = j + 1
Cells(j + 1, 7).Value = Cells(i, 1).Value
Cells(j + 1, 8).Value = Cells(i, 2).Value
End If
Next
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
End Sub
Trường hợp dữ liệu "quá lớn" thì sẽ code khác mới chạy nhanh được.Cách đơn giản, dễ hiểu và trực quan nhất:
PHP:Sub loc() Dim i, j, App Set App = Application.WorksheetFunction Application.ScreenUpdating = False Application.Calculation = xlCalculationManual For i = 2 To Range("A65536").End(xlUp).Row If App.CountIfs(Range("D:D"), Cells(i, 1).Value, Range("E:E"), Cells(i, 2).Value) = 1 Then j = j + 1 Cells(j + 1, 7).Value = Cells(i, 1).Value Cells(j + 1, 8).Value = Cells(i, 2).Value End If Next Application.ScreenUpdating = True Application.Calculation = xlCalculationAutomatic End Sub
Chủ yếu là do "tiện" thôi bác!Sao nhiều người khoái tham chiếu cả cột, nếu sau 2003 thì Excel có hơn 1 triệu dòng.
Trường hợp dữ liệu "quá lớn" thì sẽ code khác mới chạy nhanh được.
Khi nào cần nhanh thì xài code nàyKính gửi anh/chị trên diễn đàn,
Em muốn lọc dữ liệu trùng nhau giữa 2 bảng bằng code VBA ạ (trùng tên và số hợp đồng ạ). Nếu không có dữ liệu trùng, sẽ hiện thông báo "Không có dữ liệu trùng nhau" ạ. Anh chị xem giúp em ạ. Em cảm ơn nhiều ạ.
Sub Loc_Trung()
Dim Dic As Object, sArr_1(), sArr_2()
Dim Res(), k As Long, i As Long, ii As Long, tmp As String
Set Dic = CreateObject("scripting.dictionary")
sArr_1 = Range("A2", [A65536].End(3)).Resize(, 2).Value
sArr_2 = Range("D2", [D65536].End(3)).Resize(, 2).Value
ReDim Res(1 To UBound(sArr_2), 1 To 2)
For i = 1 To UBound(sArr_1)
tmp = CStr(sArr_1(i, 2))
Dic(tmp) = Empty
Next
For ii = 1 To UBound(sArr_2)
tmp = CStr(sArr_2(ii, 2))
If Dic.exists(tmp) Then
k = k + 1
Res(k, 1) = sArr_2(ii, 1)
Res(k, 2) = sArr_2(ii, 2)
End If
Next
[G2:H10000].ClearContents
If k Then [G2].Resize(k, 2) = Res Else MsgBox "No Data Found", vbInformation
End Sub
Khi nào cần nhanh thì xài code này
Mã:Sub Loc_Trung() Dim Dic As Object, sArr_1(), sArr_2() Dim Res(), k As Long, i As Long, ii As Long, tmp As String Set Dic = CreateObject("scripting.dictionary") sArr_1 = Range("A2", [A65536].End(3)).Resize(, 2).Value sArr_2 = Range("D2", [D65536].End(3)).Resize(, 2).Value ReDim Res(1 To UBound(sArr_2), 1 To 2) For i = 1 To UBound(sArr_1) tmp = CStr(sArr_1(i, 2)) Dic(tmp) = Empty Next For ii = 1 To UBound(sArr_2) tmp = CStr(sArr_2(ii, 2)) If Dic.exists(tmp) Then k = k + 1 Res(k, 1) = sArr_2(ii, 1) Res(k, 2) = sArr_2(ii, 2) End If Next [G2:H10000].ClearContents If k Then [G2].Resize(k, 2) = Res Else MsgBox "No Data Found", vbInformation End Sub
Khi nào cần nhanh thì xài code này
Mã:Sub Loc_Trung() Dim Dic As Object, sArr_1(), sArr_2() Dim Res(), k As Long, i As Long, ii As Long, tmp As String Set Dic = CreateObject("scripting.dictionary") sArr_1 = Range("A2", [A65536].End(3)).Resize(, 2).Value sArr_2 = Range("D2", [D65536].End(3)).Resize(, 2).Value ReDim Res(1 To UBound(sArr_2), 1 To 2) For i = 1 To UBound(sArr_1) tmp = CStr(sArr_1(i, 2)) Dic(tmp) = Empty Next For ii = 1 To UBound(sArr_2) tmp = CStr(sArr_2(ii, 2)) If Dic.exists(tmp) Then k = k + 1 Res(k, 1) = sArr_2(ii, 1) Res(k, 2) = sArr_2(ii, 2) End If Next [G2:H10000].ClearContents If k Then [G2].Resize(k, 2) = Res Else MsgBox "No Data Found", vbInformation End Sub
Người dùng chỉ việc bấm nút, cớ chi mệt?Code làm gì cho mệt người hả bạn!
Dạ, anh có thể giải thích giúp em đoạn code này để làm gì ạ?
For i = 1 To UBound(sArr_1) 'Duyệt qua bảng 1
tmp = CStr(sArr_1(i, 2)) 'Chuyển đổi dữ liệu về dạng text, đề phòng ổ gà ổ voi khi lội trong nước ngập
Dic(tmp) = Empty 'gán key vào công cụ Dic. Key= số hợp đồng, Item=Empty vì không có gì cần phải ghi nhớ
Next
Em thấy anh cho vòng lặp chạy qua bảng A nhưng lại cho Dic=Empty. Sau đó lại cho vòng lặp chạy qua bảng B nhưng em không hiểu đoạn code nào để dò các dữ liệu của bảng B trùng với bảng A ạ. Anh giải thích giúp em ạ. Em cảm ơn anh.
Xem chú thích màu đỏ
Có lẽ không cần kiểm tra trùng tên. Và tác giả quanghai1969 chỉ lưu "số hợp đồng".Em muốn lọc dữ liệu trùng nhau giữa 2 bảng bằng code VBA ạ (trùng tên và số hợp đồng ạ)
Có lẽ không cần kiểm tra trùng tên. Và tác giả quanghai1969 chỉ lưu "số hợp đồng".
Trong các lệnh
For i = 1 To UBound(sArr_1)
tmp = CStr(sArr_1(i, 2))
Dic(tmp) = Empty
Next
thì Dic(tmp) = Empty đã "nạp" thêm 1 thành phần có chỉ số là tmp và thành phần dữ liệu không có.
Cho nên (chú ý lệnh If )
For ii = 1 To UBound(sArr_2)
tmp = CStr(sArr_2(ii, 2))
If Dic.exists(tmp) Then
Thành phần sau lệnh IF là kiểm tra chỉ số tmp đã có (True), thì lưu thành phần trùng
Bạn nên chạy theo vết (gõ F8 trong cửa sổ edit code), và biết cách mở thêm cửa sổ chứa các tên biến và nội dung đang có trong biến thì thấy (đang chạy theo vết, chọn biến, chọn menu Debug>Add watch...
Viết thêm: Bạn cứ sửa tên 3 người đầu trong bảng 2 và chạy xem để thấy tác giả không xét cột 1
Dạ, lặp đi lặp lại nhiều lần thì code là tốt ạ, chứ code xong xài có 1 lần thì mệt thật đấy ạ! Mà kinh nghiệm cho thấy code cũng chỉ tốt cho người biết code thôi, chứ không biết gì về code, chỉ có sao xài vậy là đôi khi quá mệt luôn ạ!Người dùng chỉ việc bấm nút, cớ chi mệt?
Người code thì coi như nó là tập thể dục hoặc giải trí. Đỡ tốn tiền chơi ghêm.
Bạn dùng ADODB xử lý cho nhanhKính gửi anh/chị trên diễn đàn,
Em muốn lọc dữ liệu trùng nhau giữa 2 bảng bằng code VBA ạ (trùng tên và số hợp đồng ạ). Nếu không có dữ liệu trùng, sẽ hiện thông báo "Không có dữ liệu trùng nhau" ạ. Anh chị xem giúp em ạ. Em cảm ơn nhiều ạ.
Sub DataDuplicate(Optional ByVal Table1 As Range, _
Optional ByVal Table2 As Range, _
Optional ByVal intColumn As Integer = 2, _
Optional ByVal RangeResult As Range)
Dim LR1&, LR2&, rng As Range
LR1 = Table1(1, 1).End(xlDown).Row - Table1(1, 1).Row + 1
LR2 = Table2(1, 1).End(xlDown).Row - Table2(1, 1).Row + 1
Dim D1 As String, D2 As String
Set rng = Table1(1, 1).Resize(LR1, intColumn)
D1 = " SELECT * FROM [" & rng.Parent.Name & "$" & rng.Address(0, 0) & "] TB1 "
Set rng = Table2(1, 1).Resize(LR2, intColumn)
D2 = " [" & rng.Parent.Name & "$" & rng.Address(0, 0) & "] TB2 "
On Error Resume Next
Dim CN As Object, Rs As Object
Set CN = VBA.Interaction.CreateObject("ADODB.Connection")
If Application.Version >= 12 Then
CN.Open ("provider=Microsoft.ACE.OLEDB.12.0;data source='" & rng.Parent.Parent.FullName & "';mode=Read;Extended properties=""Excel 12.0;HDR=No"";")
Else
CN.Open ("Provider=Microsoft.Jet.OLEDB.4.0;Data Source='" & rng.Parent.Parent.FullName & "';mode=Read;Extended Properties=""Excel 8.0;HDR=No"";")
End If
Err.Clear
Set Rs = CN.Execute(D1 & "INNER JOIN " & D2 & " ON TB1.F1 = TB2.F1 and TB1.F2 = TB2.F2")
If Err.Number = 0 Then
If Not Rs.EOF Then
RangeResult.CopyFromRecordset Rs, , intColumn
Else
MsgBox "0"
End If
End If
Rs.Close
Set CN = Nothing: Set Rs = Nothing
Ends:
On Error GoTo 0
End Sub
Bạn dùng ADODB xử lý cho nhanh
Chạy thủ tục:
DataDuplicate [A2], [D2], 2, [G2]
------------------
JavaScript:Sub DataDuplicate(Optional ByVal Table1 As Range, _ Optional ByVal Table2 As Range, _ Optional ByVal intColumn As Integer = 2, _ Optional ByVal RangeResult As Range) Dim LR1&, LR2&, rng As Range LR1 = Table1(1, 1).End(xlDown).Row - Table1(1, 1).Row + 1 LR2 = Table2(1, 1).End(xlDown).Row - Table2(1, 1).Row + 1 Dim D1 As String, D2 As String Set rng = Table1(1, 1).Resize(LR1, intColumn) D1 = " SELECT * FROM [" & rng.Parent.Name & "$" & rng.Address(0, 0) & "] TB1 " Set rng = Table2(1, 1).Resize(LR2, intColumn) D2 = " [" & rng.Parent.Name & "$" & rng.Address(0, 0) & "] TB2 " On Error Resume Next Dim CN As Object, Rs As Object Set CN = VBA.Interaction.CreateObject("ADODB.Connection") If Application.Version >= 12 Then CN.Open ("provider=Microsoft.ACE.OLEDB.12.0;data source='" & rng.Parent.Parent.FullName & "';mode=Read;Extended properties=""Excel 12.0;HDR=No"";") Else CN.Open ("Provider=Microsoft.Jet.OLEDB.4.0;Data Source='" & rng.Parent.Parent.FullName & "';mode=Read;Extended Properties=""Excel 8.0;HDR=No"";") End If Err.Clear Set Rs = CN.Execute(D1 & "INNER JOIN " & D2 & " ON TB1.F1 = TB2.F1 and TB1.F2 = TB2.F2") If Err.Number = 0 Then If Not Rs.EOF Then RangeResult.CopyFromRecordset Rs, , intColumn Else MsgBox "0" End If End If Rs.Close Set CN = Nothing: Set Rs = Nothing Ends: On Error GoTo 0 End Sub
Dạ, em cảm ơn anh. Anh hướng dẫn em cách chạy với ạ. Em bỏ vô module1 bấm chạy thì hiện lên 1 bảng yêu cầu nhập Macro name ạ
Chạy thủ tục:
DataDuplicate [A2], [D2], 2, [G2]
Sub Run_DataDuplicate()
DataDuplicate [A2], [D2], 2, [G2]
End Sub