Open in a new Excel application

dewfall

New Member
Joined
Apr 21, 2006
Messages
4
Hi Folks, :)

First time poster here. I hope I'm doing this right.

I have a situation where I'd like to open a special workbook (loaded with code for security, disabling certain toolbars and menus, and appearances) in its own Excel Application object. I don't want other workbooks, opened before or after, to be subject to those settings, so I'd like to find a way to force them to open in another separate instance of the Excel application object.

Thanks for any good suggestions. :)
 

Excel Facts

Round to nearest half hour?
Use =MROUND(A2,"0:30") to round to nearest half hour. Use =CEILING(A2,"0:30") to round to next half hour.
Welcome to the board.
Try putting your code for disabling those toolbars,menus, etc in the following event.

Private Sub Workbook_Activate()

End Sub
 
Upvote 0
Thanks for the response.

I already had the Workbook_Activate event working like you suggest. What happens though, is when my special macro workbook is already open and another workbook is opened, it opens under the same application object and is subject to the toolbars and menus being disabled.

If I could somehow lock up the application my coded workbook is in so no other workbook could open in it, but instead must open in a new application object, that would solve the problem. I notice when an existing workbook is open and I open a brand new blank Excel file it does this, so there must be a way. Thanks for your suggestions.
 
Upvote 0
I'd like to find a way to force them to open in another separate instance of the Excel application object.
Dim myXL As Object
Set myXL = New Excel.Application
myXL.Visible = True
myXL.Workbooks.Open Filename:="C:\Your\File\Path\YourFileName.xls"
 
Upvote 0
Tom's method would work but you will not have control over how many instances are opened...

So... This is the required behavior?

1. If OrpanWorkbook.xls is opened alone in it's own instance...
a. do not allow any other workbook to be opened in this instance?
b. force any other workbooks that are created or opened to be opened in a separate instance?

2. If OrpanWorkbook.xls is opened in an instance that already has workbooks opened then close OrpanWorkbook.xls and open it in it's own instance?

This is doable but it might be a bit more complicated than you think. The workbook will need the ability to re-open it'self I suppose. I have some code on this board somewhere that does this. Search for username "Right_Click" or "tstom".
 
Upvote 0
This will do the above in my previous post. The only limitation I placed on it was the inability to open the same workbook in another instance (as ReadOnly). If you attempt to open the workbook in another instance at the same time, the read-only version will close it'self without prompt. The code will not allow other workbooks to be opened in "this" instance but will force them to open them in their own instance. Once a second instance has been created, it will be used for all other workbooks unless you purposely open your own instance. This code in any workbook should effectively "orphan" the workbook. If you try to open this workbook in an instance that already contains one or more workbooks, this workbook will close and reopen it'self in a new instance. See the download for a better understanding.

MyLonelyWorkbook.zip

