How to prevent a Boolean value from being reset? - excel

360 separate sheets make up this workbook.
The first sheet is the "Main Page," which is opened when the workbook is first opened, and has a userform that pops up containing the instructions for the main page.
For about 350 of the other sheets, there is a copy & pasted userform which contains instructions for those sheets, which all operate in the same manner.
Within those 350 userforms, there is a toggle button that flags a public variable as true, which prevents them from popping up again when the sheet is opened.
I want that toggle button to prevent those userforms from ever popping up again as long as the button is depressed on one of those pages.
If sheetOpenned = False Then
SubPageInstructions.Show
End If
sheetOpenned = True
End Sub
sheetOpenned is the public boolean declared at the top of the page. Is there a way to make this flag as true for every page?
The public Boolean is reset when the workbook is closed.
How can I
prevent the public Boolean from being reset?
prevent the toggle button in my Userforms from being auto toggled to their default value on workbook close?

Just for the record, I leave here the solution using the Windows Registry, registering the value of ToggleButton1 in it. In this example, I used a CommandButton, where the code evaluates whether there is a negation to display the Userform, written to the Registry. In the Userform itself, the code for registering the value of ToggleButton1 is saved, once clicked. The "VB & VBA Program Settings" subkey exists for each logged in user. So, for a new logged in user, the Userform will be displayed and, if the ToggleButton1 is clicked, it will be disabled for future reopenings of the Workbook.
On the Userform code pane:
Private Sub ToggleButton1_Click()
If Me.ToggleButton1.Value = True Then
'don't show Me again.
Me.ToggleButton1.Value = False
fToggleButton1_State = False
SaveSetting "My350Sheets", "SavedState", "ToggleButton1", False
Else
'uncomment the line below if you want the Userform to be shown again in the *NEXT* WB_open event
'SaveSetting "My350Sheets", "SavedState", "ToggleButton1", True
End If
End Sub
On a standard Module code pane:
Option Explicit
Public fToggleButton1_State As Boolean
On a CommandButton code:
Option Explicit
Private Sub CommandButton1_Click()
If fToggleButton1_State = True Then
UserForm1.Show
End If
End Sub

Related

Non modal UserForm and Workbook navigation

Very specific problem not related directly to code but more to Excel behavior.
When launching a non modal UserForm (vbmodeless) from a minimized WorkBook (not visible on screen), while another WorkBook is on screen, Excel will "link" this UserForm and its focus to the visible one. This means that minimizing or maximizing the second WorkBook will hide and show the UserForm, but doing so with the first WorkBook won't, even if it has been launched by the first WorkBook.
Worse, closing the second WorkBook will close the UserForm.
An example of the issue :
Sub TestSo()
Application.WindowState = xlMinimized
UFTest.Show vbModeless
End Sub
Just create an empty UserForm named UFTest, open 2 Workbooks and display them split mode on screen and then call this Sub. You'll see that the UserForm is now linked to the wrong WorkBook.
Is there any way to prevent this from happening?
Does it do the trick?
Sub TestSo()
UFTest.Show vbModeless
ThisWorkbook.Windows(1).Visible = False
End Sub
Then in Userform restore the visibility
Private Sub UserForm_Terminate()
ThisWorkbook.Windows(1).Visible = True
End Sub

How to hide an Excel workbook from VBA but NOT a UserForm?

I want to make a GUI-like interface for an Excel workbook, and I don't want the workbook to be visible until it closes. However, making the workbook not visible messes with the references of my code and I cannot read the ranges without heavily modifying it. I tried minimizing the window, but that minimizes the form as well.
Is there a way to keep the active workbook active but not readily visible, and the form visible?
Include the following when you load the userform
Private Sub UserForm_Initialize()
ThisWorkbook.Application.Visible = False
End Sub
and this for when you end the userform (return to normal state)
Private Sub UserForm_Terminate()
ThisWorkbook.Application.Visible = True
End Sub
put this code in form's UserForm_Initialize method
ActiveWindow.Visible = False

how to check if closing the excel (workbook) vba

I'm looking for a code that can return a boolean 0,1 or true or false, so that it can recognise if someone closes the excel by clicking on X
Open the VBA Editor, then go on ThisWorkbook (in the project tree on the left-side of the IDE) and you will access the code of the workbook events.
Then, from the dropdown list on the right-top select the event BeforeClose after having selected the Workbook object in the left-top dropdown menu, and you will get the following code on the module:
Private Sub Workbook_BeforeClose(Cancel As Boolean)
End Sub
That macro will be called every time someone tries to close the Workbook.
There, you can put a global variable to control the action, something like:
someoneIsClosing = True '<-- this is a globally defined variable
Cancel = True '<-- if you want to cancel the closing action
myMacro '<-- if you want to go back to "myMacro", i.e. any macro of your project and delegate it from handling the event.

Why, after launching a userform from a userform, does unloading the 2nd userform close both?

