簡體   English   中英

在VBA中索引(Access 2003) - 字段關聯

[英]Indexing in VBA (Access 2003) - field association

基於此教程頁面 ,Microsoft Access如何知道為索引字段集合創建的字段與TableDef字段集合中的等效字段相關聯?

即使在此Microsoft支持頁面中 ,也會為索引創建字段,然后將其附加到索引的字段集合中:

...
'Copy Indexes
For I1 = 0 To SourceTableDef.Indexes.Count - 1
  Set SI = SourceTableDef.Indexes(I1)
  If Not SI.Foreign Then         ' Foreign indexes are added by relationships
    Set I = T.CreateIndex()
    ' Copy Jet Properties
      On Error Resume Next
      For P1 = 0 To I.Properties.Count - 1
        I.Properties(P1).Value = SI.Properties(P1).Value
      Next P1
      On Error GoTo 0
    ' Copy Fields
      For f1 = 0 To SI.Fields.Count - 1
        Set F = T.CreateField(SI.Fields(f1).Name, T.Fields(SI.Fields(f1).Name).Type)
        I.Fields.Append F
      Next f1
    T.Indexes.Append I
  End If
Next I1
...

我不能簡單地從TableDef的字段集合中添加現有字段嗎? 這沒什么意義,似乎很少有凝聚力。

更新

我實際上在這里測試了代碼這基本上就是我想要做的...但它在這一行上失敗了一個未定義的對象錯誤:

Set F = T.CreateField(SI.Fields(f1).Name, T.Fields(SI.Fields(f1).Name).Type)

...當我們改變這一點時,我們會有各種各樣的樂趣。

(23/05/2016)此外,這個腳本似乎是錯誤的 - 第二個參數實際上不應該存在,這是不必要的。 省略它會導致更多錯誤! 哈! 我的尾巴在哪里? 我覺得我應該追逐它。

解決我的問題

我決定遵循HansUp的主導並使用DDL - 比試圖瀏覽與對象操作相關的問題要容易得多(盡管在最終的代碼設計中存在一定程度的這一點)......

Option Compare Database

Public Const cFname As String = "drm\drmData2016.accdb"
Public Const cPropNotFound As Integer = 3270
Public Const cNotSupported As Integer = 3251
Public Const cInvalidOp As Integer = 3219

