我在Stack Overflow页面中遇到了这个(修改过的)函数,并试图让它工作而不放弃传递的对象(如果我在第一个例程中严格处理Access.Application
它将工作)。
是的我知道有很多方法可以得到相同的答案(主要来自堆栈上的其他帖子),但是这里有一个将对象传递给我想要掌握的函数的一般概念 - 请忘记该函数检查表的存在。
Function FCN_CheckTblsExist(theDatabase As Access.Application, _
tableName As String) As Boolean
'access.Application.CurrentData.AllTables.Count
'etc is the 'workaround enabling disposal of
'the "theDatabase" object variable
' Presume that table does not exist.
FCN_CheckTblsExist = False
' Define iterator to query the object model.
Dim iTable As Integer
' Loop through object catalogue and compare with search term.
For iTable = 0 To theDatabase.CurrentData.AllTables.Count - 1
If theDatabase.CurrentData.AllTables(iTable).Name = tableName Then
FCN_CheckTblsExist = True
Exit Function
End If
Next iTable
End Function
Function callFCN_CheckTblsExist(tableName As String)
'this is an example of a curried function?--step down in dimensionality
Dim bo0 As String
Dim A As Object
Set A = CreateObject("Access.Application")
bo0 = FCN_CheckTblsExist(A, tableName)
MsgBox tableName & " Exists is " & bo0
End Function
我不知道(theDatabase As Access.Application,
。)部分是否正确,这可能是问题的根源,而不是可能需要的Dim,Set,Object(New?)体操在辅助程序中。也许存在参考库问题(我正在运行Access 2013)。
更新:我不确定以下是否足够强大,但这就是我之前在帖子中所说的内容,这只是为了完整性而放在这里。顺便说一句,这不是一个拆分应用程序,所以也许这就是为什么以下工作。我很欣赏HansUp的帖子,关于这个问题还不够。反正
Public Function FCN_CheckTblsExist(tableName As String) As Boolean 'Call this function once for every table
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Dim appAccess As New Access.Application
Dim theDatabase As Access.Application
' Presume that table does not exist.
FCN_CheckTblsExist = False
' Define iterator to query the object model.
Dim iTable As Integer
For iTable = 0 To Access.Application.CurrentData.AllTables.Count - 1
If Access.Application.CurrentData.AllTables(iTable).Name = tableName Then
FCN_CheckTblsExist = True
Exit Function
End If
Next iTable
End Function
只是想补充一点,我在技术上发布的这个最后一个函数将被视为部分或不干扰,具体取决于通过调用" Access.Application.CurrentData.AllTables来限制函数的范围。&#34 34;作为" theDatabase"的替代,只将Access.Application.CurrentDb.Name创建的特定字符串替换为原始函数...(数据库,...这将是一个真正的完全currying。
无论如何将对象传递给函数,库和它们的方法是本讨论的主要焦点。当我得到DAO问题时,我应该对可能发生的事情有更好的感觉,然后我会相应地发布并标记最佳解决方案。
答案 0 :(得分:2)
问题不在于将Access.Application
对象传递给其他函数。而是创建Access.Application
,然后检查是否存在表,而无需在该Access会话中打开数据库。在这种情况下,theDatabase.CurrentData.AllTables.Count
应该触发错误
2467,“您输入的表达式是指已关闭或不存在的对象。”
我修改了这两个程序并在Access 2010中对它们进行了测试。编译和运行都没有错误,并产生我认为你想要的结果。
Function FCN_CheckTblsExist(theDatabase As Access.Application, _
tableName As String) As Boolean
Dim tdf As DAO.TableDef
Dim blnReturn As Boolean
blnReturn = False
For Each tdf In theDatabase.CurrentDb.TableDefs
If tdf.Name = tableName Then
blnReturn = True
Exit For
End If
Next ' tdf
FCN_CheckTblsExist = blnReturn
End Function
Function callFCN_CheckTblsExist(DbPath As String, tableName As String)
Dim bo0 As Boolean
Dim A As Object
Set A = CreateObject("Access.Application")
A.OpenCurrentDatabase DbPath
bo0 = FCN_CheckTblsExist(A, tableName)
MsgBox tableName & " Exists is " & bo0
Debug.Print tableName & " Exists is " & bo0
A.Quit
Set A = Nothing
End Function
注意在尝试打开 DbPath 数据库之前,我没有包含任何检查 DbPath 数据库的规定。因此,如果为数据库提供不存在的路径,则会出现错误。
DAO参考问题:
DAO 3.6 是最旧的DAO系列。它仅支持较旧的MDB类型数据库。当Access 2007引入ACCDB数据库类型时,引入了新的DAO库( Access数据库引擎对象库,有时称为 ACEDAO )。除了支持ACCDB数据库, ACEDAO 还可以支持较旧的MDB类型。
设置引用时,请勿尝试同时选择它们。
以下是我的项目参考的截图:
当我在立即窗口中检查我的项目引用时,请注意 ACEDAO 甚至被称为 DAO 。我还运行了 callFCN_CheckTblsExist 过程来演示它在没有 DAO 3.6 引用的情况下工作:
这完全基于Access 2010.您使用的是Access 2013,因此您的 ACEDAO 版本号可能会有所不同,但其他所有内容都应该相同。
答案 1 :(得分:1)
以下是一些解决方案以及检查表是否存在的更简单方法:
<强>工作区/数据库; (比使用应用程序快得多)
Function TestFunction_DataBase()
Dim ws As Workspace
Dim db As Database
Set ws = CreateWorkspace("", "admin", "", "dbUseJet")
Set db = ws.OpenDatabase("the db path", , , CurrentProject.Connection)
MsgBox TdefExists_DataBase(db, "the table name")
db.Close
ws.Close
Set db = Nothing
Set ws = Nothing
End Function
Function TdefExists_DataBase(ac As Database, strTableName As String) As Boolean
'check to see if table exists
On Error GoTo ErrHandler
Dim strBS As String
strBS = ac.TableDefs(strTableName).Name
TdefExists_DataBase = True
Exit Function
ErrHandler:
TdefExists_DataBase = False
End Function
<强>应用强>
Function TestFunction_Application()
Dim ac As New Access.Application
ac.OpenCurrentDatabase "the db path"
MsgBox TdefExists_Application(ac, "the table name")
ac.Quit
Set ac = Nothing
End Function
Function TdefExists_Application(ac As Access.Application, strTableName As String) As Boolean
'check to see if table exists
On Error GoTo ErrHandler
Dim strBS As String
strBS = ac.CurrentDb.TableDefs(strTableName).Name
TdefExists_Application = True
Exit Function
ErrHandler:
TdefExists_Application = False
End Function
在当前数据库中:
Function TdefExists(strName As String) As Boolean
'check to see if query exists
On Error GoTo ErrHandler
Dim strBS As String
strBS = CurrentDb.TableDefs(strName).Name
TdefExists = True
Exit Function
ErrHandler:
TdefExists = False
End Function