如何确定Excel工作簿是否在本地机器上打开,因为可能有多个Excel实例在运行?

我正在尝试修改可能在本地机器上打开或不打开的Excel文件。 机器可能有多个Excel运行实例,或者文件可能在networking上打开(在这种情况下,不会进行修改)。 基于我的理解, getObject(file_path)将会:

  1. 如果文件在本地计算机上打开,则抓取工作簿的打开实例
  2. 如果该文件未打开,则在正在运行的Excel会话中打开该文件
  3. 如果没有任何文件正在运行,则在新的Excel会话中打开文件。

在所有3个实例中,我都能够以某种方式操作文档。 但是,如果我使用getObject(file_path)并且文件尚未打开,则无法调用工作簿的应用程序对象。 任何与getObject(file_path).application给我的错误:

“Object required:'application.Evaluate(…)'”

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

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

对于上下文,下面的程序旨在更新Excel 2007中的数据透视表范围。要进行testing,您需要一个带有数据透视表的工作簿,并将_filename设置为文件path,并将sheet_name设置为包含透视数据的表的名称。

 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 

 set x = GetObject("c:\file.xls") 

做你想要的。

你的做法是错误的。 你使用文件而不是应用程序。 处理文件COM规则适用,一切正常。 请注意,在过去,有一个在COM中的应用程序工作,但没有更多。

这是一个解决方法,我不完全满意,但它似乎工作。 经过testing以查看Excel是否已打开,我testing以查看工作簿窗口是否可见。 再次,不是一个完全可靠的解决scheme,但可能足以满足我的需求。

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

 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