Взгляните на .NET ArrayList, у него есть такие методы, как Add
, Contains
, Sort
и т. д. Вы можете создать экземпляр объекта в среде VBS и VBA:
Set ArrayList = CreateObject("System.Collections.ArrayList")
Scripting.Dictionary
тоже может подойти, у него уникальные ключи, метод Exists
позволяет проверить, есть ли уже ключ в словаре.
Однако SQL-запрос через ADODB, вероятно, будет более эффективным в этом случае. В приведенных ниже примерах показано, как получить уникальные строки с помощью SQL-запроса к рабочему листу:
Option Explicit
Sub GetDistinctRecords()
Dim strConnection As String
Dim strQuery As String
Dim objConnection As Object
Dim objRecordSet As Object
Select Case LCase(Mid(ThisWorkbook.Name, InStrRev(ThisWorkbook.Name, ".")))
Case ".xls"
strConnection = "Provider=Microsoft.Jet.OLEDB.4.0;User ID=Admin;Data Source='" & ThisWorkbook.FullName & "';Mode=Read;Extended Properties=""Excel 8.0;HDR=YES;"";"
Case ".xlsm", ".xlsb"
strConnection = "Provider=Microsoft.ACE.OLEDB.12.0;User ID=Admin;Data Source='" & ThisWorkbook.FullName & "';Mode=Read;Extended Properties=""Excel 12.0 Macro;HDR=YES;"";"
End Select
strQuery = "SELECT DISTINCT * FROM [Sheet1$]"
Set objConnection = CreateObject("ADODB.Connection")
objConnection.Open strConnection
Set objRecordSet = objConnection.Execute(strQuery)
RecordSetToWorksheet Sheets(2), objRecordSet
objConnection.Close
End Sub
Sub RecordSetToWorksheet(objSheet As Worksheet, objRecordSet As Object)
Dim i As Long
With objSheet
.Cells.Delete
For i = 1 To objRecordSet.Fields.Count
.Cells(1, i).Value = objRecordSet.Fields(i - 1).Name
Next
.Cells(2, 1).CopyFromRecordset objRecordSet
.Cells.Columns.AutoFit
End With
End Sub
Исходные данные помещаются на Sheet1
, результат выводится на Sheet2
. Единственное ограничение для этого метода заключается в том, что ADODB подключается к книге Excel на диске, поэтому любые изменения должны быть сохранены перед запросом, чтобы получить фактические результаты.
Если вы хотите получить только набор неразличимых строк, то запрос должен быть следующим (просто пример, вы должны поместить свой набор полей в запрос):
strQuery = "SELECT CustomerID, CustomerName, ContactName, Address, City, PostalCode, Country FROM [Sheet1$] GROUP BY CustomerID, CustomerName, ContactName, Address, City, PostalCode, Country HAVING Count(*) > 1"
person
omegastripes
schedule
18.01.2017
Scripting.Dictionary
уникальны, методExists
позволяет проверить, есть ли уже ключ в словаре. - person omegastripes   schedule 18.01.2017Set ArrayList = CreateObject("System.Collections.ArrayList")
, он имеет такие методы, какAdd
,Contains
иSort
. - person omegastripes   schedule 20.01.2017This method performs a linear search; therefore, this method is an O(n) operation, where n is Count.
Поэтому, если я использую его для поиска всех повторяющихся строк, у меня будет O (n ^ 2), а не O (n) при использовании HashSet. Кроме того, я думаю, это возможно только при установленном .NET. - person Sandro   schedule 20.01.2017