- Tham gia
- 19/5/19
- Bài viết
- 116
- Được thích
- 9
Sub TongHop()
Dim oCnn As Object
Dim oRst As Object
Dim sRngName As String, fileExcel As String
Dim s As String
Const adOpenStatic = 3
Const adLockOptimistic = 3
Const adCmdText = &H1
Set oCnn = CreateObject("ADODB.Connection")
Set oRst = CreateObject("ADODB.Recordset")
fileExcel = ThisWorkbook.FullName
With oCnn
.Provider = "Microsoft.ACE.OLEDB.12.0"
.ConnectionString = "Data Source=" & fileExcel & ";" & _
"Extended Properties=""Excel 12.0 Xml;HDR=No;"";"
.Open
End With
sRngName = "Data"
s = "SELECT F1 FROM " & sRngName & " GROUP BY F1 " & _
"HAVING Count(F1)>1"
oRst.CursorLocation = 3 'adUseClient
oRst.Open s, oCnn, adOpenStatic, adLockOptimistic, adCmdText
Sheet1.Range("B1:B" & Sheet1.Range("B" & Rows.Count).End(xlUp).Row).ClearContents
Sheet1.Range("B1").CopyFromRecordset oRst
oRst.Close
Set oRst = Nothing
If Not oCnn Is Nothing Then
oCnn.Close
Set oCnn = Nothing
End If
End Sub
Đây là code dùng ADO recordset và chạy câu lệnh truy vấn:
s = "SELECT F1 FROM " & sRngName & " GROUP BY F1 HAVING Count(F1)>1"
Bạn copy code bên dưới vào module.
- Đổi tên "Sheet1" thành Sheet tương ứng trong file của bạn.
- Bạn tạo Name range cho cột dữ liệu cần tổng hợp và đặt tên là "Data".
- Chạy Sub TongHop trong cửa sổ Immediate
Mã:Sub TongHop() Dim oCnn As Object Dim oRst As Object Dim sRngName As String, fileExcel As String Dim s As String Const adOpenStatic = 3 Const adLockOptimistic = 3 Const adCmdText = &H1 Set oCnn = CreateObject("ADODB.Connection") Set oRst = CreateObject("ADODB.Recordset") fileExcel = ThisWorkbook.FullName With oCnn .Provider = "Microsoft.ACE.OLEDB.12.0" .ConnectionString = "Data Source=" & fileExcel & ";" & _ "Extended Properties=""Excel 12.0 Xml;HDR=No;"";" .Open End With sRngName = "Data" s = "SELECT F1 FROM " & sRngName & " GROUP BY F1 " & _ "HAVING Count(F1)>1" oRst.CursorLocation = 3 'adUseClient oRst.Open s, oCnn, adOpenStatic, adLockOptimistic, adCmdText Sheet1.Range("B1:B" & Sheet1.Range("B" & Rows.Count).End(xlUp).Row).ClearContents Sheet1.Range("B1").CopyFromRecordset oRst oRst.Close Set oRst = Nothing If Not oCnn Is Nothing Then oCnn.Close Set oCnn = Nothing End If End Sub
cảm ơn anh nhiều. anh có thể nào viết code mãng đơn giản thôi. tại dữ liệu em ước lượng 5000 dòng thôi. Hiện tại chỉ có 200 tên thôi anh. Nhìn code rối và dài quá. mong anh giúp em
Sub Test()
Dim lastRow As Long
lastRow = Range("A" & Rows.Count).End(xlUp).Row
Range("A1:A" & lastRow).AdvancedFilter Action:=xlFilterCopy, CriteriaRange:=Range("B1:B2"), CopyToRange:=Range("D1"), Unique:=True
End Sub
Sub Xuat_2TroLen()
Dim Nguon, Mang, i
Nguon = Sheet1.Range("A1:A8")
ReDim Mang(UBound(Nguon))
With CreateObject("Scripting.Dictionary")
For i = 1 To UBound(Nguon)
.Item(Nguon(i, 1)) = .Item(Nguon(i, 1)) + 1
If .Item(Nguon(i, 1)) = 2 Then
.Item(2) = .Item(2) + 1
Mang(.Item(2) - 1) = Nguon(i, 1)
End If
Next i
Sheet1.Range("B1").Resize(.Item(2), 1) = WorksheetFunction.Transpose(Mang)
End With
End Sub
Dùng AdvancedFilter hoặc code
Mã:Sub Test() Dim lastRow As Long lastRow = Range("A" & Rows.Count).End(xlUp).Row Range("A1:A" & lastRow).AdvancedFilter Action:=xlFilterCopy, CriteriaRange:=Range("B1:B2"), CopyToRange:=Range("D1"), Unique:=True End Sub
Sub LOCcoban()
Dim sArr(), dArr(), I As Long, K As Long, R As Long, Col As Long
sArr = Range("a1:a1000").Value ' DU LIEU DAU VAO
R = UBound(sArr)
ReDim dArr(1 To R, 1 To 1) ' 3 COT
For I = 1 To R
If Dem trong mang > 1 Then ' DKIEN lam sao hieu de > 1
K = K + 1
For Col = 1 To 1 ' 3 COT
dArr(K, Col) = sArr(I, Col)
Next Col
End If
Next I
' OUTPUT
On Error Resume Next
Range("b1").Resize(R, 1).ClearContents
Range("b1").Resize(K, 1) = dArr ' 3 COT
End Sub
MẢNG chứ không phải "MÃNG".mãng này
Cách thì có vài cách..điều kiện làm sao để >1
Có lẽ là ít nhất có 2 cách :cảm ơn bạn. Thật code dùng AdvancedFilter mình cũng biết , nó có bất tiện là Chậm và có 1 vùng cột phụ. Em đang code mãng này mà không biết sửa điều kiện làm sao để >1
....
If Dem trong mang > 1 Then ' Điều kiện làm sao để đếm > 1
dạ em cảm ơn bác. tại em gõ nhầm. Tại mới tập tành VBA nên bác thông cảm giúp em. Tại em chỉ đang mày mò và range chưa xong, giờ sang mảng chắc em chếtMẢNG chứ không phải "MÃNG".
Cách thì có vài cách..
- Mượn hàm Countif() của worksheetFunction
- Dùng hàm Filter (mảng một chiều) của VBA.
- Dùng các công cụ cho phép nạp các đối tượng của mảng vào thư viện để xét sự tồn tại.. (ví dụ #8)
...
Cuuntif nó chí đếm tên nào xuất hiện >1 lần mà nó không có xuất ra 1 vùng bác à. Em cần xuất ra 1 vùng để cho dễ quán lýThì dùng cái đơn giản là hàm countif() đó.
Lý do tại sao mảng thì đơn giản?cảm ơn anh nhiều. anh có thể nào viết code mãng đơn giản thôi. tại dữ liệu em ước lượng 5000 dòng thôi. Hiện tại chỉ có 200 tên thôi anh. Nhìn code rối và dài quá. mong anh giúp em
Nếu bạn xài E2007 trở lên & có kiến thức vế phương thức FIND() thì cò thể giải quyết vấn đề của bạn qua các bước sau:Em cần giúp đoạn code tên hàng xuất hiện từ 2 lần trở lên không phân biệt chữ Hoa chự thường
Ảnh bên dưới Tên hàng A ,B,C xuất hiện 2 lần trở lên nên xuất kết qua ra cột B1
Dữ liệu hiện tại của File là 5000 dòng. Xin cảm ơn GPE
Code ADO trông rắc rối là vì nó làm một số thủ tục mà thực sự không thuộc về giải thuật của bài. Cũng giống như bạn lên xe thì phải mở khóa, bấm đề pa cho máy nỏ, sang số... các thủ tục không thuộc về con đường bạn cần đi từ A đến B.
Muốn giản gọn, bạn có thể nhờ tác giả lôi ba cái mớ kết nối và đọc recordset vào 1 hàm. Hàm này trả về một mảng dữ liệu. Khi ấy bạn có quyền làm ngơ với mọi rắc rối. Code của bạn chỉ gọi hàm và lấy kết quả. Đổ vào đâu tùy ý.
With CreateObject("Scripting.Dictionary")
...
End With