Stop UserForm_Initialize from triggering ToggleButton_Click event - excel

I have one sheet ("Settings"), which needs to be hidden most of the time. I have created Settings UserForm which contains various settings buttons and toggle button in there hides/show that hidden sheet (then clicked and password is entered).
Macro for hiding/showing sheet:
Private Sub SettingsTB_Click()
Dim strPassTry As String
Dim strPassword As String
Dim lTries As Long
Dim bSuccess As Boolean
If SettingsTB.Value = True Then
strPassword = "asd"
For lTries = 1 To 3
strPassTry = InputBox("Enter password", "Show Settings sheet")
If strPassTry = vbNullString Then Exit Sub
bSuccess = strPassword = strPassTry
If bSuccess = True Then Exit For
MsgBox "Incorrect password"
Next lTries
If bSuccess = True Then
Worksheets("Settings").Visible = True
End If
Else
Worksheets("Settings").Visible = xlSheetHidden
End If
End Sub
That macro works as intended, problem arises then I open UserForm and "Settings" Sheet is left visible. UserForm_Initialize event triggers SettingsTB_Click event (ask for entering password).
Code in UserForm_initialize used for remembering toggle button position (without it, every time, UserForm is opened, toggle button in FALSE possition):
Private Sub UserForm_Initialize()
If Worksheets("Settings").Visible = True Then
SettingsTB.Value = True
Else
SettingsTB.Value = False
End If
End Sub
Is it possible to stop SettingsTB_Click from triggering on UserForm_Initialize or should I use completely different approach?

Use a public variable or the tag-property to stop the click-event from running.
Private Sub SettingsTB_Click()
Dim strPassTry As String
Dim strPassword As String
Dim lTries As Long
Dim bSuccess As Boolean
If SettingsTB.Tag Then Exit Sub
If SettingsTB.Value = True Then
strPassword = "asd"
For lTries = 1 To 3
strPassTry = InputBox("Enter password", "Show Settings sheet")
If strPassTry = vbNullString Then Exit Sub
bSuccess = strPassword = strPassTry
If bSuccess = True Then Exit For
MsgBox "Incorrect password"
Next lTries
If bSuccess = True Then
Worksheets("Settings").Visible = True
End If
Else
Worksheets("Settings").Visible = xlSheetHidden
End If
End Sub
Private Sub UserForm_Initialize()
SettingsTB.Tag = True
If Worksheets("Settings").Visible = True Then
SettingsTB.Value = True
Else
SettingsTB.Value = False
End If
SettingsTB.Tag = False
End Sub

Related

Use VBA code for enabling checkboxes on multiple rows

