Excel VBAで使用するsetデータ構造を探しています。私が今までに見つけたのは、mapと思われるScripting.Dictionaryです。VBAでデータ構造を設定
VBAにも同様の設定がありますか?
基本的には、特定の値が既に追加されているかどうかを調べるのに有効なデータ構造を探しています。
Excel VBAで使用するsetデータ構造を探しています。私が今までに見つけたのは、mapと思われるScripting.Dictionaryです。VBAでデータ構造を設定
VBAにも同様の設定がありますか?
基本的には、特定の値が既に追加されているかどうかを調べるのに有効なデータ構造を探しています。
あなたは、コレクションを使用して、次の機能を行うことができ、コレクションが一意のキー識別子を強制:
Public Function InCollection(Col As Collection, key As String) As Boolean
Dim var As Variant
Dim errNumber As Long
InCollection = False
Set var = Nothing
Err.clear
On Error Resume Next
var = Col.Item(key)
errNumber = CLng(Err.Number)
On Error GoTo 0
'5 is not in, 0 and 438 represent incollection
If errNumber = 5 Then ' it is 5 if not in collection
InCollection = False
Else
InCollection = True
End If
End Function
詳細な回答ありがとうございます! 'Scripting.Dictionary'を使うこととの違いは何ですか?ディクショナリを使用する方が、「存在する」という方法があるので、直感的に思えます。コレクションと辞書の両方がキー値構造であるように見えるので、私は別のデータ構造を探していました。キーが必要です。 – Sandro
これは、コレクション対辞書に関する優れた情報源です(https://www.experts-exchange.com/articles/3391/Using-the-Dictionary-Class-in-VBA.html)。実際には両方ともこの目的のためにうまくいくので、どちらがより快適であるかを選んでください。 – Zerk
は.NET ArrayListを見てみましょう、それはAdd
、Contains
、Sort
などのような方法を持っているあなたは、インスタンス化することができますVBSやVBA環境内のオブジェクト:
Set ArrayList = CreateObject("System.Collections.ArrayList")
Scripting.Dictionary
もニーズに合わせて、それが一意キーを持っている、Exists
方法すべてキーがすでに辞書に入っているかどうかを確認します。
しかし、ADODB経由のSQLリクエストは、おそらくこのケースではより効率的です。以下の例は、ワークシートに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"
うわー、私はExcel内でSQLクエリを実行することが可能であるかどうかはわかりませんでした。私の使用事例では、検証のために使用するので、保存せずに動作するはずです。これは何とかこの方法で可能ですか?私は、私はセットのデータ構造を求めているので、私はこの答えを受け入れることができないと思う。これが受け入れられた答えであれば、データ構造を探している人にとってはミスリーディングになるでしょう。 – Sandro
@Sandroどのような種類の検証が必要かを明確にしてください。有効な行と無効な行はどのように表示されるべきですか? – omegastripes
あなたの答えは、まず保存する必要があることを除いて、私がやろうとしていたことをするようです。これまでのところ、行の表示方法はまだ決まっていません。これまではScripting.Dictionaryを使用していましたが、これはSetではありませんが、処理が完了しました。 – Sandro
単にセット様の操作だけを公開するScripting.Dictionary
のラッパーを記述します。
clsSet
Option Explicit
Private d As Scripting.Dictionary
Private Sub Class_Initialize()
Set d = New Scripting.Dictionary
End Sub
Public Sub Add(var As Variant)
d.Add var, 0
End Sub
Public Function Exists(var As Variant) As Boolean
Exists = d.Exists(var)
End Function
Public Sub Remove(var As Variant)
d.Remove var
End Sub
そして、あなたはそうのようにそれを使用することができます:予想通り、真偽とFalse出力し
mdlMain
Public Sub Main()
Dim s As clsSet
Set s = New clsSet
Dim obj As Object
s.Add "A"
s.Add 3
s.Add #1/19/2017#
Debug.Print s.Exists("A")
Debug.Print s.Exists("B")
s.Remove #1/19/2017#
Debug.Print s.Exists(#1/19/2017#)
End Sub
。
多分、あなたはおそらく配列 – Storax
のコレクションを意味するでしょうか?コレクションですか?それともクラス? – Pierre
重複を見つけようとしています。限り、私は配列とコレクションまたはインデックスされていないことを理解しているので、特定の値が存在しているかどうかを見つけるためにすべてを横断しなければならないだろう。 – Sandro