<table border="1" bgcolor="White"><caption ALIGN=left><font size="2" face=Courier New>Example VBA Code:</FONT></caption><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> SetForegroundWindow <font color="#0000A0">Lib</font> "user32" _
       (ByVal hWnd <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> FindWindow <font color="#0000A0">Lib</font> "user32" <font color="#0000A0">Alias</font> "FindWindowA" _
       (ByVal lpClassName <font color="#0000A0">As</font> String, <font color="#0000A0">ByVal</font> lpWindowName <font color="#0000A0">As</font> String) <font color="#0000A0">As</font> <font color="#0000A0">Long</font>
  
  <font color="#0000A0">Private</font> <font color="#0000A0">WithEvents</font> pParentApp <font color="#0000A0">As</font> Application
  <font color="#0000A0">Private</font> pAuxiliaryInstance <font color="#0000A0">As</font> Application
  <font color="#0000A0">Private</font> pPersonalXls <font color="#0000A0">As</font> <font color="#0000A0">String</font>
  <font color="#0000A0">Private</font> pIsLoaded <font color="#0000A0">As</font> <font color="#0000A0">Boolean</font>
  
  <font color="#0000A0">Private</font> <font color="#0000A0">Sub</font> Workbook_Open()
       SetUpOrpan
  <font color="#0000A0">End</font> <font color="#0000A0">Sub</font>
  
  <font color="#0000A0">Private</font> <font color="#0000A0">Sub</font> SetUpOrpan()
       <font color="#0000A0">Dim</font> Wb <font color="#0000A0">As</font> Workbook
      <font color="#008000"> 'get an instance to "PERSONAL.XLS" if it is loaded</font>
       <font color="#0000A0">On</font> <font color="#0000A0">Error</font> <font color="#0000A0">Resume</font> <font color="#0000A0">Next</font>
       <font color="#0000A0">If</font> ThisWorkbook.ReadOnly <font color="#0000A0">Then</font>
           ThisWorkbook.Close False
       <font color="#0000A0">End</font> <font color="#0000A0">If</font>
       <font color="#0000A0">Set</font> Wb = Workbooks("PERSONAL.XLS")
       <font color="#0000A0">On</font> <font color="#0000A0">Error</font> <font color="#0000A0">GoTo</font> 0
       <font color="#0000A0">If</font> Workbooks.Count > 1 <font color="#0000A0">And</font> Wb <font color="#0000A0">Is</font> <font color="#0000A0">Nothing</font> <font color="#0000A0">Then</font>
          <font color="#008000"> 'PERSONAL.XLS not loaded</font>
          <font color="#008000"> 'other workbooks are already open in this instance</font>
          <font color="#008000"> 'open ThisWorkbook in a new instance of Excel.Application</font>
           CloseMeAndStartMeInNewInstance
       <font color="#0000A0">ElseIf</font> Workbooks.Count > 2 <font color="#0000A0">Then</font>
          <font color="#008000"> 'PERSONAL.XLS may or may not be loaded. Does not matter at this point</font>
          <font color="#008000"> 'other workbooks are already open in this instance</font>
          <font color="#008000"> 'open ThisWorkbook in a new instance of Excel.Application</font>
           CloseMeAndStartMeInNewInstance
       <font color="#0000A0">Else</font>
          <font color="#008000"> 'this instance is ok to open ThisWorkbook</font>
          <font color="#008000"> 'close PERSONAL.XLS in this instance</font>
           <font color="#0000A0">If</font> <font color="#0000A0">Not</font> Wb <font color="#0000A0">Is</font> <font color="#0000A0">Nothing</font> <font color="#0000A0">Then</font>
               pPersonalXls = Wb.FullName
               Wb.Close
           <font color="#0000A0">End</font> <font color="#0000A0">If</font>
          <font color="#008000"> 'continue opening in this instance</font>
          <font color="#008000"> 'start watching the application level events to</font>
          <font color="#008000"> 'respond to any attempts to create a new workbook</font>
          <font color="#008000"> 'or to open an existing workbook</font>
           <font color="#0000A0">Set</font> pParentApp = Application
       <font color="#0000A0">End</font> <font color="#0000A0">If</font>
  <font color="#0000A0">End</font> <font color="#0000A0">Sub</font>
  
  <font color="#0000A0">Public</font> <font color="#0000A0">Property</font> <font color="#0000A0">Get</font> IsLoaded() <font color="#0000A0">As</font> <font color="#0000A0">Boolean</font>
       IsLoaded = pIsLoaded
  <font color="#0000A0">End</font> <font color="#0000A0">Property</font>
  
  <font color="#008000">'should only set this reference from VBScript</font>
  <font color="#0000A0">Public</font> <font color="#0000A0">Property</font> <font color="#0000A0">Set</font> AuxiliaryInstance(app <font color="#0000A0">As</font> Excel.Application)
       <font color="#0000A0">If</font> pAuxiliaryInstance <font color="#0000A0">Is</font> <font color="#0000A0">Nothing</font> <font color="#0000A0">Then</font>
           <font color="#0000A0">Set</font> pAuxiliaryInstance = app
       <font color="#0000A0">End</font> <font color="#0000A0">If</font>
  <font color="#0000A0">End</font> <font color="#0000A0">Property</font>
  
  <font color="#0000A0">Private</font> <font color="#0000A0">Sub</font> Workbook_BeforeClose(Cancel <font color="#0000A0">As</font> Boolean)
       <font color="#0000A0">If</font> <font color="#0000A0">Not</font> pAuxiliaryInstance <font color="#0000A0">Is</font> <font color="#0000A0">Nothing</font> <font color="#0000A0">Then</font>
          <font color="#008000"> 'if the user closes the Auxiliary Instance but we still have a reference</font>
          <font color="#008000"> 'to the application, we will have an orphaned proccess running invisibly</font>
          <font color="#008000"> 'this will close it</font>
           <font color="#0000A0">If</font> <font color="#0000A0">Not</font> pAuxiliaryInstance.Visible <font color="#0000A0">Then</font>
               pAuxiliaryInstance.Quit
               <font color="#0000A0">Set</font> pAuxiliaryInstance = <font color="#0000A0">Nothing</font>
           <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">Sub</font>
  
  <font color="#0000A0">Private</font> <font color="#0000A0">Sub</font> pParentApp_NewWorkbook(ByVal Wb <font color="#0000A0">As</font> Workbook)
      <font color="#008000"> 'close the newly created workbook and open it in the Auxiliary Instance</font>
       Wb.Close False
       CreateNewOrGetExistingInstance
       pAuxiliaryInstance.Workbooks.Add
       SetForegroundWindow FindWindow("XLMAIN", pAuxiliaryInstance.Caption)
  <font color="#0000A0">End</font> <font color="#0000A0">Sub</font>
  
  <font color="#0000A0">Private</font> <font color="#0000A0">Sub</font> pParentApp_WorkbookOpen(ByVal Wb <font color="#0000A0">As</font> Workbook)
      <font color="#008000"> 'close the newly opened workbook and re-open it in the Auxiliary Instance</font>
       <font color="#0000A0">Dim</font> WorkbookFullName <font color="#0000A0">As</font> <font color="#0000A0">String</font>
       <font color="#0000A0">If</font> Wb.FullName = ThisWorkbook.FullName <font color="#0000A0">Then</font>
           <font color="#0000A0">If</font> <font color="#0000A0">Not</font> pIsLoaded <font color="#0000A0">Then</font> <font color="#0000A0">Exit</font> <font color="#0000A0">Sub</font>
           MsgBox "Only one instance of this workbook may be opened..."
           Wb.Close False
       <font color="#0000A0">End</font> <font color="#0000A0">If</font>
       WorkbookFullName = Wb.FullName
       Wb.Close False
       CreateNewOrGetExistingInstance
       pAuxiliaryInstance.Workbooks.Open WorkbookFullName
       SetForegroundWindow FindWindow("XLMAIN", pAuxiliaryInstance.Caption)
       pIsLoaded = True
  <font color="#0000A0">End</font> <font color="#0000A0">Sub</font>
  
  <font color="#0000A0">Private</font> <font color="#0000A0">Sub</font> CreateNewOrGetExistingInstance()
       <font color="#0000A0">If</font> pAuxiliaryInstance <font color="#0000A0">Is</font> <font color="#0000A0">Nothing</font> <font color="#0000A0">Then</font>
           <font color="#0000A0">Set</font> pAuxiliaryInstance = <font color="#0000A0">New</font> Application
           <font color="#0000A0">If</font> pAuxiliaryInstance.Workbooks.Count = 0 <font color="#0000A0">And</font> pPersonalXls <> "" <font color="#0000A0">Then</font>
               pAuxiliaryInstance.Workbooks.Open pPersonalXls
           <font color="#0000A0">End</font> <font color="#0000A0">If</font>
       <font color="#0000A0">End</font> <font color="#0000A0">If</font>
      <font color="#008000"> 'always set the visiblility to True because the user may have closed</font>
      <font color="#008000"> 'the application but it is still running invisibly if we have a reference to it</font>
       pAuxiliaryInstance.Visible = True
  <font color="#0000A0">End</font> <font color="#0000A0">Sub</font>
  
  <font color="#0000A0">Private</font> <font color="#0000A0">Sub</font> CloseMeAndStartMeInNewInstance()
      <font color="#008000"> 'create a VBScript file to reopen this workbook in a new instance</font>
      <font color="#008000"> 'get a reference to the correct, existing instance using an</font>
      <font color="#008000"> 'arbitrary workbook's fullname</font>
       <font color="#0000A0">Dim</font> WshShell <font color="#0000A0">As</font> Object, fso <font color="#0000A0">As</font> FileSystemObject
       <font color="#0000A0">Dim</font> TempScriptFilename <font color="#0000A0">As</font> String, FhWnd <font color="#0000A0">As</font> <font color="#0000A0">Integer</font>
      
       <font color="#0000A0">Set</font> fso = CreateObject("Scripting.FileSystemObject")
      
      <font color="#008000"> 'build temp vbscript filename using temp folder and temp filename</font>
       TempScriptFilename = fso.GetSpecialFolder(2) & "\" & fso.GetTempName & ".vbs"
      
      <font color="#008000"> 'temp vbscript file</font>
       FhWnd = FreeFile
       <font color="#0000A0">Open</font> TempScriptFilename <font color="#0000A0">For</font> <font color="#0000A0">Output</font> <font color="#0000A0">As</font> #FhWnd
           <font color="#0000A0">Print</font> #FhWnd, "dim wb, auxiliaryinstance, fso, objxl, starttime"
           <font color="#0000A0">Print</font> #FhWnd, "set wb = wscript.getobject(" & Chr(34) & ThisWorkbook.FullName & Chr(34) & ")"
           <font color="#0000A0">Print</font> #FhWnd, "set auxiliaryinstance = wb.parent"
           <font color="#0000A0">Print</font> #FhWnd, "wb.close false"
           <font color="#0000A0">Print</font> #FhWnd, "set objxl = wscript.createobject(" & Chr(34) & "excel.application" & Chr(34) & ")"
           <font color="#0000A0">Print</font> #FhWnd, "objxl.visible = true"
           <font color="#0000A0">Print</font> #FhWnd, "objxl.workbooks.open " & Chr(34) & ThisWorkbook.FullName & Chr(34)
           <font color="#0000A0">Print</font> #FhWnd, "on error resume next"
           <font color="#0000A0">Print</font> #FhWnd, "set wb = objxl.workbooks(" & Chr(34) & ThisWorkbook.Name & Chr(34) & ")"
           <font color="#0000A0">Print</font> #FhWnd, "starttime = now"
           <font color="#0000A0">Print</font> #FhWnd, "do until wb.isloaded"
           <font color="#0000A0">Print</font> #FhWnd, " set wb = objxl.workbooks(" & Chr(34) & ThisWorkbook.Name & Chr(34) & ")"
           <font color="#0000A0">Print</font> #FhWnd, " if datediff(" & Chr(34) & "s" & Chr(34) & ",starttime,now) > 5 then"
           <font color="#0000A0">Print</font> #FhWnd, " msgbox " & Chr(34) & "operation timed out or other error..." & Chr(34)
           <font color="#0000A0">Print</font> #FhWnd, " wscript.quit"
           <font color="#0000A0">Print</font> #FhWnd, " end if"
           <font color="#0000A0">Print</font> #FhWnd, "loop"
           <font color="#0000A0">Print</font> #FhWnd, "on error goto 0"
           <font color="#0000A0">Print</font> #FhWnd, "set wb.auxiliaryinstance = auxiliaryinstance"
           <font color="#0000A0">Print</font> #FhWnd, "set fso = createobject(" & Chr(34) & "scripting.filesystemobject" & Chr(34) & ")"
           <font color="#0000A0">Print</font> #FhWnd, "fso.deletefile wscript.scriptfullname"
       <font color="#0000A0">Close</font> #FhWnd
            
       <font color="#0000A0">Set</font> WshShell = CreateObject("WScript.Shell")
      <font color="#008000"> 'run the script to close and reopen this in another instance</font>
      <font color="#008000"> 'the script will delete it'self</font>
       WshShell.Run TempScriptFilename
  <font color="#0000A0">End</font> <font color="#0000A0">Sub</font>
  
</FONT></td></tr></table>
 
Upvote 0
hey Tom. This is a very creative piece of work and I find it quite educational as well. Thank you for that.

However, I am finding it a bit difficult to follow the progression of your code . What's the reason behind running a code from a vbs file for example?

Do you mind summarizing the logic of the code ?... in human language please :)

