【问题标题】:Getting Fullname in Access 2007 through CreateObject("Application")..?通过 CreateObject("Application").. 在 Access 2007 中获取全名?
【发布时间】:2018-06-14 12:06:43
【问题描述】:

我正在尝试通过CreateObject() 方法在Access 2007 中获取当前db 文件的全名,但它不起作用,只是返回一个空字符串。我正在使用CreateObject(),因为该代码将用于多个 Microsoft Office 产品。我认为正确的术语是“后期绑定”..?

例如,这行得通...

Public Sub ThisWorks()
    Dim obj1 As Object
    Dim obj2 As Object
    Set obj1 = Access.Application
    Set obj2 = obj1.CurrentProject
    Debug.Print obj2.FullName
End Sub

...但这不起作用...

Public Sub ThisDoesNotWork()
    Dim obj1 As Object
    Dim obj2 As Object
    Set obj1 = CreateObject("Access.Application") 'This is the only change.
    Set obj2 = obj1.CurrentProject
    Debug.Print obj2.FullName
End Sub

为什么这不起作用..?

是否有任何改变可以使它工作..?

这是一个如何使用它的完整示例...

Public Function CurrentFilename() As String
    
    'This function tries to return the full name & path of the currently open file. It's
    'based on the idea that all (or most?) implementations of VBA have the foundation
    'object called "Application", and a child object with a property that has the
    'filename. The design of this function should allow it to run in any software
    'product that supports VBA. It might even run in VBScript too, but that's not been
    'tested. If any error occurs, or the product cannot return the filename, or the
    'function does not recognize the product, an empty string is returned. As time goes
    'on, more software product names can be added to the Select Case, but for now it's
    'just Microsoft Office products.

    Dim productName As String
    Dim obj1 As Object
    Dim obj2 As Object
    Dim filename As String
    Dim msgStyle As VbMsgBoxStyle
    
    On Error GoTo ErrorHandler
    
    msgStyle = vbApplicationModal + vbExclamation + vbOKOnly
    
    productName = Application.Name
       
    Select Case productName
        Case "Microsoft Access"
            Set obj1 = CreateObject("Access.Application")
            Set obj2 = obj1.CurrentProject
            filename = obj2.FullName
        Case "Microsoft Excel"
            Set obj1 = CreateObject("Excel.Application")
            Set obj2 = obj1.ActiveWorkbook
            filename = obj2.FullName
        Case "Outlook"
            'Returns the path\name of the current default *.OST file.
            Set obj1 = CreateObject("Outlook.Application")
            Set obj2 = obj1.Session.DefaultStore
            filename = obj2.FilePath
        Case "Microsoft PowerPoint"
            Set obj1 = CreateObject("PowerPoint.Application")
            Set obj2 = obj1.ActivePresentation
            filename = obj2.FullName
        Case "Microsoft Publisher"
            Set obj1 = CreateObject("Publisher.Application")
            Set obj2 = obj1.ActiveDocument
            filename = obj2.FullName
        Case "Microsoft Word"
            Set obj1 = CreateObject("Application.ActivePresentation")
            Set obj2 = obj1.Session.DefaultStore
            filename = obj2.FullName
        Case Else
            'Optional error message to the user.
            MsgBox "The current VBA runtime environment is not recognized.", _
                    msgStyle, "Error getting file name."
    End Select
    
    CurrentFilename = filename
    
    Exit Function

ErrorHandler:

    Dim msg As String
    Dim dot As String
    
    'Be a grammar grouch. Ensure the description ends with a period/fullstop.
    If VBA.Right(err.Description, 1) <> "." Then
        dot = "."
    End If
    
    msg = ""
    msg = msg & "Error:" & vbTab & VBA.CStr(err.Number)
    msg = msg & vbCrLf & vbCrLf
    msg = msg & "Desc:" & vbTab & err.Description & dot
    msg = msg & vbCrLf & vbCrLf
    msg = msg & "Source:" & vbTab & err.Source
    
    MsgBox msg, msgStyle, "Runtime Error"
    
    'Do not return from the error. Just exit and return an empty string.
    'Resume Next

End Function

【问题讨论】:

    标签: excel ms-access ms-word vba


    【解决方案1】:

    后期绑定版本不起作用的基本问题是因为您要求 VBA 引擎给您一个新的Application,而不是当前正在运行的。在早期绑定代码中CreateObject("Access.Application") 等价于new Access.Application。 (字符串“Access.Application` 描述了您想要在此处获取的类型。)这不是您想要的。

    另一方面,当您分配Access.Application 时,您将全局变量Access.Application 分配给对象,该对象是当前运行的Access 实例。

    请注意,这是您的方法的普遍问题。

    由于您总是想访问当前的Application 对象,您可以简单地将它分配给obj1 并从那里继续。这始终解析为引用对话框中具有最高优先级的引用,这将是主机应用程序之一。

    【讨论】:

    • 但是如果我使用Set hostApp = Application,编译器会阻塞其他产品的成员。例如,如果我在 Access 中运行它,CurrentProject 的分配工作正常,但它在 Excel ActiveWorkbook 类上出现错误“找不到方法或数据成员”。这就是我尝试使用 CreateObject() 的原因。编译器不会评估库名称,如果允许早期绑定滑过而不会出现错误,那么哪些是无法识别的方法和属性。
    • 您是否将Application 分配给声明为Object 的变量?这很重要。当我在 Excel 中运行您的代码时,将 Set obj1 = Application 拉到 Select 语句前面,它可以完美运行。
    • 哈..!!那钉了它.. !!正如你所说,完美无瑕(现在)。 =-)
    • 仅作为背景说明:您使用Object 类型的变量使代码后期绑定。 Object 类型本身几乎没有定义成员。但是,它是一个所谓的可扩展接口。对于此类接口,编译器从不检查您调用的成员是否实际存在;检查仅在运行时发生。此类接口的另一个示例是ADODB.Connection,它允许您以成员身份访问存储过程。
    • 啊,是的,我明白了。我还没有在野外使用过接口,但是在我去年最终完成学位的四个 Java 学期中,我们对它们进行了很多研究。向前思考:有没有办法知道任何类何时可扩展,例如在对象浏览器中或类似的......?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-26
    • 1970-01-01
    • 1970-01-01
    • 2020-01-27
    • 2012-07-23
    • 1970-01-01
    相关资源
    最近更新 更多