调用应用程序时出现对象错

时间:2018-04-16 09:58:32

标签: vba word-vba

我正在尝试在用户点击按钮时打开Excel文档。有多个按钮可以打开同一个文档,但我希望它在文档已经打开时更改工作表而不是文档的另一个实例

Public objExcel As Object

Sub Main()
    Set objExcel = CreateObject("Excel.Application")
End Sub

Public Sub QE1_Click()
    Call Main
    If objExcel Is Nothing Then
        objExcel.Visible = True
        objExcel.Workbooks.Open "H:\My Documents\Flowchart to Word\Quality and Environmental management system flowchart.xlsm"
        objExcel.Worksheets("Project enquiry").Activate
    Else
        objExcel.Worksheets("Project enquiry").Activate
    End If
End Sub


Public Sub QE2_Click()
    Call Main
    If objExcel Is Nothing Then
        objExcel.Visible = True
        objExcel.Workbooks.Open "H:\My Documents\Flowchart to Word\Quality and Environmental management system flowchart.xlsm"
        objExcel.Worksheets("Order and project release").Activate
    Else
        objExcel.Worksheets("Order and project release").Activate
    End If
End Sub

运行代码会给我一个错误:Application-defined or object-defined error

有人能指出造成错误的原因吗?

3 个答案:

答案 0 :(得分:0)

这段代码:

Set objExcel = CreateObject("Excel.Application")

正在创建一个新的Excel应用程序。然后这个在这里:

objExcel.Worksheets("Project enquiry").Activate

已经假设新应用程序有一个名为Project enquiry的工作表,但这不是真的。因此,您收到1004错误。优化您的业务逻辑,它应该工作。

一般情况下,请尝试删除此条件If objExcel Is Nothing Then,因为objExcel永远不会是Nothing,您正在调用Main来为其分配对象。然后代码可以工作。

答案 1 :(得分:0)

为了让您的代码更有效地工作,我们需要一些高手:

Option Explicit

Public objExcel As Object

Sub Main()

    ' don't need to open another instance of Excel, can use the same instance
    On Error Resume Next
    Set objExcel = GetObject(, "Excel.Application") ' check if there is an open instance of Excel running
    On Error GoTo 0
    If objExcel Is Nothing Then 
        Set objExcel = CreateObject("Excel.Application")
    End If

End Sub

'==================================================================

Public Sub QE1_Click()

    Dim wb As Workbook
    Dim sht As Worksheet

    If objExcel Is Nothing Then
        Main ' call sub that initializes an Excel application object            
    End If

    objExcel.Visible = True
    Set wb = objExcel.Workbooks.Open("H:\My Documents\Flowchart to Word\Quality and Environmental management system flowchart.xlsm")

    On Error Resume Next
    Set sht = wb.Worksheets("Project enquiry")
    On Error GoTo 0
    If sht Is Nothing Then ' sheet doesn't exist >> raise an error
        MsgBox "Workbook doesn't have a sheet named 'Project enquiry'", vbCritical, "Sheet critical error"
    Else ' sheet object created successfully
        sht.Activate  ' <-- NOT SURE why you need to use Activate ?
    End If

End Sub     

注意:应对Sub QE2_Click()应用相同的修改。

答案 2 :(得分:0)

如果要从另一个中控制Office应用程序 - 例如,从Word中控制Excel,首先需要决定是否要使用Intellisense编写代码以及所谓的“早期绑定”或者是否想要使用“后期绑定”,它没有智能感知,但有一个优点,就是你不需要依赖链接到另一个(Excel)VBA代码库。

要使用早期绑定,您必须转到VBA编辑器中的工具/参考,然后激活其他应用程序(Excel)条目旁边的复选框。只有这样你才能使用像Dim wb As Workbook这样的东西。

如果您不想使用早期绑定,那么您必须将事物声明为Dim wb as Object,与您为Excel.Application所做的相同。

为了让代码决定是否需要使用其他应用程序(Excel)的运行实例或启动新实例,请使用方法GetObject。这可用于获取任何正在运行的实例,或检查特定文件。

Set ojbExcel = GetObject(,"Excel.Application")

VS

Set objExcel = GetObject("H:\My Documents\Flowchart to Word\Quality and Environmental management system flowchart.xlsm")

如果您目前无法使用GetObject找到的内容,则会收到错误,您可以检查并随后使用CreateObject启动该应用程序。

Option Explicit

Public objExcel As Object

Sub Main()

    ''' Try to re-use an existing instance
    ' If that instance does not exist, an error will be generated
    ' So temporarily turn off error messages
    On Error Resume Next
    ' check if there is an open instance of Excel running
    Set objExcel = GetObject(, "Excel.Application") 
    ' Turn error messages back on
    On Error GoTo 0
    If objExcel Is Nothing Then 
        Set objExcel = CreateObject("Excel.Application")
    End If    
End Sub

请注意,您通常关闭错误消息 - 您需要一个非常好的理由这样做,并且应该尽快再次打开它。

如果所有按钮基本相同 - 在两个程序中,除了Else步骤外,您显示的内容都是相同的 - 那么您可以减少重复的代码。 (如果您不必在所有程序中进行更改,这也将使维护更简单。)

此外,由于Else操作与If中的上一个操作相同,因此您可以在End If之后添加该操作。

Private Sub ActivateWorksheet(wsName as String)
    If objExcel Is Nothing Then
        objExcel.Visible = True
        objExcel.Workbooks.Open "H:\My Documents\Flowchart to Word\Quality and Environmental management system flowchart.xlsm"
    End If
    objExcel.Worksheets(wsName).Activate
End Sub

Public Sub QE1_Click()
    Call Main
    ActivateWorksheet "Project enquiry"
End Sub


Public Sub QE2_Click()
    Call Main
    ActivateWorksheet "Order and project release"
End Sub