Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/vba/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ms access 访问:在程序重置期间保留COM引用?_Ms Access_Vba_Com_Ms Access 2003 - Fatal编程技术网

Ms access 访问:在程序重置期间保留COM引用?

Ms access 访问:在程序重置期间保留COM引用?,ms-access,vba,com,ms-access-2003,Ms Access,Vba,Com,Ms Access 2003,Access VBA(2003)中是否有方法将COM引用强制转换为整数,并调用AddRef/Release?(给出错误“函数或接口标记为受限,或函数使用Visual Basic不支持的自动化类型”) 我使用的是一个第三方COM对象,它不会处理在一个进程中被实例化两次的问题(这是一个已知的bug)。因此,我考虑将引用存储为隐藏窗体上控件的标题,以防止程序重置清除所有VB变量 Edit:我认为可以使用未记录的ObjPtr将其转换为int,然后使用CopyMemory API再次转换为int,并且可以

Access VBA(2003)中是否有方法将COM引用强制转换为整数,并调用AddRef/Release?(给出错误“函数或接口标记为受限,或函数使用Visual Basic不支持的自动化类型”)

我使用的是一个第三方COM对象,它不会处理在一个进程中被实例化两次的问题(这是一个已知的bug)。因此,我考虑将引用存储为隐藏窗体上控件的标题,以防止程序重置清除所有VB变量


Edit:我认为可以使用未记录的ObjPtr将其转换为int,然后使用CopyMemory API再次转换为int,并且可以隐式调用AddRef/Release。但是有更好的办法吗?外接程序是否受到程序重置的保护?

是代码重置后仍然存在问题,还是代码重置后无法重新初始化

对于第一个问题,将顶级对象包装在函数中,并在内部使用静态变量来缓存引用。如果静态变量为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的情况下进行调用,因为这会清理引用,因此当应用程序关闭时超出范围时,不会出现应用程序挂起的风险


对于另一个问题,我真的怀疑VBA中是否有任何解决方案,除非您可以进行API调用并终止外部进程。但我认为这是一个长期问题。

这是第二个问题。此外,它是一个进程内COM对象,因此不存在“杀死外部进程”的问题。顺便说一句,如果你用“”开始你的代码注释,那么它们在VB中是有效的,在标记中看起来是合理的。在标记中,这些注释对我来说很好。和#在VBA中不是有效的注释字符。问题是markdown将“视为字符串分隔符,字符串可以跨多行。除非我们看到不同的东西,否则您的一些代码是红色的,好像它是一个(很长的)字符串。因此,我用第二个“结束字符串,用a#开始markdown认为是注释的内容。(VB不知道并不重要——这只是评论的一部分)我一定很愚蠢,但我不能在
'
上得到任何变化,从而导致我文章中代码注释的格式出现任何差异。你能编辑我的一行代码注释来说明你的意思吗?