I want to open a workbook (WB1) and then as it's opened, another workbook (WB2) is opened. I want WB2 hidden.
Private Sub Workbook_Open()
Application.ScreenUpdating = False
Workbooks.Open Filename:="C:\WB2.xlsm"
ActiveWindow.Visible = False
End Sub
This is what I have so far and what it does is hide BOTH workbooks. I want WB1 to remain on top and visible.
Thank you! Josh
Private Sub Workbook_Open()
Dim wb as workbook
Application.ScreenUpdating = False
set wb=Workbooks.Open(Filename:="C:\WB2.xlsm")
wb.Windows(1).Visible = False
End Sub
an important part would seem to be how to turn view back on again.
other post is the answer.. i just had to see it work before i commited it.
hope this is enough to explain it, may have been done in less space. thanks.
i would have to agree to post a couple words describing the key working line. i am just novice at vb & have to say that 99% of posts require some research to get a needed variable in there. i believe so enough to add some expletives as hours by many can be spent, trying to find the dang answer, but will refrain : ).
the consequence is: everyone on the planet has to spend 2 to infinite hours.
(thanks for having code, to put code in a box, needs some tweaking for lines to include / space lines interfere?).
what i found: changing out may not work: .Visible and .Hidden
- have no idea what the 1 in windows(1) is for.
sub TEST1() 'in a module
'if want to happen when you open a wb, place in: "ThisWorkbook" module as:
'Private Sub Workbook_Open()
Dim wb As Workbook
'Set wb = Workbooks("WB2.xlsm") 'YES
'Set wb = Workbooks(Filename:="C:\WB2.xlsm") 'untried should work for path eg
'Set wb = Workbooks.Open(Filename:="C:\WB2.xlsm") 'original, with a command added: open
Application.ScreenUpdating = False
If 0 = 0 Then 'set to: if 0 = 1 to skip test
If wb.WINDOWS(1).Visible = False Then 'TOGGLES: press F5 or run macro button
wb.WINDOWS(1).Visible = True
MsgBox "Workbook is NOT Hidden" & Space(10), vbQuestion 'a good test method
Else
wb.WINDOWS(1).Visible = False '<< line to use, to hide wb on open
MsgBox "Workbook is Hidden" & Space(10), vbQuestion 'a good test method
End If
Else
wb.WINDOWS(1).Visible = False '<< line to use, to hide wb on open
end if
End Sub
This seems to be an old post but I thought I'd add in my version of the answer,as I was working on something similar.
Set m_WB = Workbooks("WB2FilePath\WB2.xlsm")
Windows(m_WB.Name).Visible = False
'Do work
'Set WorkBook to visible
Windows(m_WB.Name).Visible = True
Keep in mind, it would be good practice to set WB2 to visible once completed. This would avoid any memory being eaten up in the background without you knowing!
Cheers.
Related
I have two separated workbooks with macroces: Book1 with Macro1 and Book2 with Macro2.
Macro1 is simple code to:
hidely open Book2 (has an open password: 1111);
write "test" in A1 Active Sheet of Book2;
run Macro2 from Book2, which is simple MsgBox "Hello! I am an msgbox
from Book2";
close Book2 with saving.
Sub Macro1()
Application.ScreenUpdating = False
Application.EnableEvents = False
Application.DisplayAlerts = False
Dim myWb As Workbook
Set myWb = Workbooks.Open(ThisWorkbook.Path & "/" & "Book2.xlsb", True, False, , "1111")
myWb.Unprotect ("1111")
Cells(1, 1) = "test"
myWb.IsAddin = True
Application.Run "'Book2.xlsb'!Macro2"
myWb.Close savechanges:=True
Application.DisplayAlerts = True
Application.ScreenUpdating = True
Application.EnableEvents = True
End Sub
Sub Macro2()
MsgBox "Hello! I am an msgbox from Book2"
End Sub
I emphasize that everything should be done secretly and the user should not see neither Book2 nor any flashes, etc.
But when code comes to the saving step a window pops up on the screen, which, by the way, can be ignored and the code will continue to run/execute but anyway it's a PROBLEM I want get rid of:
password pop-up window
What I noticed:
If I remove the opening password from book2, the saving will be successfull and without pop-up dialogs. But I need Book2 opening protected.
I tried to modify code, but results are not unsatisfactory due to
screen blinking, screenshots below:
OK
V1-NOK
V2-NOK
V1: myWb.IsAddin = True is deleted/commented
Application.Run "'Book2.xlsb'!Macro2"
myWb.Close savechanges:=True
V2: ON/OFF IsAddin = True before/after Macro2 executing
myWb.IsAddin = True
Application.Run "'Book2.xlsb'!Macro2"
myWb.IsAddin = False
myWb.Close savechanges:=True
Please, try the next way. It will open the workbook in a new session, will write in its first sheet and run the macro. But a macro sending a message from a non visible session/window is not the best idea. In order to see the message, please move the cursor over the Excel workbooks icons on taskbar, select the MsgBox window and press OK. A better idea would be do avoid sending messages. The code should run as you need:
Sub HiddenWBOpenRunMacro()
Dim newEx As Excel.Application, myWb As Workbook
Set newEx = CreateObject("Excel.Application")
'Open the workbook in the newly created session:
Set myWb = newEx.Workbooks.Open(ThisWorkbook.Path & "/" & "Book2.xlsb", , , , "1111")
myWb.Sheets(1).cells(1, 1).Value = "Test" 'write in its first sheet
myWb.Application.Run "'Book2.xlsb'!Macro2" 'run the macro
myWb.Close True 'close the workbook, saving it
newEx.Quit 'quit the session
End Sub
If ThisWorkbook not in Excel Trusted Locations it must be added.
I have an unexpected display when closing a new workbook !
I launch my macro from the command line.
Application is made invisible from workbook_open :
Sub workbook_open()
Application.Visible = False
UserForm1.Show
Application.Visible = True
End Sub
UserForm1 contains a single button.
-> Only the userform is displayed.
Pressing the button starts the following code :
Sub UnexpectedDisplay()
Dim NewBook As Workbook
Debug.Print "_______________"
Application.Visible = False
Application.ScreenUpdating = False
Application.DisplayAlerts = False
Set NewBook = Workbooks.Add
With NewBook
.Title = "MyTitle"
.Subject = "Display"
.SaveAs Filename:="MyWorkbook"
End With
Debug.Print ActiveWorkbook.Name
MsgBox "New workbook added"
NewBook.Close SaveChanges:=True
Debug.Print ActiveWorkbook.Name
MsgBox "Workbook closed"
Application.DisplayAlerts = True
End Sub
The first msgbox is displayed : "New workbook added"
-> Only the msgbox is displayed.
Press "Ok"
The second msgbox is displayed : "Workbook closed"
Debug Trace :
_______________
MyWorkbook.xlsx
MyMacroFile.xlsm
-> A workbook becomes visible
( when MyMacroFile.xlsm is opened?).
-> Question : How to avoid this.
Please try this code.
Sub TestInVis()
Dim Wb As Workbook
Dim Fn As String
Fn = FileOpenName("Test")
Application.ScreenUpdating = False
Set Wb = Workbooks.Open(Fn)
Wb.Windows(1).Visible = False
Application.ScreenUpdating = True
End Sub
Before doing so, please set the variable Fn to contain a valid filename, complete with its path. (I used a function called FileOpenName which calls a FilePicker dialog.) The code will open the specified workbook and hide its window, leaving the previously displayed window on top.
In my test, the Open action didn't re-instate Screen Updating but I'm not sure that disabling it makes a difference. There is a short flicker while the workbook is being opened and I thought it was less pronounced while ScreenUpdating = False. It will be prolonged, however, if the file is large. One way or the other, the file opens invisibly and you can access it by the object variable to which it was assigned.
Next, I tested the same procedure with Workbooks.Add. All I said about about Open applies equally, except that the new workbook is very small, of course. Therefore it's even harder to tell whether ScreenUpdating really makes a difference.
I've encountered a strange thing: I've joined three workbooks: Personal Data Tracker, Global Tracker and the workbook with pivots and charts. The logic is as it follows: the user clicks on a button after the work is finished so the data is copied to the GL Tracker. Once the change event is triggered in the GL Tracker Table, the last workbook opens, the pivot is refreshed upon the open vent and the wb is closed.
Everything seems to be working fine, however when I run the macro live, at the very end I get an error message about
"Application-defined or object-defined error".
Only OK and Help button displayed, it doesn't make the VBE Open so I could debug it.
Would anyone know what it may be happening even if the whole chain works fine?
Thank you.
Code from the Personal Tracker:
Sub test()
Dim path As String
Dim wb As Workbook
path = ThisWorkbook.path & "\Dest.xlsm"
Application.ScreenUpdating = False
ThisWorkbook.Sheets("Total").Range("R1").Value = Date
Range("R1").Font.Color = VBA.ColorConstants.vbWhite
Worksheets("TOTAL").Range("B2:B13").Copy
On Error GoTo Handler
Workbooks.Open (path)
On Error GoTo 0
Set wb = Workbooks("Dest")
Worksheets("Sheet1").Range("B2").PasteSpecial Paste:=xlPasteValues
Exit Sub
Handler:
MsgBox "Someone else is saving their data at the moment." & vbNewLine & _
"Please try in a few seconds"
End Sub
Code from the GL Tracker:
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
Dim MRange As Range
Dim wbPivot As Workbook
Dim pt As PivotTable
Dim ws As Worksheet
Dim Name As String
Dim answer As VbMsgBoxResult
Set MRange = ThisWorkbook.Sheets(1).Range("Table1")
Name = Application.UserName
Application.ScreenUpdating = False
If Not Intersect(Target, MRange) Is Nothing Then
Application.EnableEvents = True
Set wbPivot = Workbooks.Open("C:\Users\jakub\Desktop\Excel - various\Pivot.xlsm")
End If
'refresh
For Each ws In wbPivot.Worksheets
For Each pt In ws.PivotTables
pt.PivotCache.Refresh
pt.Update
pt.RefreshTable
Next
Next
'saving
Application.ScreenUpdating = True
If Application.UserName <> "Jakub Tracz" Then
MsgBox "User not authorised. Workbook will be closed."
wbPivot.Close True
ThisWorkbook.Close True
Else
answer = MsgBox(Prompt:="Do you want to save and close the workbook?", _
Buttons:=vbYesNo + vbQuestion)
Select Case answer
Case vbYes
wbPivot.Close True
ThisWorkbook.Close True
Case vbNo
MsgBox "Welcome, " & Application.UserName
End Select
End If
End Sub
I'm going to give you a proof of concept code as an example for you to use. This will not exactly answer your question with code you can just copy/paste, but you will be able to use this to put it together the way you want it to work instead of me making assumptions about many things and restructuring it myself.
This simply demonstrates how to use a workbook object variable in one routine that can reference another workbook, and how to make changes to that 2nd workbook and save/close it.
Sub Tracker_Update()
Dim wbPivot as Workbook
' open the workbook
Set wbPivot = Workbooks.Open("C:\Users\jakub\Desktop\Excel - various\Test.xlsx")
' optionally make it hidden
wbPivot.Visible = False
With wbPivot
' pretend this code updates the pivot table
.Worksheets(1).Range("A1") = "hello world"
' Close and save it
.Close True
End With
' optionally clear the variable
' this is not really needed in VBA, but if you eventually
' start using VB.NET with Excel as a COM object,
' you will want to know how to do this part when you are done
Set wbPivot = Nothing
End Sub
I think you will like this approach in the end much better in the end anyway, as the code isn't scattered around so much in different places. Easier to debug later, and easier for someone else to understand what you are doing if and when you leave the company.
I've run into an interesting situation with Excel, and I was wondering if anyone of you knew an answer / solution.
Setup:
I have an empty excel worksheet with a ActiveX ToggleButton on it.
In a VBA code, I change the width of the button to 0, and then change the width to 100. (Why I do that is a different question, its part of a larger project, however, this causes the problem).
Then I set the save-status of the workbook to true, without actually saving the workbook.
Normally, if I now closed the workbook, it would just close, without asking me wether I want to save.
Now, due to the resizing, and even though the .Saved-Status is True, it asks me if I want to save when I close the workbook, and by clicking onto the close Icon of excel, the .Saved-Status is set to "False"
If you want to try for yourself, try the below steps.
Alternatively, I uploaded for convenience the same file here: (https://filebin.ca/3aLbbRxMTdUs/SavePromptUponResize.xlsm)
1) create a new workbook and add a new ACTIVEX toggle button.
2) in the VBA code of the workbook, add the below code
3) save the workbook, close it, and reopen it.
4) You should see a messagebox and after clicking, as second one
5) Now the status of the workbook is "saved"
6) Try to close the workbook -> you will be prompted if you want to save
7) If you check the .saved status now, it would say "false"
Looking forward to your insights!
Private Sub Workbook_Open()
MsgBox "Now a macro will run and resize twice the button you see." & vbCrLf & "Afterwards, the status of the workbook will be set to 'saved'." & vbCrLf & "However, upon closing, excel will still prompt to save."
Dim wb As Workbook: Set wb = ThisWorkbook
Dim ws As Worksheet: Set ws = wb.Sheets(1)
ws.Shapes("ToggleButton1").Width = 0
ws.Shapes("ToggleButton1").Width = 100
wb.Saved = True
MsgBox "Macro finished, save status is: " & wb.Saved
End Sub
Private Sub CheckSaveStatus()
MsgBox "Save status is: " & ActiveWorkbook.Saved
End Sub
The solution is as simple as this:
Private Sub Workbook_Open()
MsgBox "Now a macro will run and resize twice the button you see." & vbCrLf & "Afterwards, the status of the workbook will be set to 'saved'." & vbCrLf & "However, upon closing, excel will still prompt to save."
Dim wb As Workbook: Set wb = ThisWorkbook
Dim ws As Worksheet: Set ws = wb.Sheets(1)
Dim boolSaved As Boolean
boolSaved = wb.Saved
ws.Shapes("ToggleButton1").Width = 0
ws.Shapes("ToggleButton1").Width = 100
If boolSaved Then wb.Save
MsgBox "Macro finished, save status is: " & wb.Saved
End Sub
This technique can be used anywhere in your code where you need to do something that 'dirties' the workbook. The beauty of it is that it preserves the save prompt if the user has modified the workbook.
As to why it's happening, best guess is - a(nother) ActiveX bug in Excel.
Please try the below:
Option Explicit
Dim wb As Workbook
Dim ws As Worksheet
Dim i As Integer
Private Sub Workbook_BeforeClose(Cancel As Boolean)
If i = 1 Then
wb.Saved = False
Else
wb.Saved = True
End If
End Sub
Private Sub Workbook_Open()
MsgBox "Now a macro will run and resize twice the button you see." & vbCrLf & "Afterwards, the status of the workbook will be set to 'saved'." & vbCrLf & "However, upon closing, excel will still prompt to save."
Set wb = ThisWorkbook
Set ws = wb.Sheets(1)
ws.Shapes("ToggleButton1").Width = 0
ws.Shapes("ToggleButton1").Width = 100
End Sub
Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)
i = 1
End Sub
My experience has been that this Excel bug is triggered as a result of using VBA code to change the value of some properties of some ActiveX/OLE controls. I don't have a complete list of such properties but here's a few:
CommandButton:
Enabled property
Height property
TextBox:
ForeColor property
BackColor property
I use a generalized system (similar to Nikolaos Polygenis's solution), including extensive explanation due to this bug's subtlety, as follows:
In a standard module, define a project-global variable to indicate the no-save-needed condition:
'*************************************************************************************************************
'EXCEL OLE/ACTIVE-X SAVE-BUG WORKAROUND - BUG WORKAROUND - BUG WORKAROUND - BUG WORKAROUND - BUG WORKAROUND
'
'(See the Workbook_BeforeClose event handler, in the ThisWorkbook module, for a complete explanation.)
'
Public SuppressWkBkSaveMsg As Boolean
'
'END SAVE-BUG WORKAROUND - END WORKAROUND - END WORKAROUND - END WORKAROUND - END WORKAROUND - END WORKAROUND
'*************************************************************************************************************
In the ThisWorkbook module, place the following Workbook_BeforeClose event handler, with full explanation:
Private Sub Workbook_BeforeClose(Cancel As Boolean)
'*************************************************************************************************************
'EXCEL OLE/ACTIVE-X SAVE-BUG WORKAROUND - BUG WORKAROUND - BUG WORKAROUND - BUG WORKAROUND - BUG WORKAROUND
'
'Excel has a very subtle bug in which, if you change the value of some properties of some ActiveX/OLE
'controls, the parent workbook's Saved property will not function correctly until the next actual workbook
'save event. That is, you can subsequently set the workbook's Saved property to True but Excel will still
'prompt the user about whether to save the workbook when closing it. In fact, if you check the value of the
'Saved property in a Workbook_BeforeClose event handler, it will be defined as False even though no changes
'have been made to the workbook after explicitly setting it to True!
'
'The most effective workaround is to defer the override of the workbook's Saved property until the Close event
'has been actually initiated: declare the project-global SuppressWkBkSaveMsg variable in a standard module,
'add this Workbook_BeforeClose event handler to the ThisWorkbook module, and then set SuppressWkBkSaveMsg to
'True whenever it's necessary to suppress Excel's user-inquiry about whether to save changes to the workbook
'before closing it.
'
If SuppressWkBkSaveMsg Then Me.Saved = True
'
'END SAVE-BUG WORKAROUND - END WORKAROUND - END WORKAROUND - END WORKAROUND - END WORKAROUND - END WORKAROUND
'*************************************************************************************************************
End Sub
In any location in the code, in any module, whenever it's necessary to suppress Excel's user-inquiry about whether to save changes to the workbook before closing it, set SuppressWkBkSaveMsg to True:
'Do stuff that doesn't need to be saved, including modifications to OLE/ActiveX control-objects...
'
'*************************************************************************************************************
'EXCEL OLE/ACTIVE-X SAVE-BUG WORKAROUND - BUG WORKAROUND - BUG WORKAROUND - BUG WORKAROUND - BUG WORKAROUND
'
'(See the Workbook_BeforeClose event handler, in the ThisWorkbook module, for a complete explanation.)
'
SuppressWkBkSaveMsg = True
'
'END SAVE-BUG WORKAROUND - END WORKAROUND - END WORKAROUND - END WORKAROUND - END WORKAROUND - END WORKAROUND
'*************************************************************************************************************
'
'...
I have a simple question (I think). Let's say I set a global variable in a standard module in Book1 to an open (different) workbook:
Public Sub InitGlobals()
Set gwkb = Workbooks("book2.xlsx")
End Sub
Now I close book2.xlsx manually. What is the status of gwkb? This is what I get when I run various tests in the immediate window:
?gwkb is nothing
False
?isempty(gwkb)
False
?isnull(gwkb)
False
However, if I ask for any property of gwkb, such as gwkb.Name, I get an automation error.
My question is: is there a way to test for this condition, without resorting to some sort of "On Error Resume Next" test?
Thanks for your help.
If Book2 is initially open and may be closed then looping over the open books will not find it:
Public Sub InitGlobals()
Dim gwkb As Workbook, wb As Workbook
Set gwkb = Workbooks("Book2.xlsx")
gwkb.Close
For Each wb In Workbooks
If wb.Name = "Book2" Then
MsgBox wb.Name & " is open "
End If
Next wb
End Sub