New Instance Of Excel

Jonmo1

MrExcel MVP
Joined
Oct 12, 2006
Messages
44,061
OK, I have a problem with opening new instances of excel.

I have a macro that uses SendKeys (I know, I didn't write it) to open a company program. It runs some reports and exports them to excel spreadsheets. The problem is that when it exports, it exports into a NEW Excel Application. Like going to Start - Programs - Office - Excel. Instead of going to File - New from within the already open instance of excel.

That's just how the company's program works, and I can't change it. Even if I do it by hand, it creates a NEW excel instance for each export.

Now this causes a problem because I use a Personal.xls file. The person who wrote the macro didn't. So each time it opens a new instance of excel, it tries to open my personal.xls file. Creating a Dialog Box saying personal.xls is already open, do you want a read only copy?

That disrupts the Synchronization of the SendKeys.


Now, I can't just add another keystroke to say cancel to the dialog because I'm not the only one using this macro, and not everyone uses a personal.xls file.

I'm thinking I could make a loop to go through all the open books, and if it's name is personal.xls, save it and close it. Then proceed with the export.

But I can't figure out how to Loop through all instances of excel.

I've done

for each wb in workbooks
if wb.name = "Personal.xls" then
wb.save
wb.close
end if
next wb

but that only loops through the workbooks in the Original instance of excel.

I've tried
Workbooks("Personal.xls").Save
Workbooks("Personal.xls").Close

but it says Subscript out of range.

How do you loop through each instance of excel, THEN loop each wb within that instance?


Thanks.
 

Excel Facts

Copy PDF to Excel
Select data in PDF. Paste to Microsoft Word. Copy from Word and paste to Excel.
Taken from this post.

Paste all of the following in a standard module alone:
<table width="100%" border="1" bgcolor="White" style="filter:progid:DXImageTransform.Microsoft.Gradient(endColorstr='#C0CFE2', startColorstr='#FFFFFF', gradientType='0');"><tr><TD><font size="2" face=Courier New>  <font color="#0000A0">Option</font> <font color="#0000A0">Explicit</font>

  <font color="#0000A0">Private</font> <font color="#0000A0">Declare</font> <font color="#0000A0">Function</font> GetRunningObjectTable <font color="#0000A0">Lib</font> "ole32.dll" (ByVal dwReserved <font color="#0000A0">As</font> Long, pROT <font color="#0000A0">As</font> Long) <font color="#0000A0">As</font> <font color="#0000A0">Long</font>
  <font color="#0000A0">Private</font> <font color="#0000A0">Declare</font> <font color="#0000A0">Function</font> CreateBindCtx <font color="#0000A0">Lib</font> "ole32.dll" (ByVal dwReserved <font color="#0000A0">As</font> Long, pBindCtx <font color="#0000A0">As</font> Long) <font color="#0000A0">As</font> <font color="#0000A0">Long</font>
  <font color="#0000A0">Private</font> <font color="#0000A0">Declare</font> <font color="#0000A0">Sub</font> CoTaskMemFree <font color="#0000A0">Lib</font> "ole32.dll" (ByVal pv <font color="#0000A0">As</font> Long)

  <font color="#0000A0">Private</font> <font color="#0000A0">Declare</font> <font color="#0000A0">Sub</font> OleInitialize <font color="#0000A0">Lib</font> "ole32.dll" (pvReserved <font color="#0000A0">As</font> Any)
  <font color="#0000A0">Private</font> <font color="#0000A0">Declare</font> <font color="#0000A0">Sub</font> OleUninitialize <font color="#0000A0">Lib</font> "ole32.dll" ()

  <font color="#0000A0">Private</font> <font color="#0000A0">Declare</font> <font color="#0000A0">Function</font> CallWindowProc <font color="#0000A0">Lib</font> "user32" <font color="#0000A0">Alias</font> "CallWindowProcA" (ByVal lpPrevWndFunc <font color="#0000A0">As</font> Long, <font color="#0000A0">ByVal</font> hwnd <font color="#0000A0">As</font> Long, <font color="#0000A0">ByVal</font> Msg <font color="#0000A0">As</font> Long, <font color="#0000A0">ByVal</font> wParam <font color="#0000A0">As</font> Long, <font color="#0000A0">ByVal</font> lParam <font color="#0000A0">As</font> Long) <font color="#0000A0">As</font> <font color="#0000A0">Long</font>
  <font color="#0000A0">Private</font> <font color="#0000A0">Declare</font> <font color="#0000A0">Sub</font> CopyMemory <font color="#0000A0">Lib</font> "kernel32" <font color="#0000A0">Alias</font> "RtlMoveMemory" (lpDest <font color="#0000A0">As</font> Any, lpSource <font color="#0000A0">As</font> Any, <font color="#0000A0">ByVal</font> cBytes <font color="#0000A0">As</font> Long)

  <font color="#0000A0">Private</font> <font color="#0000A0">Declare</font> <font color="#0000A0">Function</font> PutMem2 <font color="#0000A0">Lib</font> "msvbvm60" (ByVal pWORDDst <font color="#0000A0">As</font> Long, <font color="#0000A0">ByVal</font> NewValue <font color="#0000A0">As</font> Long) <font color="#0000A0">As</font> <font color="#0000A0">Long</font>
  <font color="#0000A0">Private</font> <font color="#0000A0">Declare</font> <font color="#0000A0">Function</font> PutMem4 <font color="#0000A0">Lib</font> "msvbvm60" (ByVal pDWORDDst <font color="#0000A0">As</font> Long, <font color="#0000A0">ByVal</font> NewValue <font color="#0000A0">As</font> Long) <font color="#0000A0">As</font> <font color="#0000A0">Long</font>
  <font color="#0000A0">Private</font> <font color="#0000A0">Declare</font> <font color="#0000A0">Function</font> GetMem4 <font color="#0000A0">Lib</font> "msvbvm60" (ByVal pDWORDSrc <font color="#0000A0">As</font> Long, <font color="#0000A0">ByVal</font> pDWORDDst <font color="#0000A0">As</font> Long) <font color="#0000A0">As</font> <font color="#0000A0">Long</font>
  <font color="#0000A0">Private</font> <font color="#0000A0">Declare</font> <font color="#0000A0">Function</font> VarPtr <font color="#0000A0">Lib</font> "msvbvm60" (var <font color="#0000A0">As</font> Any) <font color="#0000A0">As</font> <font color="#0000A0">Long</font>

  <font color="#0000A0">Private</font> <font color="#0000A0">Declare</font> <font color="#0000A0">Function</font> GlobalAlloc <font color="#0000A0">Lib</font> "kernel32" (ByVal wFlags <font color="#0000A0">As</font> Long, <font color="#0000A0">ByVal</font> dwBytes <font color="#0000A0">As</font> Long) <font color="#0000A0">As</font> <font color="#0000A0">Long</font>
  <font color="#0000A0">Private</font> <font color="#0000A0">Declare</font> <font color="#0000A0">Function</font> GlobalFree <font color="#0000A0">Lib</font> "kernel32" (ByVal hMem <font color="#0000A0">As</font> Long) <font color="#0000A0">As</font> <font color="#0000A0">Long</font>

  <font color="#0000A0">Private</font> <font color="#0000A0">Declare</font> <font color="#0000A0">Function</font> CopyStringA <font color="#0000A0">Lib</font> "kernel32" <font color="#0000A0">Alias</font> "lstrcpyA" (ByVal NewString <font color="#0000A0">As</font> String, <font color="#0000A0">ByVal</font> OldString <font color="#0000A0">As</font> Long) <font color="#0000A0">As</font> <font color="#0000A0">Long</font>
  <font color="#0000A0">Private</font> <font color="#0000A0">Declare</font> <font color="#0000A0">Function</font> lstrlenW <font color="#0000A0">Lib</font> "kernel32" (ByVal lpString <font color="#0000A0">As</font> Long) <font color="#0000A0">As</font> <font color="#0000A0">Long</font>
  <font color="#0000A0">Private</font> <font color="#0000A0">Declare</font> <font color="#0000A0">Function</font> lstrlenA <font color="#0000A0">Lib</font> "kernel32" (ByVal lpString <font color="#0000A0">As</font> Long) <font color="#0000A0">As</font> <font color="#0000A0">Long</font>
  <font color="#0000A0">Private</font> <font color="#0000A0">Declare</font> <font color="#0000A0">Function</font> WideCharToMultiByte <font color="#0000A0">Lib</font> "kernel32" _
       (ByVal codepage <font color="#0000A0">As</font> Long, <font color="#0000A0">ByVal</font> dwFlags <font color="#0000A0">As</font> Long, _
       lpWideCharStr <font color="#0000A0">As</font> Any, <font color="#0000A0">ByVal</font> cchWideChar <font color="#0000A0">As</font> Long, _
       lpMultiByteStr <font color="#0000A0">As</font> Any, <font color="#0000A0">ByVal</font> cchMultiByte <font color="#0000A0">As</font> Long, _
       <font color="#0000A0">ByVal</font> lpDefaultChar <font color="#0000A0">As</font> String, _
       <font color="#0000A0">ByVal</font> lpUsedDefaultChar <font color="#0000A0">As</font> Long) <font color="#0000A0">As</font> <font color="#0000A0">Long</font>

  <font color="#0000A0">Private</font> <font color="#0000A0">Const</font> GMEM_FIXED <font color="#0000A0">As</font> <font color="#0000A0">Long</font> = &H0
  <font color="#0000A0">Private</font> <font color="#0000A0">Const</font> asmPUSH_imm32 <font color="#0000A0">As</font> <font color="#0000A0">Byte</font> = &H68
  <font color="#0000A0">Private</font> <font color="#0000A0">Const</font> asmRET_imm16 <font color="#0000A0">As</font> <font color="#0000A0">Byte</font> = &HC2
  <font color="#0000A0">Private</font> <font color="#0000A0">Const</font> asmRET_16 <font color="#0000A0">As</font> <font color="#0000A0">Long</font> = &H10C2&
  <font color="#0000A0">Private</font> <font color="#0000A0">Const</font> asmCALL_rel32 <font color="#0000A0">As</font> <font color="#0000A0">Byte</font> = &HE8

  <font color="#008000">'IUnknown vTable ordinals</font>
  <font color="#0000A0">Private</font> <font color="#0000A0">Const</font> unk_QueryInterface <font color="#0000A0">As</font> <font color="#0000A0">Long</font> = 0
  <font color="#0000A0">Private</font> <font color="#0000A0">Const</font> unk_AddRef <font color="#0000A0">As</font> <font color="#0000A0">Long</font> = 1
  <font color="#0000A0">Private</font> <font color="#0000A0">Const</font> unk_Release <font color="#0000A0">As</font> <font color="#0000A0">Long</font> = 2
  <font color="#0000A0">Private</font> <font color="#0000A0">Const</font> vtbl_ROT_EnumRunning = 9
  <font color="#0000A0">Private</font> <font color="#0000A0">Const</font> vtbl_EnumMoniker_Next = 3
  <font color="#0000A0">Private</font> <font color="#0000A0">Const</font> vtbl_Moniker_GetDisplayName = 20


  <font color="#008000">'Function to call Interface members by ordinal in VTable</font>
  <font color="#0000A0">Private</font> <font color="#0000A0">Function</font> CallInterface(ByVal pInterface <font color="#0000A0">As</font> Long, <font color="#0000A0">ByVal</font> FuncOrdinal <font color="#0000A0">As</font> Long, <font color="#0000A0">ByVal</font> ParamsCount <font color="#0000A0">As</font> Long, <font color="#0000A0">Optional</font> <font color="#0000A0">ByVal</font> p1 <font color="#0000A0">As</font> <font color="#0000A0">Long</font> = 0, <font color="#0000A0">Optional</font> <font color="#0000A0">ByVal</font> p2 <font color="#0000A0">As</font> <font color="#0000A0">Long</font> = 0, <font color="#0000A0">Optional</font> <font color="#0000A0">ByVal</font> p3 <font color="#0000A0">As</font> <font color="#0000A0">Long</font> = 0, <font color="#0000A0">Optional</font> <font color="#0000A0">ByVal</font> p4 <font color="#0000A0">As</font> <font color="#0000A0">Long</font> = 0, <font color="#0000A0">Optional</font> <font color="#0000A0">ByVal</font> p5 <font color="#0000A0">As</font> <font color="#0000A0">Long</font> = 0, <font color="#0000A0">Optional</font> <font color="#0000A0">ByVal</font> p6 <font color="#0000A0">As</font> <font color="#0000A0">Long</font> = 0, <font color="#0000A0">Optional</font> <font color="#0000A0">ByVal</font> p7 <font color="#0000A0">As</font> <font color="#0000A0">Long</font> = 0, <font color="#0000A0">Optional</font> <font color="#0000A0">ByVal</font> p8 <font color="#0000A0">As</font> <font color="#0000A0">Long</font> = 0, <font color="#0000A0">Optional</font> <font color="#0000A0">ByVal</font> p9 <font color="#0000A0">As</font> <font color="#0000A0">Long</font> = 0, <font color="#0000A0">Optional</font> <font color="#0000A0">ByVal</font> p10 <font color="#0000A0">As</font> <font color="#0000A0">Long</font> = 0) <font color="#0000A0">As</font> <font color="#0000A0">Long</font>
     <font color="#0000A0">Dim</font> i <font color="#0000A0">As</font> Long, t <font color="#0000A0">As</font> <font color="#0000A0">Long</font>
     <font color="#0000A0">Dim</font> hGlobal <font color="#0000A0">As</font> Long, hGlobalOffset <font color="#0000A0">As</font> <font color="#0000A0">Long</font>

     <font color="#0000A0">If</font> ParamsCount < 0 <font color="#0000A0">Then</font> Err.Raise 5 'invalid call
     <font color="#0000A0">If</font> pInterface = 0 <font color="#0000A0">Then</font> Err.Raise 5

    <font color="#008000"> '5 bytes for each parameter</font>
    <font color="#008000"> '5 bytes - PUSH this</font>
    <font color="#008000"> '5 bytes - call member function</font>
    <font color="#008000"> '3 bytes - ret 0x0010, pop CallWindowProc</font>
    <font color="#008000"> '1 byte - dword align.</font>

     hGlobal = GlobalAlloc(GMEM_FIXED, 5 * ParamsCount + 5 + 5 + 3 + 1)
     <font color="#0000A0">If</font> hGlobal = 0 <font color="#0000A0">Then</font> Err.Raise 7 'insuff. memory
     hGlobalOffset = hGlobal

     <font color="#0000A0">If</font> ParamsCount > 0 <font color="#0000A0">Then</font>
       t = VarPtr(p1)
       <font color="#0000A0">For</font> i = ParamsCount - 1 <font color="#0000A0">To</font> 0 <font color="#0000A0">Step</font> -1
         PutMem2 hGlobalOffset, asmPUSH_imm32
         hGlobalOffset = hGlobalOffset + 1
         GetMem4 t + i * 4, hGlobalOffset
         hGlobalOffset = hGlobalOffset + 4
       <font color="#0000A0">Next</font>
     <font color="#0000A0">End</font> <font color="#0000A0">If</font>

   <font color="#008000"> 'First member of any interface - this. Assign...</font>
     PutMem2 hGlobalOffset, asmPUSH_imm32
     hGlobalOffset = hGlobalOffset + 1
     PutMem4 hGlobalOffset, pInterface
     hGlobalOffset = hGlobalOffset + 4

    <font color="#008000"> 'Call IFace Function by its ordinal</font>
     PutMem2 hGlobalOffset, asmCALL_rel32
     hGlobalOffset = hGlobalOffset + 1

     GetMem4 pInterface, VarPtr(t) 'dereference: find vTable
     GetMem4 t + FuncOrdinal * 4, VarPtr(t) 'Function offset in vTable, dereference
     PutMem4 hGlobalOffset, t - hGlobalOffset - 4
     hGlobalOffset = hGlobalOffset + 4

    <font color="#008000"> 'all interfaces are stdcall, so forget about stack clearing</font>
     PutMem4 hGlobalOffset, asmRET_16 'ret 0x0010

     CallInterface = CallWindowProc(hGlobal, 0, 0, 0, 0)

     GlobalFree hGlobal

  <font color="#0000A0">End</font> <font color="#0000A0">Function</font>

  <font color="#0000A0">Private</font> <font color="#0000A0">Function</font> StrFromPtrA(ByVal lpszA <font color="#0000A0">As</font> Long, <font color="#0000A0">Optional</font> nSize <font color="#0000A0">As</font> <font color="#0000A0">Long</font> = 0) <font color="#0000A0">As</font> <font color="#0000A0">String</font>
      <font color="#0000A0">Dim</font> s <font color="#0000A0">As</font> String, bTrim <font color="#0000A0">As</font> <font color="#0000A0">Boolean</font>
      <font color="#0000A0">If</font> nSize = 0 <font color="#0000A0">Then</font>
         nSize = lstrlenA(lpszA)
         bTrim = <font color="#0000A0">True</font>
      <font color="#0000A0">End</font> <font color="#0000A0">If</font>
      s = String(nSize, Chr$(0))
      CopyStringA s, <font color="#0000A0">ByVal</font> lpszA
      <font color="#0000A0">If</font> bTrim <font color="#0000A0">Then</font> s = TrimNULL(s)
      StrFromPtrA = s
  <font color="#0000A0">End</font> <font color="#0000A0">Function</font>

  <font color="#0000A0">Private</font> <font color="#0000A0">Function</font> StrFromPtrW(ByVal lpszW <font color="#0000A0">As</font> Long, <font color="#0000A0">Optional</font> nSize <font color="#0000A0">As</font> <font color="#0000A0">Long</font> = 0) <font color="#0000A0">As</font> <font color="#0000A0">String</font>
      <font color="#0000A0">Dim</font> s <font color="#0000A0">As</font> String, bTrim <font color="#0000A0">As</font> <font color="#0000A0">Boolean</font>
      <font color="#0000A0">If</font> nSize = 0 <font color="#0000A0">Then</font>
         nSize = lstrlenW(lpszW) * 2
         bTrim = <font color="#0000A0">True</font>
      <font color="#0000A0">End</font> <font color="#0000A0">If</font>
      s = String(nSize, Chr$(0))
  <font color="#008000">' CopyMemory ByVal StrPtr(s), ByVal lpszW, nSize ' VBA doesn't support StrPtr :(</font>
      WideCharToMultiByte 0, &H0, <font color="#0000A0">ByVal</font> lpszW, -1, <font color="#0000A0">ByVal</font> s, Len(s), &H0, &H0
      <font color="#0000A0">If</font> bTrim <font color="#0000A0">Then</font> s = TrimNULL(s)
      StrFromPtrW = s
  <font color="#0000A0">End</font> <font color="#0000A0">Function</font>

  <font color="#0000A0">Private</font> <font color="#0000A0">Function</font> TrimNULL(ByVal str <font color="#0000A0">As</font> String) <font color="#0000A0">As</font> <font color="#0000A0">String</font>
       <font color="#0000A0">If</font> InStr(str, Chr$(0)) > 0& <font color="#0000A0">Then</font>
           TrimNULL = Left$(str, InStr(str, Chr$(0)) - 1&)
       <font color="#0000A0">Else</font>
           TrimNULL = str
       <font color="#0000A0">End</font> <font color="#0000A0">If</font>
  <font color="#0000A0">End</font> <font color="#0000A0">Function</font>

  <font color="#0000A0">Public</font> <font color="#0000A0">Function</font> GetAllInstances() <font color="#0000A0">As</font> Collection
      <font color="#0000A0">Dim</font> pROT <font color="#0000A0">As</font> Long, pEnumMoniker <font color="#0000A0">As</font> Long, pMoniker <font color="#0000A0">As</font> Long, pBindCtx <font color="#0000A0">As</font> <font color="#0000A0">Long</font>
      <font color="#0000A0">Dim</font> ret <font color="#0000A0">As</font> Long, nCount <font color="#0000A0">As</font> Long, CheckForInstance <font color="#0000A0">As</font> Boolean, Key <font color="#0000A0">As</font> <font color="#0000A0">String</font>
      <font color="#0000A0">Dim</font> pName <font color="#0000A0">As</font> Long, RegisteredName <font color="#0000A0">As</font> String, ExcelApp <font color="#0000A0">As</font> Application
      ret = GetRunningObjectTable(0, pROT)
      ret = CreateBindCtx(0, pBindCtx)
      CallInterface pROT, vtbl_ROT_EnumRunning, 1, VarPtr(pEnumMoniker)
      <font color="#0000A0">While</font> CallInterface(pEnumMoniker, vtbl_EnumMoniker_Next, 3, 1, VarPtr(pMoniker), VarPtr(nCount)) = 0
           CallInterface pMoniker, vtbl_Moniker_GetDisplayName, 3, pBindCtx, 0, VarPtr(pName)
      <font color="#008000"> 'For win9x you'll need StrFromPtrA</font>

           RegisteredName = StrFromPtrW(pName)
           <font color="#0000A0">If</font> InStr(LCase(RegisteredName), "book") <font color="#0000A0">Then</font>
               CheckForInstance = <font color="#0000A0">True</font>
           <font color="#0000A0">Else</font>
               <font color="#0000A0">Select</font> <font color="#0000A0">Case</font> Right(RegisteredName, 3)
                   <font color="#0000A0">Case</font> "xla", "slk", "dif", "csv", "txt", "prn", "dbf", "wq1", "wks", "wk1", "wk3", "wk4", "xlw", "xls", "xlt", "htm", "mht", "xml"
                       CheckForInstance = <font color="#0000A0">True</font>
               <font color="#0000A0">End</font> <font color="#0000A0">Select</font>
               <font color="#0000A0">Select</font> <font color="#0000A0">Case</font> Right(RegisteredName, 5)
                   <font color="#0000A0">Case</font> ".html", "mhtml"
                       CheckForInstance = <font color="#0000A0">True</font>
               <font color="#0000A0">End</font> <font color="#0000A0">Select</font>
           <font color="#0000A0">End</font> <font color="#0000A0">If</font>

           <font color="#0000A0">If</font> CheckForInstance <font color="#0000A0">Then</font>
               CheckForInstance = <font color="#0000A0">False</font>
               <font color="#0000A0">If</font> ParentIsExcel(RegisteredName, ExcelApp) <font color="#0000A0">Then</font>
                   <font color="#0000A0">If</font> GetAllInstances <font color="#0000A0">Is</font> <font color="#0000A0">Nothing</font> <font color="#0000A0">Then</font> <font color="#0000A0">Set</font> GetAllInstances = <font color="#0000A0">New</font> Collection
                   Key = CStr(ObjPtr(ExcelApp))
                   <font color="#0000A0">If</font> <font color="#0000A0">Not</font> InstanceAlreadyCollected(GetAllInstances, Key) <font color="#0000A0">Then</font>
                       GetAllInstances.Add ExcelApp, Key
                   <font color="#0000A0">End</font> <font color="#0000A0">If</font>
               <font color="#0000A0">End</font> <font color="#0000A0">If</font>
           <font color="#0000A0">End</font> <font color="#0000A0">If</font>

           CallInterface pMoniker, unk_Release, 0
           CoTaskMemFree pName
      <font color="#0000A0">Wend</font>
      CallInterface pEnumMoniker, unk_Release, 0
      CallInterface pBindCtx, unk_Release, 0
      CallInterface pROT, unk_Release, 0
  <font color="#0000A0">Exit</font> <font color="#0000A0">Function</font>


  <font color="#0000A0">End</font> <font color="#0000A0">Function</font>

  <font color="#0000A0">Private</font> <font color="#0000A0">Function</font> ParentIsExcel(ByVal RegisteredName <font color="#0000A0">As</font> String, ExcelApp <font color="#0000A0">As</font> Application) <font color="#0000A0">As</font> <font color="#0000A0">Boolean</font>
       <font color="#0000A0">On</font> <font color="#0000A0">Error</font> <font color="#0000A0">Resume</font> <font color="#0000A0">Next</font>

       <font color="#0000A0">Set</font> ExcelApp = GetObject(RegisteredName).Parent
       <font color="#0000A0">If</font> ExcelApp.Name = "Microsoft Excel" <font color="#0000A0">Then</font>
           ParentIsExcel = <font color="#0000A0">True</font>
       <font color="#0000A0">End</font> <font color="#0000A0">If</font>

  <font color="#0000A0">End</font> <font color="#0000A0">Function</font>

  <font color="#0000A0">Private</font> <font color="#0000A0">Function</font> InstanceAlreadyCollected(GetAllInstances <font color="#0000A0">As</font> Collection, Key <font color="#0000A0">As</font> String) <font color="#0000A0">As</font> <font color="#0000A0">Boolean</font>
       <font color="#0000A0">On</font> <font color="#0000A0">Error</font> <font color="#0000A0">GoTo</font> Err_InstanceAlreadyCollected
       <font color="#0000A0">Dim</font> o <font color="#0000A0">As</font> Application
       <font color="#0000A0">Set</font> o = GetAllInstances(Key)
       InstanceAlreadyCollected = <font color="#0000A0">True</font>
  Err_InstanceAlreadyCollected:
  <font color="#0000A0">End</font> <font color="#0000A0">Function</font>
</FONT></td></tr></table><button onclick='document.all("11212007184953725").value=document.all("11212007184953725").value.replace(/<br \/>\s\s/g,"");document.all("11212007184953725").value=document.all("11212007184953725").value.replace(/<br \/>/g,"");window.clipboardData.setData("Text",document.all("11212007184953725").value);'>Copy to Clipboard</BUTTON><textarea style="position:absolute;visibility:hidden" name="11212007184953725" wrap="virtual">
Option Explicit

Private Declare Function GetRunningObjectTable Lib "ole32.dll" (ByVal dwReserved As Long, pROT As Long) As Long
Private Declare Function CreateBindCtx Lib "ole32.dll" (ByVal dwReserved As Long, pBindCtx As Long) As Long
Private Declare Sub CoTaskMemFree Lib "ole32.dll" (ByVal pv As Long)

Private Declare Sub OleInitialize Lib "ole32.dll" (pvReserved As Any)
Private Declare Sub OleUninitialize Lib "ole32.dll" ()

Private Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (lpDest As Any, lpSource As Any, ByVal cBytes As Long)

Private Declare Function PutMem2 Lib "msvbvm60" (ByVal pWORDDst As Long, ByVal NewValue As Long) As Long
Private Declare Function PutMem4 Lib "msvbvm60" (ByVal pDWORDDst As Long, ByVal NewValue As Long) As Long
Private Declare Function GetMem4 Lib "msvbvm60" (ByVal pDWORDSrc As Long, ByVal pDWORDDst As Long) As Long
Private Declare Function VarPtr Lib "msvbvm60" (var As Any) As Long

Private Declare Function GlobalAlloc Lib "kernel32" (ByVal wFlags As Long, ByVal dwBytes As Long) As Long
Private Declare Function GlobalFree Lib "kernel32" (ByVal hMem As Long) As Long

Private Declare Function CopyStringA Lib "kernel32" Alias "lstrcpyA" (ByVal NewString As String, ByVal OldString As Long) As Long
Private Declare Function lstrlenW Lib "kernel32" (ByVal lpString As Long) As Long
Private Declare Function lstrlenA Lib "kernel32" (ByVal lpString As Long) As Long
Private Declare Function WideCharToMultiByte Lib "kernel32" _
(ByVal codepage As Long, ByVal dwFlags As Long, _
lpWideCharStr As Any, ByVal cchWideChar As Long, _
lpMultiByteStr As Any, ByVal cchMultiByte As Long, _
ByVal lpDefaultChar As String, _
ByVal lpUsedDefaultChar As Long) As Long

Private Const GMEM_FIXED As Long = &H0
Private Const asmPUSH_imm32 As Byte = &H68
Private Const asmRET_imm16 As Byte = &HC2
Private Const asmRET_16 As Long = &H10C2&
Private Const asmCALL_rel32 As Byte = &HE8

'IUnknown vTable ordinals
Private Const unk_QueryInterface As Long = 0
Private Const unk_AddRef As Long = 1
Private Const unk_Release As Long = 2
Private Const vtbl_ROT_EnumRunning = 9
Private Const vtbl_EnumMoniker_Next = 3
Private Const vtbl_Moniker_GetDisplayName = 20


'Function to call Interface members by ordinal in VTable
Private Function CallInterface(ByVal pInterface As Long, ByVal FuncOrdinal As Long, ByVal ParamsCount As Long, Optional ByVal p1 As Long = 0, Optional ByVal p2 As Long = 0, Optional ByVal p3 As Long = 0, Optional ByVal p4 As Long = 0, Optional ByVal p5 As Long = 0, Optional ByVal p6 As Long = 0, Optional ByVal p7 As Long = 0, Optional ByVal p8 As Long = 0, Optional ByVal p9 As Long = 0, Optional ByVal p10 As Long = 0) As Long
Dim i As Long, t As Long
Dim hGlobal As Long, hGlobalOffset As Long

If ParamsCount < 0 Then Err.Raise 5 'invalid call
If pInterface = 0 Then Err.Raise 5

'5 bytes for each parameter
'5 bytes - PUSH this
'5 bytes - call member function
'3 bytes - ret 0x0010, pop CallWindowProc
'1 byte - dword align.

hGlobal = GlobalAlloc(GMEM_FIXED, 5 * ParamsCount + 5 + 5 + 3 + 1)
If hGlobal = 0 Then Err.Raise 7 'insuff. memory
hGlobalOffset = hGlobal

If ParamsCount > 0 Then
t = VarPtr(p1)
For i = ParamsCount - 1 To 0 Step -1
PutMem2 hGlobalOffset, asmPUSH_imm32
hGlobalOffset = hGlobalOffset + 1
GetMem4 t + i * 4, hGlobalOffset
hGlobalOffset = hGlobalOffset + 4
Next
End If

'First member of any interface - this. Assign...
PutMem2 hGlobalOffset, asmPUSH_imm32
hGlobalOffset = hGlobalOffset + 1
PutMem4 hGlobalOffset, pInterface
hGlobalOffset = hGlobalOffset + 4

'Call IFace Function by its ordinal
PutMem2 hGlobalOffset, asmCALL_rel32
hGlobalOffset = hGlobalOffset + 1

GetMem4 pInterface, VarPtr(t) 'dereference: find vTable
GetMem4 t + FuncOrdinal * 4, VarPtr(t) 'Function offset in vTable, dereference
PutMem4 hGlobalOffset, t - hGlobalOffset - 4
hGlobalOffset = hGlobalOffset + 4

'all interfaces are stdcall, so forget about stack clearing
PutMem4 hGlobalOffset, asmRET_16 'ret 0x0010

CallInterface = CallWindowProc(hGlobal, 0, 0, 0, 0)

GlobalFree hGlobal

End Function

Private Function StrFromPtrA(ByVal lpszA As Long, Optional nSize As Long = 0) As String
Dim s As String, bTrim As Boolean
If nSize = 0 Then
nSize = lstrlenA(lpszA)
bTrim = True
End If
s = String(nSize, Chr$(0))
CopyStringA s, ByVal lpszA
If bTrim Then s = TrimNULL(s)
StrFromPtrA = s
End Function

Private Function StrFromPtrW(ByVal lpszW As Long, Optional nSize As Long = 0) As String
Dim s As String, bTrim As Boolean
If nSize = 0 Then
nSize = lstrlenW(lpszW) * 2
bTrim = True
End If
s = String(nSize, Chr$(0))
' CopyMemory ByVal StrPtr(s), ByVal lpszW, nSize ' VBA doesn't support StrPtr :(
WideCharToMultiByte 0, &H0, ByVal lpszW, -1, ByVal s, Len(s), &H0, &H0
If bTrim Then s = TrimNULL(s)
StrFromPtrW = s
End Function

Private Function TrimNULL(ByVal str As String) As String
If InStr(str, Chr$(0)) > 0& Then
TrimNULL = Left$(str, InStr(str, Chr$(0)) - 1&)
Else
TrimNULL = str
End If
End Function

Public Function GetAllInstances() As Collection
Dim pROT As Long, pEnumMoniker As Long, pMoniker As Long, pBindCtx As Long
Dim ret As Long, nCount As Long, CheckForInstance As Boolean, Key As String
Dim pName As Long, RegisteredName As String, ExcelApp As Application
ret = GetRunningObjectTable(0, pROT)
ret = CreateBindCtx(0, pBindCtx)
CallInterface pROT, vtbl_ROT_EnumRunning, 1, VarPtr(pEnumMoniker)
While CallInterface(pEnumMoniker, vtbl_EnumMoniker_Next, 3, 1, VarPtr(pMoniker), VarPtr(nCount)) = 0
CallInterface pMoniker, vtbl_Moniker_GetDisplayName, 3, pBindCtx, 0, VarPtr(pName)
'For win9x you'll need StrFromPtrA

RegisteredName = StrFromPtrW(pName)
If InStr(LCase(RegisteredName), "book") Then
CheckForInstance = True
Else
Select Case Right(RegisteredName, 3)
Case "xla", "slk", "dif", "csv", "txt", "prn", "dbf", "wq1", "wks", "wk1", "wk3", "wk4", "xlw", "xls", "xlt", "htm", "mht", "xml"
CheckForInstance = True
End Select
Select Case Right(RegisteredName, 5)
Case ".html", "mhtml"
CheckForInstance = True
End Select
End If

If CheckForInstance Then
CheckForInstance = False
If ParentIsExcel(RegisteredName, ExcelApp) Then
If GetAllInstances Is Nothing Then Set GetAllInstances = New Collection
Key = CStr(ObjPtr(ExcelApp))
If Not InstanceAlreadyCollected(GetAllInstances, Key) Then
GetAllInstances.Add ExcelApp, Key
End If
End If
End If

CallInterface pMoniker, unk_Release, 0
CoTaskMemFree pName
Wend
CallInterface pEnumMoniker, unk_Release, 0
CallInterface pBindCtx, unk_Release, 0
CallInterface pROT, unk_Release, 0
Exit Function


End Function

Private Function ParentIsExcel(ByVal RegisteredName As String, ExcelApp As Application) As Boolean
On Error Resume Next

Set ExcelApp = GetObject(RegisteredName).Parent
If ExcelApp.Name = "Microsoft Excel" Then
ParentIsExcel = True
End If

End Function

Private Function InstanceAlreadyCollected(GetAllInstances As Collection, Key As String) As Boolean
On Error GoTo Err_InstanceAlreadyCollected
Dim o As Application
Set o = GetAllInstances(Key)
InstanceAlreadyCollected = True
Err_InstanceAlreadyCollected:
End Function</textarea>

Elsewhere in your project, paste this in:
<table width="100%" border="1" bgcolor="White" style="filter:progid:DXImageTransform.Microsoft.Gradient(endColorstr='#C0CFE2', startColorstr='#FFFFFF', gradientType='0');"><tr><TD><font size="2" face=Courier New>  <font color="#0000A0">Sub</font> CloseStartUpsInAllInstances()
       <font color="#0000A0">Dim</font> c <font color="#0000A0">As</font> Collection, app <font color="#0000A0">As</font> Application, wb <font color="#0000A0">As</font> Workbook

       <font color="#0000A0">Set</font> c = GetAllInstances
       <font color="#0000A0">If</font> <font color="#0000A0">Not</font> c <font color="#0000A0">Is</font> <font color="#0000A0">Nothing</font> <font color="#0000A0">Then</font>
           <font color="#0000A0">For</font> <font color="#0000A0">Each</font> app <font color="#0000A0">In</font> c
               <font color="#0000A0">For</font> <font color="#0000A0">Each</font> wb <font color="#0000A0">In</font> app.Workbooks
                   <font color="#0000A0">If</font> wb.Path = Application.StartupPath <font color="#0000A0">Then</font>
                       wb.Close <font color="#0000A0">True</font>
                   <font color="#0000A0">End</font> <font color="#0000A0">If</font>
               <font color="#0000A0">Next</font>
           <font color="#0000A0">Next</font>
       <font color="#0000A0">End</font> <font color="#0000A0">If</font>
  <font color="#0000A0">End</font> <font color="#0000A0">Sub</font>
</FONT></td></tr></table><button onclick='document.all("11212007185059341").value=document.all("11212007185059341").value.replace(/<br \/>\s\s/g,"");document.all("11212007185059341").value=document.all("11212007185059341").value.replace(/<br \/>/g,"");window.clipboardData.setData("Text",document.all("11212007185059341").value);'>Copy to Clipboard</BUTTON><textarea style="position:absolute;visibility:hidden" name="11212007185059341" wrap="virtual">
Sub CloseStartUpsInAllInstances()
Dim c As Collection, app As Application, wb As Workbook

Set c = GetAllInstances
If Not c Is Nothing Then
For Each app In c
For Each wb In app.Workbooks
If wb.Path = Application.StartupPath Then
wb.Close True
End If
Next
Next
End If
End Sub</textarea>
 
Upvote 0
Well, this kinda works, Thanks for the code. If I run it by itself it works great. And I can close my personal.xls file with it. But when I try to incorporate it into the existimg macro that's causing the problem, it disrupts the SendKeys Syncronization.

I've figured a way around it by putting this code at the beginning (before any sendkeys happens). It searches all open excel apps for personal.xls and saves/closes it. Then copies it to a different location, and deletes it from the XLSTART folder. Then restores it at the end of the macro.


But I still find it hard to beleive that it has to be this complicated to loop through all open workbooks regardless of which instance of excel it was opened from. There has to be a simpler way.

Also, is there any way to just supress the New Instance of Excel opening the personal.xls file in the XLSTART folder??
 
Upvote 0
I've figured a way around it by putting this code at the beginning (before any sendkeys happens). It searches all open excel apps for personal.xls and saves/closes it. Then copies it to a different location, and deletes it from the XLSTART folder. Then restores it at the end of the macro.
Wow. I hope the people you are writing this for are forgiving if something happens to their Personal.xls. :eek:

But I still find it hard to beleive that it has to be this complicated to loop through all open workbooks regardless of which instance of excel it was opened from. There has to be a simpler way.
The top level object provided to us VBA'ers is Application. There is no Applications collection. The complexity on your end required a copy and paste. I even provided lovely, little buttons in my post. What's the problem? :rolleyes:

Also, is there any way to just supress the New Instance of Excel opening the personal.xls file in the XLSTART folder??
I don't know. :biggrin:
 
Upvote 0
The complexity on your end required a copy and paste. What's the problem?

I was referring to the complexity of the code itself, not the use of it.

Wow. I hope the people you are writing this for are forgiving if something happens to their Personal.xls.

good call, I will amend it to Only do that if I'M running the code. I already have a function to get windows logon ID. So I can use

IF UserName() = "Jon" Then...
 
Upvote 0
Thanks for the thought employee..

But it's not any excel code that opens the new instance of excel. It's my companies Application that does it. The macro is using SendKeys to mimick keystroks in that application to export reports to excel. But each export opens a new instance of excel.

so I can't use the ReadOnly code, as there is no place to put it. And I tink
application.displayalerts = false

would only apply to the instance of excel the code is executed from..
 
Upvote 0
Thanks for the thought employee..

But it's not any excel code that opens the new instance of excel. It's my companies Application that does it. The macro is using SendKeys to mimick keystroks in that application to export reports to excel. But each export opens a new instance of excel.

so I can't use the ReadOnly code, as there is no place to put it. And I tink
application.displayalerts = false

would only apply to the instance of excel the code is executed from..

ya I figured...

sendkeys are a motha..
 
Upvote 0

Forum statistics

Threads
1,215,326
Messages
6,124,263
Members
449,149
Latest member
mwdbActuary

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top