title: How can I determine if an Excel workbook is open on local machine given that there may be multiple instances of Excel running?
body: <p>I'm trying to modify an Excel file that may or may not be open on the local machine. The machine may have multiple instances of Excel running, or the file may be open on the network (in which case no modification would be made).  Based on my understanding, <code>getObject(file_path)</code>, will either:</p>
  
  <ol>
  <li>grab the open instance of the workbook if the file is open on the local machine</li>
  <li>open the file in an already running Excel session if the file is not open, or </li>
  <li>open the file in a new Excel session if none are running.</li>
  </ol>
  
  <p>In all 3 instances, I'm able to manipulate the document in certain ways.  However, if I use <code>getObject(file_path)</code> and the file is not already open, I'm having trouble calling the application object of the workbook. Any line with <code>getObject(file_path).application</code> gives me the error:</p>
  
  <blockquote>
    <p>"Object required: 'application.Evaluate(...)'" </p>
  </blockquote>
  
  <p>in instances where the Workbook is not already open.  </p>
  
  <p>I've worked around this limitation by first testing if any instances of Excel are open; if none are, then I manually create an instance and then open the workbook using <code>application.Workbooks.Open(to_filename,UpdateLinksCode)</code>.  The code below works in scenarios 1 and 3.  I could try to open the workbook using "<code>Workbooks.open</code>" in every scenario; however it's important that at the end of the execution, the Excel instances and open workbooks are the same as when the script started (so, in effect, I probably need to determine whether I'm in scenario 1 or 2).</p>
  
  <p>For context, the program below is meant to update pivot table ranges in Excel 2007. To test, you need a workbook with a pivot table and set to _filename  as the file path and sheet_name to be the name of the sheet with the pivot data.</p>
  
  <pre><code>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&lt;&gt;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) &lt;&gt; 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
  </code></pre>