Regards.
 
Upvote 0
Tom and Right_Click,

Thanks for the suggestions.

Tom, I've gotten a variation of your code to work (thanks). I think Right_Click makes a valid point about reopening the same workbook in another application object, and that could definitely be a hazard that my end users would pose.

Right_Click, you nailed my issue with your post on 4/22 at 8:40. It's going to take me awhile to figure out the code you've provided, but it looks very promising. Thanks!
 
Upvote 0
Hi dewfall. It's copy and paste code. You should not need to edit it but it should work in any workbook. Admittedly, this is not production code and was just a "I think I can, I think I can" curiosity to see if I could. Tusharm might throw a conniption and Nate might post a lecture. :)

Jaafar. Giving a workbook the ability to close it'self and then reopen in another instance without it becoming read-only would require some kind of third party source. For example, if the code were contained in the workbook it'self, the code to reopen could not run because the workbook would be closed before running any code to reopen. So the workbook creates a vbscript file on the fly that gets a reference to the current application object(auxiliaryinstance), closes the workbook, creates a new application object, and reopens the workbook in the newly created instance. Once opened the script passes a reference to the auxiliaryinstance property of the workbook. This auxiliaryinstance is then available to open any workbook that the user attempts to open in the new orphaned workbook instance. Clear? :)
 
Upvote 0

Forum statistics

Threads
1,214,909
Messages
6,122,189
Members
449,072
Latest member
DW Draft

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