【问题标题】:Adding field to MS Access Table using VBA使用 VBA 将字段添加到 MS Access 表
【发布时间】:2014-06-23 14:49:13
【问题描述】:

我需要将计算字段添加到现有表中。我知道有两种方法可以做到这一点,我想知道是否有人对哪种方法最好以及如何使它们起作用有任何意见:

  1. 使用 TableDef.CreateField,然后使用 TableDef.Fields.Append
  2. 使用 DDL Alter Table ADD COLUMN 语句

我尝试使用第一种方法,但我不断收到 3211 错误,因为 Access 无法锁定表。我没有打开桌子。但是,我从一个访问了表中当前存在哪些字段的表单调用 CreateField。

这里是调用 CreateField 的代码:

`
Public Sub AddFieldToTable(strTable As String, strField As String, nFieldType As     Integer)

    Dim db As DAO.Database
    Dim tdf As DAO.TableDef
    Dim fld As DAO.Field

    On Error GoTo ErrorHandler

    Set db = CurrentDb
    Set tdf = db.TableDefs(strTable)
    Set fld = tdf.CreateField(strField, nFieldType)
    tdf.Fields.Append fld

    MsgBox "The field named [" & strField & "] has been added to table [" & strTable & "]."

    Set tdf = Nothing
    Set db = Nothing

    Exit Sub

    ErrorHandler:
        MsgBox "An error has occurred. Number: " & Err.Number & ", description: " &        Err.Description
        Exit Sub

End Sub
`

我在 tdf.fields.append 行收到错误。执行 ALTER TABLE 语句会更好吗?有什么取舍?

【问题讨论】:

    标签: vba ms-access


    【解决方案1】:

    您可以使用 DDL 创建字段:

    长:

    CurrentDb.Execute "ALTER TABLE t ADD COLUMN a Long not null", dbFailOnError 
    

    (添加 NOT NULL IDENTITY(1,1) 以获得自动编号)

    CurrentDb.Execute "ALTER TABLE t ADD COLUMN b text(100)", dbFailOnError 
    

    布尔值:

    CurrentDb.Execute "ALTER TABLE t ADD COLUMN c Bit not null", dbFailOnError 
    

    日期时间:

    CurrentDb.Execute "ALTER TABLE t ADD COLUMN d datetime null", dbFailOnError 
    

    备忘录:

    CurrentDb.Execute "ALTER TABLE t ADD COLUMN e memo null", dbFailOnError 
    

    显然,这很适合函数化,你可以传入你自己的永恒枚举,结合Select,来构造字符串并执行它:

    Public Sub AddFieldToTable(TableName as string, FieldName as string, _
          FieldType as Long, FieldLen as Long, FieldAllowsNull as Boolean)
    
    Dim FieldText as String
    
    Select Case(FieldType)
        Case 0:
            FieldText = "Long"
        Case 1:
            FieldText = "text(" & FieldLen & ")"
        Case 2:
            FieldText = "bit"
        Case 3:
            FieldText = "datetime"
        Case 4:
            FieldText = "memo"
    
    End Select
    
    Dim Sql as string
    Sql = "ALTER TABLE " & TableName & " ADD COLUMN " & FieldName & " " & FieldText
    
    If FieldAllowsNull then
       Sql = Sql & " NULL"
    Else
       Sql = Sql & " NOT NULL"
    End If
    
    CurrentDb.Execute Sql, dbFailOnError
    
    End Sub
    

    【讨论】:

    • 感谢您提供的示例。我尝试使用 db.execute 语句并得到相同的 3211 错误。
    • 3211 表示表被锁定。其他东西正在使用它。您是否将其用作当前表单的记录源?
    • @Lynn Crumbring:DAO 是 Access 的标准,不是吗?
    • 显然 ACEDAO 现在是要走的路;见this SO post
    • 话虽如此,我要骂自己告诉你不要使用DAO;看起来有点相反。
    【解决方案2】:

    我得到了使用 CreateField 或 ALTER TABLE 语句的代码。这里的关键是我使用了一个记录集来访问表的数据(我需要在运行 AddField 方法之前检查该字段是否已经存在和/或包含数据)。在编辑表结构之前,我将 rst.close 语句移动到它工作!没有更多的 3211。

    `
    Set db = CurrentDb
    Set rst = db.OpenRecordset(strTable)
    
    bFieldExists = Field_Exists(rst, strOutputField) ' Custom field_exists in table function
    
    If bFieldExists then nFieldType = rst(strOutputField).Type
    
    If CheckFieldHasValues(strTable, strOutputField) = True Then ' custom CheckField function
        If MsgBox("The output field has values in it. Proceed?", vbYesNo) = vbNo Then Exit Sub
    End If
    
    rst.Close ' Recordset must release the table data before we can alter the table!
    
    If bFieldExists = False Then
        AddFieldToTable strTable, strOutputField, dbCurrency
    End If
    
    Set db = Nothing
    

    【讨论】:

      【解决方案3】:

      我刚刚在一个模块中做了以下工作,效果很好

      Sub AddTableFields()
          Dim db As DAO.Database
          Dim t As DAO.TableDef
          Dim f As DAO.Field
          Set db = CurrentDb
          Set t = db.TableDefs("tl_LongTermStat")
      
          Dim intY As Integer
          Dim intQ As Integer
      
          For intY = 2012 To 2018
              For intQ = 1 To 4
                  Set f = t.CreateField("Y" & intY & "Q" & intQ, dbText, 10)
                  t.Fields.Append f
              Next
          Next
          Debug.Print "AddTableFields() done"
      End Sub
      

      【讨论】:

        猜你喜欢
        • 2017-11-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-16
        • 1970-01-01
        • 2020-03-29
        相关资源
        最近更新 更多