[英]Adding field to MS Access Table using VBA
I need to add a calculated field to an existing table. 我需要将一个计算字段添加到现有表中。 I am aware of two ways to do this and I'm wondering if anyone has any input on which is best and how to make them work:
我知道有两种方法可以做到这一点,我想知道是否有人有任何关于哪个是最好的输入以及如何使它们工作:
I tried using the first method, but I keep getting a 3211 error because Access could not lock the table. 我尝试使用第一种方法,但我一直收到3211错误,因为Access无法锁定表。 I don't have the table open.
我没有打开桌子。 However, I am calling CreateField from a form that has accessed which fields currently exist in the table.
但是,我从一个访问表中当前存在的字段的表单调用CreateField。
Here's the code for calling 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
`
I get the error on the tdf.fields.append line. 我在tdf.fields.append行上得到了错误。 Would executing an ALTER TABLE statement be better?
执行ALTER TABLE语句会更好吗? What are the tradeoffs?
有什么权衡?
You can use DDL to create fields: 您可以使用DDL创建字段:
Long: 长:
CurrentDb.Execute "ALTER TABLE t ADD COLUMN a Long not null", dbFailOnError
(tack on NOT NULL IDENTITY(1,1)
for an autonumber) (针对自动编号的
NOT NULL IDENTITY(1,1)
)
CurrentDb.Execute "ALTER TABLE t ADD COLUMN b text(100)", dbFailOnError
Boolean: 布尔:
CurrentDb.Execute "ALTER TABLE t ADD COLUMN c Bit not null", dbFailOnError
DateTime: 约会时间:
CurrentDb.Execute "ALTER TABLE t ADD COLUMN d datetime null", dbFailOnError
Memo: 备忘录:
CurrentDb.Execute "ALTER TABLE t ADD COLUMN e memo null", dbFailOnError
Obviously, this lends itself well to functionalization, and you could just pass in your own eternal enum, combined with a Select
, to construct the string and execute it: 显然,这很适合功能化,你可以传入你自己的永恒枚举,结合
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
I got the code working with either the CreateField or the ALTER TABLE statement. 我得到的代码使用CreateField或ALTER TABLE语句。 The key here was that I had used a recordset to access the table's data (I needed to check whether the field already existed and/or contained data before I ran the AddField method).
这里的关键是我使用了一个记录集来访问表的数据(在运行AddField方法之前,我需要检查字段是否已经存在和/或包含数据)。 I moved the rst.close statement up to before I edited the table structure and it worked!
在我编辑表结构之前,我将rst.close语句移动到了它的工作状态! No more 3211.
不再是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
I just did the following in a module and it works fine 我只是在一个模块中做了以下,它工作正常
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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.