enter image description hereI have a spreadsheet that has 3 checkbox options for each row, I have created a VBA to disable the other 2 checkboxes once a checkbox is created (so that only 1 checkbox can be checked), however my solution only works for one row and I need some help in rewriting this so that it will apply to all rows please. (I'm new to VBA).
The code I have used is this:
Private Sub CheckBox1_Click()
If CheckBox1.Value = True Then
CheckBox2.Value = False
CheckBox2.Enabled = False
CheckBox3.Value = False
CheckBox3.Enabled = False
Else
CheckBox2.Value = False
CheckBox2.Enabled = True
CheckBox3.Value = False
CheckBox3.Enabled = True
End If
End Sub
Private Sub CheckBox2_Click()
If CheckBox2.Value = True Then
CheckBox1.Value = False
CheckBox1.Enabled = False
CheckBox3.Value = False
CheckBox3.Enabled = False
Else
CheckBox1.Value = False
CheckBox1.Enabled = True
CheckBox3.Value = False
CheckBox3.Enabled = True
End If
End Sub
Private Sub CheckBox3_Click()
If CheckBox3.Value = True Then
CheckBox1.Value = False
CheckBox1.Enabled = False
CheckBox2.Value = False
CheckBox2.Enabled = False
Else
CheckBox1.Value = False
CheckBox1.Enabled = True
CheckBox2.Value = False
CheckBox2.Enabled = True
End If
End Sub
You should probably just use Radios it would be a lot simpler.
If you are intent on doing this you will need to delete all your boxes and then put this code in. It will create and name your boxes and assign them code on click.
Alright, This needs to go in your Sheet module:
Sub Worksheet_Activate()
'Change Module2 to whatever the module name you are using is.
Module2.ActivateCheckBoxes ActiveSheet
End Sub
This next stuff will go into the module you're referencing from the Worksheet Module.
Sub ActivateCheckBoxes(sht As Worksheet)
If sht.CheckBoxes.Count = 0 Then
CreateCheckBoxes sht
End If
Dim cb As CheckBox
For Each cb In sht.CheckBoxes
'You may be able to pass sht as an object, It was giving me grief though
cb.OnAction = "'Module2.CheckBoxClick """ & cb.name & """, """ & sht.name & """'"
Next cb
End Sub
Sub CreateCheckBoxes(sht As Worksheet)
Dim cell As Range
Dim chkbox As CheckBox
With sht
Dim i As Long
Dim prevrow As Long
prevrow = 0
For Each cell In .Range("B2:D5") 'Change this to whatever range you want.
If prevrow < cell.row Then
prevrow = cell.row
i = 0
End If
Set chkbox = .CheckBoxes.Add(cell.Left, cell.Top, 30, 6)
With chkbox
.name = "CheckBox" & i & "_" & cell.row
.Caption = ""
End With
i = i + 1
Next cell
End With
End Sub
Sub CheckBoxClick(chkname As String, sht As String)
Dim cb As CheckBox
With Worksheets(sht)
For Each cb In .CheckBoxes
If Split(cb.name, "_")(1) Like Split(chkname, "_")(1) And Not cb.name Like chkname Then
cb.Value = -4146
End If
Next cb
End With
End Sub
You do not say anything about your sheet check boxes type... Please, test the next solution. It will be able to deal with both sheet check boxes type:
Copy this two Subs in a standard module:
Public Sub CheckUnCheckRow(Optional strName As String)
Dim sh As Worksheet, s As CheckBox, chK As OLEObject ' MSForms.CheckBox
Set sh = ActiveSheet
If strName <> "" Then
Set chK = sh.OLEObjects(strName) '.OLEFormat.Object
solveCheckRow chK.Object.Value, sh, Nothing, chK
Else
Set s = sh.CheckBoxes(Application.Caller)
solveCheckRow s.Value, sh, s
End If
End Sub
Sub solveCheckRow(boolVal As Long, sh As Worksheet, chF As CheckBox, Optional chK As OLEObject)
Dim s As CheckBox, oObj As OLEObject, iCount As Long
If Not chF Is Nothing Then
For Each s In sh.CheckBoxes
If chF.TopLeftCell.Address <> s.TopLeftCell.Address Then
If s.TopLeftCell.Row = chF.TopLeftCell.Row Then
s.Value = IIf(boolVal = -4146, 1, -4146): iCount = iCount + 1
If iCount = 2 Then Exit Sub
End If
End If
Next
ElseIf Not chK Is Nothing Then
For Each oObj In sh.OLEObjects
If oObj.TopLeftCell.Address <> chK.TopLeftCell.Address Then
If oObj.TopLeftCell.Row = chK.TopLeftCell.Row Then
boolStopEvents = True
oObj.Object.Value = IIf(boolVal = 0, True, False): iCount = iCount + 1
boolStopEvents = False
If iCount = 2 Then Exit Sub
End If
End If
Next
End If
End Sub
For case of Form check boxes type:
a). Manually assign the first sub to all your Form Type check boxes (right click - Assign Macro, choose CheckUnCheckRow and press OK).
b). Automatically assign the macro:
Dim sh As Worksheet, s As CheckBox
Set sh = ActiveSheet ' use here your sheet keeping the check boxes
For Each s In sh.CheckBoxes
s.OnAction = "'" & ThisWorkbook.Name & "'!CheckUnCheckRow"
Next
End Sub
If your check boxes have already assigned a macro, adapt CheckUnCheckRow, in Form check boxes section, to also call that macro...
For case of ActiveX check boxes:
a). Create a Public variable on top of a standard module (in the declarations area):
Public boolStopEvents
b). Manually adapt all your ActiveX check boxes Click or Change event, like in the next example:
Private Sub CheckBox1_Click()
If Not boolStopEvents Then CheckUnCheckRow "CheckBox1"
End Sub
Private Sub CheckBox2_Click()
If Not boolStopEvents Then CheckUnCheckRow "CheckBox2"
End Sub
Private Sub CheckBox3_Click()
If Not boolStopEvents Then CheckUnCheckRow "CheckBox3"
End Sub
and so on...
c). Or do all that with a click, using the next piece of code:
Sub createEventsAllActiveXCB()
Dim sh As Worksheet, oObj As OLEObject, strCode As String, ButName As String
Set sh = ActiveSheet 'use here your sheet keeping ActveX check boxes
For Each oObj In sh.OLEObjects
If TypeName(oObj.Object) = "CheckBox" Then
ButName = oObj.Name
strCode = "Private Sub " & ButName & "_Click()" & vbCrLf & _
" If Not boolStopEvents Then CheckUnCheckRow """ & ButName & """" & vbCrLf & _
"End Sub"
addClickEventsActiveXChkB sh, strCode
End If
Next
End Sub
Anyhow, the code cam be simplified in order to deal with only a type of such check boxes. If you intend to use it and looks too bushy, I can adapt it only for the type you like. Like it is, the code deals with both check box types, if both exist on the sheet...
Save the workbook and start playing with the check boxes. But, when you talk about check boxes on a row, all tree of them must have the same TopLeftCell.Row...

Excel Password protected sheet

I am using this code to password protect two pages.
For some weird reason I can hide "Sheet1" but not "Sheet2" as its always visiable.
The reason for the line Sheets(MySheet2).Visible = True is so if someone puts in the wrong password it won't just hide it instantly.
Private Sub Workbook_SheetActivate(ByVal Sh As Object)
Dim MySheets As String, Response As String
MySheet = "Sheet1"
MySheet2 ="Sheet2"
If ActiveSheet.Name = MySheet Then
ActiveSheet.Visible = False
Response = InputBox("Enter password to view sheet")
If Response = "MyPass" Then
Sheets(MySheet).Visible = True
Application.EnableEvents = False
Sheets(MySheet).Select
Application.EnableEvents = True
End If
End If
Sheets(MySheet).Visible = True
Private Sub Workbook_SheetActivate(ByVal Sh As Object)
If ActiveSheet.Name = MySheet2 Then
ActiveSheet.Visible = False
Response = InputBox("Enter password to view sheet")
If Response = "MyPass" Then
Sheets(MySheet2).Visible = True
Application.EnableEvents = False
Sheets(MySheet2).Select
Application.EnableEvents = True
End If
End If
Sheets(MySheet2).Visible = True
End Sub
I guess you're after this:
Private Sub Workbook_SheetActivate(ByVal Sh As Object)
Dim MySheets As String, Response As String
With ActiveSheet
Select Case .Name
Case "Sheet1", "Sheet2"
Application.EnableEvents = False
.Visible = False
Response = InputBox("Enter password to view sheet")
If Response = "MyPass" Then
.Visible = True
.Select
End If
Application.EnableEvents = True
End Select
End With
End Sub
as you should already know, this code is to be placed in ThisWorkbook code pane

Accessing Multiple pages in a User locked excel document

I am trying to create a budget document in which each department only has access to their particular page - I have that part working - I am having trouble allowing an ADMIN to access all of the pages.
This is what I have as the code for my UserForm so far: (I would like "Scott" to be able to open all of the pages not just "overview")
Dim bOK2Use As Boolean
Private Sub btnOK_Click()
Dim bError As Boolean
Dim sSName As String
Dim ws As Worksheet
Dim p As DocumentProperty
Dim bSetIt As Boolean
bOK2Use = False
bError = True
If Len(txtUser.Text) > 0 And Len(txtPass.Text) > 0 Then
bError = False
Select Case txtUser.Text
Case "Scott"
sSName = "Overview"
If txtPass.Text <> "act2" Then bError = True
Case "Chris"
sSName = "Run Crew"
If txtPass.Text <> "act2" Then bError = True
Case Else
bError = True
End Select
End If
If bError Then
MsgBox "Invalid User Name or Password"
Else
'Set document property
bSetIt = False
For Each p In ActiveWorkbook.CustomDocumentProperties
If p.Name = "auth" Then
p.Value = sSName
bSetIt = True
Exit For
End If
Next p
If Not bSetIt Then
ActiveWorkbook.CustomDocumentProperties.Add _
Name:="auth", LinkToContent:=False, _
Type:=msoPropertyTypeString, Value:=sSName
End If
bOK2Use = True
Unload UserForm1
End If
End Sub
Private Sub UserForm_Terminate()
If Not bOK2Use Then
ActiveWorkbook.Close (False)
End If
End Sub
Thank you!

Can't change application settings on workbook close

I have an Exit button on a userform. If the user clicks it I want it to return Excel's settings to it's original values and then close the workbook. The code in the Exit button is as follows:
Unload Me
If g_Released Then
ThisWorkbook.Close savechanges:=False
End If
The code in the Workbook_BeforeClose event is:
Private Sub Workbook_BeforeClose(Cancel As Boolean)
Dim bSaved As Boolean
bSaved = ThisWorkbook.Saved
ActiveWindow.DisplayWorkbookTabs = True
'more code here
The last line does not cause the workbook tabs to be displayed. Further in the code I also try to set things like Application.DisplayFormulaBar = True and so forth, but none of them have any impact. It appears as if these properties has somehow been forced into a read-only state, but I don't know why.
Edit: Here is the complete code.
Private Sub Workbook_Open()
InitialiseVariables
Application.ScreenUpdating = False
HideExcelUI Application, False, True, False, "Some Company", "Budgeting Module Release 0.1", ThisWorkbook.Path & "\Logo.ico"
HideWorksheetsUI False, False, False
wsBackground.Select
With Application
.WindowState = xlNormal
.Height = frmMain.Height
.Width = frmMain.Width
End With
Application.ScreenUpdating = True
DisplayFormInCenter frmMain
End Sub
Public Sub InitialiseVariables()
g_tDBfolder = ThisWorkbook.Path & "\"
Set g_cn = New ADODB.Connection
With g_cn
.Provider = "Microsoft.ACE.OLEDB.12.0"
.Properties("Data Source") = g_tDBfolder & g_tDBname
.Open
End With
g_ScenarioIsSaved = True
g_ScenarioID = CLng([Scenario_ID])
Set g_rBudgetYear = [BudgetYear]
Set g_rStartMonth = [StartMonth]
Set g_rDealerName = [DealerName]
Set g_rScenario = [Scenario]
End Sub
Public Sub HideExcelUI(ByRef xlApp As Excel.Application, _
ByVal ShowFormulaBar As Boolean, ByVal ShowScrollBars As Boolean, ByVal ShowStatusBar As Boolean, _
Optional ByVal strApplicationCaption As String, Optional ByVal strWindowCaption As String, Optional ByVal strIcoFile As String)
With xlApp
.ExecuteExcel4Macro "SHOW.TOOLBAR(""RIBBON"",FALSE)"
.DisplayFormulaBar = ShowFormulaBar
.DisplayScrollBars = ShowScrollBars
.DisplayStatusBar = ShowStatusBar
If strApplicationCaption <> "" Then
.Caption = strApplicationCaption
End If
If strWindowCaption <> "" Then
.Windows(1).Caption = strWindowCaption
End If
If strIcoFile <> "" Then
SetIcon strIcoFile, 0
End If
End With
End Sub
Public Sub HideWorksheetsUI(ByVal ShowGridlines As Boolean, ByVal ShowHeadings As Boolean, ByVal ShowWorkbookTabs As Boolean)
Dim ws As Worksheet, wsCurrent As Worksheet
Application.ScreenUpdating = False
Set wsCurrent = ActiveSheet
For Each ws In ThisWorkbook.Worksheets
ws.Activate
With ActiveWindow
.DisplayGridlines = False
.DisplayHeadings = False
.DisplayWorkbookTabs = False
.Caption = ""
End With
Next
wsCurrent.Activate
Application.ScreenUpdating = True
End Sub
Public Sub DisplayFormInCenter(ByVal objForm As Object, Optional ByVal bModeless As Boolean)
With objForm
.startupposition = 0
.Left = Application.Left + (0.5 * Application.Width) - (0.5 * .Width)
.Top = Application.Top + (0.5 * Application.Height) - (0.5 * .Height)
If bModeless Then
.Show vbModeless
Else
.Show
End If
End With
End Sub
Private Sub ExitButton_Click()
Unload Me
If g_Released Then
ThisWorkbook.Close savechanges:=False
End If
End Sub
Private Sub Workbook_BeforeClose(Cancel As Boolean)
Dim bSaved As Boolean, Success As Boolean
Dim UserResponse As Long
bSaved = ThisWorkbook.Saved
ActiveWindow.DisplayWorkbookTabs = True
If g_Released Then
If Not g_ScenarioIsSaved Then
UserResponse = MsgBox(Prompt:="There are unsaved changes in the current budget. Save changes?", Buttons:=vbYesNoCancel)
If UserResponse = vbYes Then
Success = SaveInputs(ActiveSheet)
If Not Success Then
MsgBox "Unexpected error. All inputs were not saved. Please contact vendor."
End If
ElseIf UserResponse = vbNo Then
'Go ahead and close
Else
Cancel = True
End If
End If
End If
ResetIconToExcel
ThisWorkbook.Saved = bSaved
End Sub

Unable to set the hidden property of the range class run time error '1003'

I have code in this module:
Sub HideSalTable()
User = Worksheets("log").Range("R1").Value
If User = ThisWorkbook.Worksheets("SSSSSS").Range("za1").Value Then
Columns("S:AA").EntireColumn.Hidden = True
ElseIf User = ThisWorkbook.Worksheets("SSSSSS").Range("za3").Value Then
Columns("S:AA").EntireColumn.Hidden = False
ElseIf User = ThisWorkbook.Worksheets("SSSSSS").Range("za4").Value Then
Columns("S:AA").EntireColumn.Hidden = False
End If
End Sub
I have a button to redirect me to ThisWorkbook.Worksheets("SSSSSS") with this code:
Private Sub Change_SSSSSS_Button_Click()
Dim pass1 As String
Dim pass2 As String
pass1 = ThisWorkbook.Worksheets("SSSSSS").Range("za3").Value
pass2 = ThisWorkbook.Worksheets("SSSSSS").Range("za4").Value
Dim Inp
Dim lTries As Long
lTries = 1
Do
Inp = InputBoxDK("enter password", "Zmhnk")
If Inp = "" Or Inp = vbCancel Then Exit Sub '* Cancel button pressed or nothing entered
If Inp = (pass1) Or Inp = (pass2) Then
Exit Do
End If
lTries = lTries + 1
If lTries > 4 Then
MsgBox "Error", vbInformation, "Zmhnk"
Exit Sub
Else
If MsgBox("try again", vbYesNo, "error_Zmhnk") = vbNo Then Exit Sub
End If
Loop
Application.ScreenUpdating = False
Sheets("SSSSSS").Visible = True
Sheets("SSSSSS").Activate
Application.ScreenUpdating = True
End Sub
The problem is when the user presses the button with the 2nd code I face an error and I don't know why.
The error:
Unable to set the hidden property of the range class run time error '1003'
Two things
1) You have not fully qualified your range. I understand that you are getting redirected but this is much safer.
Columns("S:AA").EntireColumn.Hidden = True
Change it to
ThisWorkbook.Sheets("SSSSSS").Columns("S:AA").EntireColumn.Hidden = True
2) I believe your worksheet is protected. You have to unprotect it. You can do that as follows
ThisWorkbook.Sheets("SSSSSS").Unprotect "myPassword"
when you have the control from the Form there is no Problem
but if you have it from the worksheet itself then it works actually but with Error:1004
so just use ( On Error Resume Next)
Private Sub ComboBox1_Change()
Dim wsMon As Worksheet
Set wsMon = ThisWorkbook.Worksheets("Montag")
On Error Resume Next
Select Case ComboBox1.ListIndex
Case 0
xHide (False)
wsMon.Rows("12:25").EntireRow.Hidden = True
xHide (True)
Case 1
xHide (False)
wsMon.Rows("12:25").EntireRow.Hidden = False
wsMon.Rows("19:25").EntireRow.Hidden = True
xHide (True)
Case 2
xHide (False)
wsMon.Rows("12:25").EntireRow.Hidden = False
xHide (True)
End Select
End Sub
xHide is a Boolean Function :
true
Application.ScreenUpdating = True
Application.DisplayAlerts = True
or False
Application.ScreenUpdating = False
Application.DisplayAlerts = False
I had a similar issue (only the error code was 1004, but the error message was the same). What solved the issue at my Excel sheet was to remove a comment which was within the range that I tried to hide. It seems like comments are not allowed within the range that should be hidden.

Resources