A button on a worksheet launches a macro that opens a userform (say, userform1). Userform1 is loaded non-modal in order for the user to use both userform1 and the worksheet (i.e., click cells) for input. There is a button on userform1 that, when clicked, opens another userform (say, userform2). Userform2 is modal. Clicking a Cancel button on userform2 unloads userform2 as it is supposed to; however, it, for some reason, also unloads userform1, which I do not want. If I make userform1 modal, then unloading userform2 does not unload userform1; however, the user can no longer use (i.e., click) the cells in the worksheet. I cannot find any info that will give me a clue as to why unloading one userform unloads both.
I am very happy I just stumbled upon this old thread.
What I discoverd is that the problem goes away when the VBA-editor window is closed. You really have to CLOSE it, minimizing the window is not enough. It also does not matter if the window is opend on the same screen or not. Only closing it did the trick for me. What I discoverd is that as soon as Form2 was unloaded, the VBA-editor shows Form2, no matter what other code-module I was just in.
I aimed to isolate the problem in a TestWorkbook.xlsm(review code below). I tried out the suggestions DoEvents and a line of code after Form2.Show and both helped. In my DevelopmentAddIn.xlam they did not help, the 1st form still closes. So the problem could still lay in the more complex code of my AddIn.
But like I said, closing the VBA-editor window does the trick, all though I still do not understand why.
TestWorkbook.xslm (two userforms Form1 and Form2 and a code module mLoad)
mLoad:
Option Explicit
Public Changed As Integer
'***Load the 1st form
Public Sub LoadFirstForm()
Load Form1
'allow user to change the active workbook
Form1.Show vbModeless
End Sub
'***Load a 2nd form (from Form1)
Public Sub LoadSecondForm()
Dim a As Integer
Load Form2
'continue after 2nd form closes
Form2.Show vbModal
'suggestions
a = 1
DoEvents
'2nd form was changed
If Changed = 1 Then
Form1.InfoBox.Value = "Changed"
'process changes
'2nd form is unchanged
Else
Form1.InfoBox.Value = "Unchanged"
End If
End Sub
Form1 (with button cmdLoad and textbox InfoBox)
'***Load the 2nd form (from Form1)
Private Sub cmdLoad_Click()
LoadSecondForm
End Sub
Form2: (with button cmdOK)
Option Explicit
'***Initial status is 'unchanged'
Private Sub UserForm_Initialize()
Changed = 0
End Sub
'***Status is 'changed'
Private Sub cmdOk_Click()
Changed = 1
'close 2nd form and continue
Unload Me
End Sub
UserForm2.Show
a = 1 ' only 1 more line of any code to execute
this will do the trick. At least this worked for me with the same issue...

Excel VBA: Save As triggers Change event in ComboBox

I have an Excel workbook containing some ComboBox controls placed directly on the sheets. These are standard combo boxes from the Forms toolbar.
When the user uses "Save As" to save the workbook with a different name, this triggers the Change event on all the combo boxes, including ones on sheets that aren't active. This seems unreasonable as the selection hasn't actually changed. This causes various undesirable behaviour because of the code in the event handlers. The event isn't triggered on a simple "Save".
Google suggests this is a known problem in Excel. There are rumours that it's caused by using a named range as the ListFillRange for the combo box, which I have done, although it's not a volatile name. I'm looking for a way to prevent this happening with minimal changes to the code and the spreadsheet. Does anyone have a proven solution?
I did the following in a new workbook with only one sheet, Sheet1, and it seemed to work to diable events before save and then reenable them after. It should bypass the problem you see by mimicing an AfterSave event. This is my event code on Sheet1 (could be OLEObject code, too)
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
MsgBox Target.Address & ": " & Target.Value
End Sub
This is my ThisWorkbook code
Option Explicit
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
' To see the change code work before disabling
' Should show a message box
Sheet1.Range("A1") = "Before After Events Off"
Application.EnableEvents = False
Application.OnTime Now, "ThisWorkbook.Workbook_AfterSave"
' This time it will not show a message box
' You will never see this one . . .
Sheet1.Range("A1") = "After After Events Off"
End Sub
Private Sub Workbook_AfterSave()
Application.EnableEvents = True
End Sub
The .OnTime method throws the AfterSave "event" onto the execution queue. It works!
You could set a flag in the Workbook's BeforeSave event and then check that flag before processing a change event in each of the combo boxes. There does not seem to be an AfterSave event, so you would need to clear the flag after checking it within the combo box change events. The flag would need to be more than a simple boolean since it could not be turned off until all combo box change events were processed. Here's some sample code:
Public ComboBoxChangeCounter As Integer
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
Const NumOfComboBoxChangeEvents As Integer = 5
ComboBoxChangeCounter = NumOfComboBoxChangeEvents
End Sub
Function JustSaved() As Boolean
If ComboBoxChangeCounter > 0 Then
ComboBoxChangeCounter = ComboBoxChangeCounter - 1
JustSaved = True
End If
End Function
Private Sub Combo1_Change()
If JustSaved Then Exit Sub
'Your existing code '
' ... '
' ... '
' ... '
End Sub
I set the number of combo box change events as a constant, but there may be some way for you to determine that number programmatically. This workaround does require adding code to every combo box change event, but it should be easy as all you need to do is copy and paste the line If JustSaved Then Exit Sub at the beginning of each event.
This workaround assumes that the Workbook BeforeSave event will get called prior to the combo box change events. I don't know for a fact if that's the case.

Resources