Access VBA(2003)中是否有方法将COM引用转换为整数,并调用AddRef / Release? (它给出错误“标记为受限制的函数或接口,或者该函数使用Visual Basic中不支持的自动化类型”)
我正在使用第三方COM对象,它不能处理在单个进程中实例化两次(这是一个已知错误)。因此,我考虑将引用存储为隐藏表单上的控件标题,以防止程序重置清除所有VB变量。
编辑:我认为可以使用未记录的ObjPtr完成对int的强制转换,然后使用CopyMemory API再次返回,并且可以隐式调用AddRef / Release。但有更好的方法吗?加载项是否受程序重置保护?
答案 0 :(得分:0)
代码重置后是否存在问题,或者一旦代码重置,它是否无法重新初始化?
对于第一个问题,将顶级对象包装在函数中并在内部使用STATIC变量来缓存引用。如果STATIC变量为Nothing,则重新初始化。这是我用来缓存对本地数据库的引用的函数:
Public Function dbLocal(Optional bolInitialize As Boolean = True) +
As DAO.Database
' 2003/02/08 DWF added comments to explain it to myself!
' 2005/03/18 DWF changed to use Static variable instead
' uses GoTos instead of If/Then because:
' error of dbCurrent not being Nothing but dbCurrent being closed (3420)
' would then be jumping back into the middle of an If/Then statement
On Error GoTo errHandler
Static dbCurrent As DAO.Database
Dim strTest As String
If Not bolInitialize Then GoTo closeDB
retryDB:
If dbCurrent Is Nothing Then
Set dbCurrent = CurrentDb()
End If
' now that we know the db variable is not Nothing, test if it's Open
strTest = dbCurrent.Name
exitRoutine:
Set dbLocal = dbCurrent
Exit Function
closeDB:
If Not (dbCurrent Is Nothing) Then
Set dbCurrent = Nothing
End If
GoTo exitRoutine
errHandler:
Select Case err.Number
Case 3420 ' Object invalid or no longer set.
Set dbCurrent = Nothing
If bolInitialize Then
Resume retryDB
Else
Resume closeDB
End If
Case Else
MsgBox err.Number & ": " & err.Description, vbExclamation, "Error in dbLocal()"
Resume exitRoutine
End Select
End Function
您在代码中的任何一个位置:
Dim db As DAO.Database
Set db = CurrentDB()
Set db = DBEngine(0)(0)
db.Execute "[SQL DML]", dbFailOnError
...你可以用以下内容替换整个内容:
dbLocal.Execute "[SQL DML]", dbFailOnError
...您不必担心在应用程序打开时或代码重置后初始化它 - 它会自我修复,因为它会检查静态内部变量并在需要时重新初始化。
唯一需要注意的是,当您关闭应用程序时,需要将bolInitialize参数设置为False进行调用,因为这样可以清除引用,因此当应用程序超出范围时,不存在应用程序挂起的风险app关闭。
对于另一个问题,我真的怀疑VBA中有任何解决方案,除非你可以进行API调用并终止外部进程。但我认为这是一个长镜头。