Public Sub GenerateTables()

    OpenLog

    'Initalise...
    Dim db As Database
    Dim tdb As Database

    Dim ts As TableDef, tt As TableDef
    Dim p As Property
    Dim f As Field, ft As Field
    Dim i As Index
    Dim s As String, t As String
    Dim x As Boolean

    Set db = CurrentDb
    If Dir$(cFname) <> "" Then Kill cFname
    Set tdb = Application.DBEngine.CreateDatabase(cFname, dbLangGeneral, dbVersion140)
    WriteLog "Created database " & cFname & "."

    'Create the tables...
    WriteLog "Creating TableDefs...", 1
    For Each ts In db.TableDefs
        If Not StartsWith(ts.Name, "msys", "~", "$", "Name AutoCorrect") And Not EndsWith(ts.Name, "_xrep") Then
            s = "SELECT "
            For Each f In ts.Fields
                If Not StartsWith(f.Name, "s_", "S_") Then s = s & "[" & f.Name & "], "
            Next f
            s = Left$(s, Len(s) - 2) & " INTO [" & ts.Name & "] IN """ & cFname & """ FROM [" & ts.Name & "];"
            On Error Resume Next
                db.Execute s
                If Err.Number = 0 Then
                    WriteLog "Created [" & ts.Name & "] using " & s, 2
                Else
                    WriteLog "Failed to create [" & ts.Name & "].", 2
                    WriteLog "Error " & Err.Number & ": " & Err.Description, 3
                    WriteLog "SQL: " & s, 3
                    Err.Clear
                End If
                tdb.TableDefs.Refresh
            On Error GoTo 0
        End If
    Next ts

    'Copy the properties...
    WriteLog "Tables...", 1
    For Each ts In db.TableDefs

        If Not StartsWith(ts.Name, "msys", "~", "$", "Name Autocorrect") And Not EndsWith(ts.Name, "_xrep") Then

            Set tt = tdb.TableDefs(ts.Name)

            WriteLog ts.Name, 2

            WriteLog "Table Properties...", 3
            'Table properties...
            For Each p In ts.Properties
                On Error Resume Next
                    tt.Properties(p.Name) = p.value
                    If Err.Number = 0 Then
                        WriteLog p.Name & " = " & p.value, 3
                    Else
                        WriteLog "Error setting " & p.Name, 3
                        WriteLog Err.Number & ": " & Err.Description, 4
                        Err.Clear
                    End If
                On Error GoTo 0
            Next p

            'Field properties...
            WriteLog "Fields...", 3
            For Each f In ts.Fields
                If Not StartsWith(f.Name, "s_") Then
                    Set ft = tt.Fields(f.Name)
                    WriteLog f.Name, 3
                    WriteLog "Properties...", 3
                    For Each p In f.Properties
                        On Error Resume Next
                            ft.Properties(p.Name).value = p.value
                            Select Case Err.Number
                                Case 0
                                    'Normal...
                                    WriteLog p.Name & " = " & p.value, 4
                                Case cPropNotFound
                                    'Create the property...
                                    Dim np As Property
                                    Set np = ft.CreateProperty(p.Name, p.Type, p.value)
                                    ft.Properties.Append np
                                    ft.Properties.Refresh
                                    WriteLog "Created property " & p.Name & ", value of " & p.value, 4
                                Case cNotSupported, cInvalidOp
                                    'We're not worried about these values - simply skip over them...
                                Case Else
                                    WriteLog "Failed to create or change property " & p.Name & ".", 4
                                    WriteLog "Error " & Err.Number & ": " & Err.Description, 5
                                    Err.Clear
                            End Select
                        On Error GoTo 0
                    Next p
                End If
            Next f

            'Create the indexes...
            WriteLog "Table indexes...", 2
            For Each i In ts.Indexes
                x = False
                s = "CREATE "
                If i.Unique Then s = s & "UNIQUE "
                s = s & "INDEX [" & i.Name & "] ON [" & ts.Name & "] ("
                For Each f In i.Fields
                    s = s & "[" & f.Name & "], "
                    'Just make sure we're not dealing with replication fields...
                    x = StartsWith(f.Name, "s_")
                Next f
                'We only want
                If Not x Then
                    WriteLog i.Name, 3
                    s = Left$(s, Len(s) - 2) & ") "
                    If i.Primary Or i.IgnoreNulls Or i.Required Then
                        s = s & "WITH "
                        If i.Primary Then s = s & "PRIMARY "
                        If i.IgnoreNulls Then s = s & "IGNORE NULL "
                        If i.Required Then s = s & "DISALLOW NULL "
                    End If
                    s = s & ";"
                    On Error Resume Next
                        tdb.Execute s
                        Select Case Err.Number
                            'Note: used select case just in case I need to add extra error numbers...
                            Case 0
                                'Normal...
                                WriteLog "Created index [" & i.Name & "] using " & s, 4
                            Case Else
                                WriteLog "Failed to create index [" & ts.Name & "].", 4
                                WriteLog "Error " & Err.Number & ": " & Err.Description, 5
                                WriteLog "SQL: " & s, 3
                                Err.Clear
                        End Select
                    On Error GoTo 0
                End If
            Next i

        End If

    Next ts

    'Belt and braces tidy-up...
    Set p = Nothing
    Set f = Nothing
    Set ft = Nothing
    Set i = Nothing
    Set ts = Nothing
    Set tt = Nothing

    tdb.Close
    Set tdb = Nothing
    Set db = Nothing

    WriteLog "Closed database."

    WriteLog "Finished.", , False
    CloseLog

End Sub

Microsoft Access如何知道為索引字段集合創建的字段與TableDef字段集合中的等效字段相關聯?

它根據名稱進行檢查。 新索引字段的名稱必須存在於TableDef並且該字段的數據類型必須是可索引的數據類型。 如果不滿足其中任何一個條件,您將收到錯誤消息。

綜上所述:
索引(從DAO的角度來看)基本上是一個具有一些屬性和字段名稱集合+數據類型的數據結構。

不是 tabledef字段的指針集合。

要通過DAO向索引添加字段,需要一個由CreateField()創建的字段對象。

索引對象也有一個.CreateField()方法,這實際上是更常用的方法,我會說。

來自http://allenbrowne.com/func-dao.html#CreateIndexesDAO

'3. Multi-field index.
Set ind = tdf.CreateIndex("FullName")
With ind
    .Fields.Append .CreateField("Surname")
    .Fields.Append .CreateField("FirstName")
End With
tdf.Indexes.Append ind

請注意, 此方法不采用TypeSize參數,僅采用Name 我很高興地承認這一切都有點令人困惑(如果你願意的話,還是語無倫次)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM