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!
Related
Something strange is happening where I call a userform to show via a module, but it says object is required and does not initialize the form. The strange part is the method of calling does not change from a workbook that functions the exact same.
I have a module with the following code assigned to a button:
Sub SHOW_INSERT_TASK_FORM()
INSERT_TASK_FORM.Show ' Error Occurs here
End Sub
This should initialize the "INSERT_TASK_FORM" user form and run its code but I receive an object required error upon the "Show" method.
Here is the code imbedded within the user form:
Private Sub SUBMIT_BUTTON_Click()
Unload Me
End Sub
Private Sub UserForm_Initialize()
'DECLARE OBJECT VARIABLES
Dim planner_ws As Worksheet, data_ws As Worksheet
Dim departments As ListObject
Dim types As ListObject
Dim tasks As ListObject
Dim dep_arr() As Variant
Dim type_arr() As Variant
Dim task_arr() As Variant
Dim i As Double, j As Double, x As Double
Dim lrow As Double, srow As Double
'SET WS VARIABLES
Set planner_ws = ThisWorkbook.Worksheets("TASK_PLANNER")
Set data_ws = ThisWorkbook.Worksheets("DATA")
'ASSIGN OBJECT VARIABLES
Set departments = data_ws.ListObjects("DEPARTMENT_TABLE")
Set types = data_ws.ListObjects("TASK_TYPE_TABLE")
Set tasks = data_ws.ListObjects("TASKS_TABLE")
'ASSIGN VARIABLE VALUES
dep_arr = departments.DataBodyRange
type_arr = types.DataBodyRange
task_arr = tasks.DataBodyRange
lrow = planner_ws.Cells(planner_ws.Rows.Count, 2).End(xlUp).Row
'INITIAL USER FORM VALUES
TASK_NAME_TBOX.Value = ""
DESC_TBOX.Value = ""
SDATE_TBOX.Value = ""
EDATE_TBOX.Value = ""
Task_Option = False
Sub_Option = False
'POPULATE COMBO BOXES
With TYPE_CBOX
For i = LBound(type_arr) To UBound(type_arr)
.AddItem type_arr(i, types.ListColumns("Task_Type").Index)
Next i
End With
With DEP_CBOX
For i = LBound(dep_arr) To UBound(dep_arr)
.AddItem dep_arr(i, types.ListColumns("Department").Index)
Next i
End With
With TASK_CBOX
For i = LBound(task_arr) To UBound(task_arr)
.AddItem task_arr(i, types.ListColumns("Task Name").Index)
Next i
End With
End Sub
Private Sub SUB_OPTION_Click()
If Sub_Option.Value = True Then
Task_Label.Visible = True
TASK_CBOX.Visible = True
Else
Task_Label.Visible = False
TASK_CBOX.Visible = False
End If
End Sub
For reference, the following code in another workbook of mine works just fine:
Sub GameSale_Form()
xInput_GameSale.Show
End Sub
Private Sub UserForm_Initialize()
LCS_Option = False
NOTLCS_Option = False
Qty_TextBox.Value = ""
Discount_TextBox.Value = ""
InputCost_Textbox.Value = ""
InRegion_Option.Value = False
NotInRegion_Option = False
New_Option.Value = False
Used_Option.Value = False
InputCost_Option = False
AvCost_Option = False
FDAPricing_Option = False
NoFDAPricing_Option = False
With Cabinet_Combobox
For i = 2 To ThisWorkbook.Worksheets("List_Data").Cells(Rows.Count, 36).End(xlUp).Row
.AddItem ThisWorkbook.Worksheets("List_Data").Cells(i, 36).Value
Next i
End With
Opening_Textbox.Value = ""
Ambition_Textbox.Value = ""
Goal_Textbox.Value = ""
WalkAway_Textbox.Value = ""
Qty_SpinButton.Min = 0
Qty_SpinButton.Max = 1000
End Sub
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...
Any time I enable the macro below, the worksheet corrupts.
I have copied and pasted my data into a brand new book.
Upon saving and re-opening, I receive the "Do you want to attempt to recover as much as we can?" dialog, and the formatting on the macro-enabled sheet is reset, and the macro disabled.
I see this in the VBA editor, which appears like "Sheet 2" is being treated as some unknown object, and gives "First Article" another sheet variable.
Can anyone help?
Private Sub Worksheet_Activate()
Dim vars As Variant
vars = Array("<CLICK FOR VARIANT LIST>", "sensitive content hidden")
Dim sVars As String
sVars = Join(vars, ",")
With Range("E6").Validation
.Delete
.Add Type:=xlValidateList, Formula1:=sVars
End With
vars = Array("NOT SET", "SET")
sVars = Join(vars, ",")
With Range("I6").Validation
.Delete
.Add Type:=xlValidateList, Formula1:=sVars
End With
End Sub
Private Sub Worksheet_Change(ByVal Target As Range)
Dim vars As Variant
vars = Array("<CLICK FOR VARIANT LIST>", "sensitive content hidden")
If Target.Address = Range("E6").Address Then
Dim i As Integer
i = Application.Match(Range("E6").Value, vars, False)
If i = 1 Then
Range("A11:A109").EntireRow.Hidden = True
Range("D111:D112").EntireRow.Hidden = False
Else
Range("A11:A109").EntireRow.Hidden = False
Range("D111:D112").EntireRow.Hidden = True
Range("A1").Value = i + 6
End If
'SXM/HD
If i = 0 _
Or Range("E6").Value = "sensitive content hidden" Then
Range("hd_sw_row").EntireRow.Hidden = False
Range("hd_pn_row").EntireRow.Hidden = False
Range("sxm_pn_row").EntireRow.Hidden = False
Range("sxm_function_row").EntireRow.Hidden = False
Else
Range("hd_sw_row").EntireRow.Hidden = True
Range("hd_pn_row").EntireRow.Hidden = True
Range("sxm_pn_row").EntireRow.Hidden = True
Range("sxm_function_row").EntireRow.Hidden = True
End If
'DAB
If i = 0 _
Or Range("E6").Value = "sensitive content hidden"
Then
Range("dab_sw_row").EntireRow.Hidden = False
Range("dab_pn_row").EntireRow.Hidden = False
Range("dab_function_row").EntireRow.Hidden = False
Else
Range("dab_sw_row").EntireRow.Hidden = True
Range("dab_pn_row").EntireRow.Hidden = True
Range("dab_function_row").EntireRow.Hidden = True
End If
'GPS
If i = 0 _
Or Range("E6").Value = "sensitive content hidden"
Then
Range("gps_sw_row").EntireRow.Hidden = False
Range("gps_pn_row").EntireRow.Hidden = False
Range("gps_function_row").EntireRow.Hidden = False
Else
Range("gps_sw_row").EntireRow.Hidden = True
Range("gps_pn_row").EntireRow.Hidden = True
Range("gps_function_row").EntireRow.Hidden = True
End If
End If
End Sub
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
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.