Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/vba/15.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/solr/3.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
Vba 鉴于可能有多个Excel实例正在运行,如何确定本地计算机上是否打开了Excel工作簿?_Vba_Excel - Fatal编程技术网

Vba 鉴于可能有多个Excel实例正在运行,如何确定本地计算机上是否打开了Excel工作簿?

Vba 鉴于可能有多个Excel实例正在运行,如何确定本地计算机上是否打开了Excel工作簿?,vba,excel,Vba,Excel,我正在尝试修改一个Excel文件,该文件可能在本地计算机上打开,也可能没有打开。计算机可能运行多个Excel实例,或者文件可能在网络上打开(在这种情况下,不会进行任何修改)。根据我的理解,getObject(file\u path)将: 如果文件在本地计算机上打开,则获取工作簿的打开实例 如果文件未打开,请在已运行的Excel会话中打开该文件,或者 如果未运行任何Excel会话,请在新Excel会话中打开该文件 在所有3个实例中,我都能够以某些方式操纵文档。但是,如果我使用getObject(f

我正在尝试修改一个Excel文件,该文件可能在本地计算机上打开,也可能没有打开。计算机可能运行多个Excel实例,或者文件可能在网络上打开(在这种情况下,不会进行任何修改)。根据我的理解,
getObject(file\u path)
将:

  • 如果文件在本地计算机上打开,则获取工作簿的打开实例
  • 如果文件未打开,请在已运行的Excel会话中打开该文件,或者
  • 如果未运行任何Excel会话,请在新Excel会话中打开该文件
  • 在所有3个实例中,我都能够以某些方式操纵文档。但是,如果我使用
    getObject(file\u path)
    并且该文件尚未打开,则调用工作簿的应用程序对象时会遇到问题。任何带有
    getObject(文件路径)的行。应用程序
    都会显示错误:

    “所需对象:'应用程序.评估(…)'”

    在工作簿尚未打开的情况下

    我已经解决了这个限制,首先测试是否有任何Excel实例是打开的;如果没有,则我手动创建一个实例,然后使用
    application.Workbooks.open(to_filename,updatelinkcode)
    打开工作簿。下面的代码适用于场景1和3。我可以尝试使用“
    工作簿打开工作簿。在每个场景中打开”
    ;但是,重要的是,在执行结束时,Excel实例和打开的工作簿与脚本启动时相同(因此,实际上,我可能需要确定我是在场景1还是场景2中)

    在上下文中,下面的程序旨在更新Excel2007中的透视表范围。要进行测试,您需要一个包含透视表的工作簿,并将文件路径设置为_filename,将工作表名称设置为包含透视数据的工作表的名称

    Dim UpdateLinksCode, UpdateLinks, destsheet, excel_version, comma_delimit, tab_delimit, t, filename, sheet_name, to_filename, safepath, replacesheet, fso, sourcebook, destbook, objExcel, readfile, filesys, updatepivotrange, please, chart, preserve_formats, live, dest_Excel
    
    to_filename = "C:\Users\user\Desktop\this.xlsx"
    
    'see if Excel is open
    On error resume next
        Set objExcel = GetObject(, "Excel.Application")     
        if Err.Number<>0 then 
            Set dest_Excel = CreateObject("Excel.Application")
            Set destbook = dest_Excel.Workbooks.Open(to_filename,UpdateLinksCode)
            live = false
        else:
            Set destbook = GetObject(to_filename)
            Set dest_Excel = destbook.application
            live = true
        end if
    
    On error goto 0
    sheet_name = "Sheet1"
    dest_Excel.DisplayAlerts = false
    
    'Loop through sheets
    for I = 1 To destbook.Worksheets.Count
        'loop through pivot tables
        for J = 1 to destbook.Worksheets(I).PivotTables.Count
            Set pt = destbook.Worksheets(I).PivotTables(J)
            'Error in attempting to get Pivot data source range
            Set rangeobj = dest_Excel.Evaluate(dest_Excel.ConvertFormula(pt.SourceData, -4150, 1))
            Set datasheet = destbook.Worksheets(rangeobj.Parent.Name)
            'only update pivot tables that have the sheet being updated referenced
            if sheet_name = datasheet.name then
                With datasheet
                    If dest_Excel.WorksheetFunction.CountA(.Cells) <> 0 Then
                        lastrow = .Cells.Find("*", dest_Excel.Range("A1"), -4123, 2,  1, 2, False).Row
                        lastcol = .Cells.Find("*", dest_Excel.Range("A1"), -4123, 2,  2, 2, False).Column
                    Else 
                        lastrow = 1
                        lastcol = 1
                    End If
                End With
                    Set sheet_range = datasheet.Range(datasheet.Cells(1, 1), datasheet.Cells(lastrow, lastcol))
    
                    With pt
                        .ChangePivotCache destbook.PivotCaches.Create(1, sheet_range, 3)
                        .PivotCache.Refresh
                        .HasAutoFormat = False
                        .SaveData = True
                        .PivotCache.RefreshOnFileOpen = True
                        .InGridDropZones = True
                        .RowAxisLayout 1
                    End with
            End if
            destbook.Worksheets(I).PivotTables(J).RefreshTable
         Next
     Next
    
     if not live then
        destbook.save
        destbook.close
        dest_Excel.quit
    end if
    
    Dim UpdateLinksCode、UpdateLinks、destsheet、excel版本、逗号分隔、制表符分隔、t、文件名、工作表名称、to文件名、safepath、replacesheet、fso、sourcebook、destbook、objExcel、readfile、filesys、updatepivotrange、请、图表、保留格式、live、dest excel
    to_filename=“C:\Users\user\Desktop\this.xlsx”
    '查看Excel是否打开
    出错时继续下一步
    Set objExcel=GetObject(,“Excel.Application”)
    如果错误号为0,则
    设置dest_Excel=CreateObject(“Excel.Application”)
    设置destbook=dest\u Excel.Workbooks.Open(到\u文件名,updateLink代码)
    活=假
    其他:
    将destbook=GetObject(设置为文件名)
    设置dest\u Excel=destbook.application
    真实的
    如果结束
    错误转到0
    表\u name=“表1”
    dest_Excel.DisplayAlerts=false
    “在床单上循环
    对于I=1,destbook.Worksheets.Count
    '循环通过数据透视表
    对于J=1,删除book.Worksheets(I).PivotTables.Count
    Set pt=destbook.工作表(I).数据透视表(J)
    '尝试获取透视数据源范围时出错
    Set rangeobj=dest_Excel.Evaluate(dest_Excel.ConvertFormula(pt.SourceData,-4150,1))
    Set datasheet=destbook.Worksheets(rangeobj.Parent.Name)
    '仅更新引用了正在更新的工作表的透视表
    如果图纸名称=datasheet.name,则
    带数据表
    如果dest_Excel.WorksheetFunction.CountA(.Cells)为0,则
    lastrow=.Cells.Find(“*”,dest_Excel.Range(“A1”),-4123,2,1,2,False)。行
    lastcol=.Cells.Find(“*”,dest_Excel.Range(“A1”),-4123,2,2,2,False)。列
    其他的
    lastrow=1
    lastcol=1
    如果结束
    以
    Set sheet_range=datasheet.range(datasheet.Cells(1,1),datasheet.Cells(lastrow,lastcol))
    与pt
    .ChangePivotCache destbook.PivotCaches.Create(1,工作表范围,3)
    .PivotCache.Refresh
    .hasaautoformat=False
    .SaveData=True
    .PivotCache.RefreshOnFileOpen=True
    .IngridRopZones=True
    .RowAxis布局1
    以
    如果结束
    destbook.工作表(I).数据透视表(J).刷新表
    下一个
    下一个
    如果不活着的话
    保存
    结束
    dest_Excel.quit
    如果结束
    
    做你想做的事


    你的方法是错误的。您使用的是文件而不是应用程序。应用COM规则处理文件,一切正常。请注意,在过去,人们确实可以在COM中使用应用程序,但仅此而已。

    这是一个我并不完全满意的解决方案,但它似乎可以工作。在测试Excel是否打开后,我测试工作簿窗口是否可见。同样,这不是一个完全可靠的解决方案,但可能足以满足我的需要

    在下面的代码中,live=“true”对应于场景1,“稍微”对应于场景2,“false”对应于场景3

    出错时继续下一步
    Set dest_Excel=GetObject(,“Excel.Application”)
    如果Err.Number0,则live=“false”
    将destbook=GetObject(设置为文件名)
    设置dest\u Excel=destbook.application
    '如果工作簿可见且路径正确
    如果dest_excel.Windows(destbook.name).visible=-1,dest_excel.Windows(destbook.name).activesheet.parent.fullname=to_filename,则
    live=“true”
    其他的
    如果live“false”,则live=“稍微”
    设置destbook=dest\u Excel.Workbooks.Open(到\u文件名,updateLink代码)
    如果结束
    错误转到0
    
    但是否有一种方法可以调用应用程序方法,即如果文件尚未打开,则仅使用GetObject(文件)对application.Evaluate(…)进行计算?在我的脚本中,有几个实例依赖Excel应用程序,我不知道如何对它们进行编码。
    workbook.application
    。所以
    set x=createObject(“c:file.xls”):x.application.displayalerts
    我不确定你指的是什么
    set x = GetObject("c:\file.xls")
    
    On error resume next
        Set dest_Excel = GetObject(, "Excel.Application")
         if Err.Number<>0 then live = "false"
         Set destbook = GetObject(to_filename)
         Set dest_Excel = destbook.application
        'if workbook is visible and has the right path
        if dest_excel.Windows(destbook.name).visible = -1 and dest_excel.Windows(destbook.name).activesheet.parent.fullname = to_filename then
             live = "true"
        else
            if live <> "false" then live = "somewhat"
            set destbook = dest_Excel.Workbooks.Open(to_filename,UpdateLinksCode)
        end if
    On error goto 0