在回答这个问题的过程中,我写了一个简单的函数来测试一个MS Access表是否包含提供的数组中的所有字段:
Function ValidateFields(strTbl As String, arrReq As Variant) As Boolean
Dim fld
Dim fldTmp As Field
On Error GoTo err
For Each fld In arrReq
Set fldTmp = CurrentDb.TableDefs(strTbl).Fields(fld)
Next fld
ValidateFields = True
err:
Exit Function
End Function
Run Code Online (Sandbox Code Playgroud)
?ValidateFields("TempTable", Array("Field1", "Field2", "Field3"))
False
Run Code Online (Sandbox Code Playgroud)
这按预期执行,但是,为了提高效率,我尝试将 Fields Collection 分配给For Each循环外的变量:
Function ValidateFields(strTbl As String, arrReq As Variant) As Boolean
Dim fld
Dim fldTmp As Field
Dim colFld As Fields
Set colFld = CurrentDb.TableDefs(strTbl).Fields
On Error GoTo err
For Each fld In arrReq
Set fldTmp = colFld(fld)
Next fld
ValidateFields = True
err:
Exit Function
End Function
Run Code Online (Sandbox Code Playgroud)
现在,如果我注释掉该On Error语句,则会收到以下错误,其中Set fldTmp = colFld(fld)突出显示的行是原因:
运行时错误“3420”:
对象无效或不再设置。
为什么变量colFld会在For Each循环中丢失其值?
这里的问题是:
CurrentDb创建DAO.Database当前打开的数据库的对象。你TableDef是其中的一员。
但是由于您没有存储该对象,因此在将 tabledef 复制到对象后,它会立即关闭并释放,并且成员也将被释放。
存储数据库对象,成员也会持久化:
Function ValidateFields(strTbl As String, arrReq As Variant) As Boolean
Dim fld
Dim fldTmp As Field
Dim colFld As Fields
Dim db As DAO.Database
Set db = CurrentDb
Set colFld = db.TableDefs(strTbl).Fields
On Error GoTo err
For Each fld In arrReq
Set fldTmp = colFld(fld)
Next fld
ValidateFields = True
err:
Exit Function
End Function
Run Code Online (Sandbox Code Playgroud)