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