I'm Using Excel 2013 vba. I have 2 Forms: frmMain and . In frmMain, I only have a cmd button with a code UserForm1.show ,however i can't open the UserForm1.
Here's my code:
Private Sub Workbook_Open()
Application.Visible = False 'This code hides the workbook
UserForm1.Show 'Brings the UserForm
End Sub
'Module1 Code..
Sub hidden()
Sheet1.Visible = False
End Sub
screenshot of my UserForm1
Code for UserForm1...
'Application.ScreenUpdating = False
'Sheets("Sheet1").Visible = True
Private Sub cmbCalltype_Change()
'==========sayon rani dri=======
'If cmbCalltype.List(cmbCalltype.ListIndex) = "Training" Then
' cmbGc.Enabled = False
'ElseIf cmbCalltype.List(cmbCalltype.ListIndex) = "Wrong GC" Then
' cmbGc.Enabled = False
'ElseIf cmbCalltype.List(cmbCalltype.ListIndex) = "Wrong Number" Then
' cmbGc.Enabled = False
'ElseIf cmbCalltype.List(cmbCalltype.ListIndex) = "Resident" Then
' cmbGc.Enabled = False
'Else
' cmbGc.Enabled = True
'End If
If cmbCalltype.Text = "Training" Then
cmbGc.Enabled = False
ElseIf cmbCalltype.Text = "Resident" Then
cmbGc.Enabled = False
ElseIf cmbCalltype.Text = "Wrong GC" Then
cmbGc.Enabled = False
ElseIf cmbCalltype.Text = "Wrong Number" Then
cmbGc.Enabled = False
Else
cmbGc.Enabled = True
End If
End Sub
Private Sub cmdApplicationshow_Click()
Application.Visible = True 'This will open the excel file...
End Sub
Private Sub cmdClear_Click()
'==========sayon rani dri=======
'Call UserForm_Initialize
txtName.Value = ""
cmbCalltype.Value = ""
cmbGc.Value = ""
cmbVisit.Value = ""
End Sub
Private Sub cmdHidden_Click()
Application.Visible = False 'This will open the excel file...
End Sub
Private Sub cmdMove_Click()
'Dim emptyRow As Long
'Sheet1.Activate 'Make Sheet1 active
'emptyRow = WorksheetFunction.CountA(Range("A:A")) + 1
'Transfer information
'Cells(emptyRow, 1).Value = txtName.Value
'Cells(emptyRow, 2).Value = cmbCalltype.Value
'Cells(emptyRow, 3).Value = cmbVisit.Value
With Sheet1
With .Range("A" & .Rows.Count).End(xlUp)
.Offset(1).Resize(1, 4).Value = Array(txtName.Value, cmbCalltype.Value, cmbGc.Value, cmbVisit.Value)
End With
txtLeasing.Value = Application.CountIf(.Columns(2), "Leasing") 'counting the number of instances leasing text occur
txtGc.Value = Application.CountIf(.Columns(3), "Yes")
'txtYes.Value = Application.CountIf(.Columns(4), "Yes")
'txtNo.Value = Application.CountIf(.Columns(4), "No")
txtPercentage.Value = txtGc.Value / txtLeasing.Value * 100
''==================
txtVisLeasing.Value = txtLeasing.Value
txtTotvisit.Value = Application.CountIf(.Columns(4), "Yes")
txtVisitper.Value = txtTotvisit.Value / txtVisLeasing * 100
End With
End Sub
Private Sub UserForm_Initialize()
'Worksheets("Sheet1").Activate
'Sheets("Sheet1").Visible = False
txtName.Value = "" 'Empty Customer
cmbCalltype.Value = "" 'Empty Call Type
cmbGc.Value = "" 'Empty GC
cmbVisit.Value = "" 'Empty Visit
cmbCalltype.Clear
With cmbCalltype
.AddItem "Leasing"
.AddItem "Training"
.AddItem "Resident"
.AddItem "Wrong GC"
.AddItem "Wrong Number"
End With
cmbGc.Clear
With cmbGc
.AddItem "Yes"
.AddItem "No"
End With
cmbVisit.Clear
With cmbVisit
.AddItem "Yes"
.AddItem "No"
End With
txtName.SetFocus
End Sub
Is the instance of UserForm1 called from Workbook_Open() same as the instance of UserForm1 called from frmMain ?
If Yes, then create a Module and declare the instance of UserForm1 in Module1 as Public.
If No, then declare a form level instance of UserForm1 in frmMain.
Something like below.
'frmMain Code
Dim fUser As UserForm1
Private Sub CommandButton1_Click()
If fUser Is Nothing Then
fUser = New UserForm1
End If
fUser.Show
End Sub
Related
maybe you can help me with this issue:
I am trying to set for one excel sheet different kind of privileges.
For example, there will be an Admin with all right and a guest, how is only allowed the change an range of cells.
I started to setup 2 different kind of logins, the one for the admin is working well however the one for the guest not at all.
What am I doing wrong here?
Ps: I just started to learn VBA ☺
Private Sub CommandButton1_Click()
Dim objTargetWorksheet As Worksheet
'Gast
If (TextBox1.Value = "Gast" And TextBox2.Value = "123") _
Or (TextBox1.Value = "Amy" And TextBox2.Value = "345") _
Or (TextBox1.Value = "Paul" And TextBox2.Value = "456") Then
Me.Hide: Application.Visible = True
For Each objTargetWorksheet In ActiveWorkbook.Worksheets
If objTargetWorksheet.Name = TextBox1.Value Then
Range("K3:K50").Locked = True
ActiveSheet.Protect Password:="12345", Contents:=True
Else
Range("K3:K50").Locked = True
ActiveSheet.Protect Password:="12345", Contents:=True
End If
Next
'Admin
ElseIf TextBox1.Value = "Admin" Then
If TextBox2.Value = "" Then
MsgBox "Please Input the Password"
ElseIf TextBox2.Value = "123" Then
Me.Hide: Application.Visible = True
Else
MsgBox "Please Input the right User Name and the right Password"
End If
Else
MsgBox "Please input the right user name and the right password"
End If
End Sub
Private Sub CommandButton2_Click()
ThisWorkbook.Application.Quit
End Sub
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer)
ThisWorkbook.Application.Quit
End Sub
You need to reference the sheet you are working on.
For Each objTargetWorksheet In ActiveWorkbook.Worksheets
If objTargetWorksheet.Name = TextBox1.Value Then
objTargetWorksheet.Range("K3:K50").Locked = True
objTargetWorksheet.Protect Password:="12345", Contents:=True
Else
objTargetWorksheet.Range("K3:K50").Locked = True
objTargetWorksheet.Protect Password:="12345", Contents:=True
End If
Next
UPDATE: Cells are locked by default so you actually have to unlock them before protecting the sheet. Try this:
For Each objTargetWorksheet In ActiveWorkbook.Worksheets
If objTargetWorksheet.Name = TextBox1.Value Then
objTargetWorksheet.Cells.Locked = False
objTargetWorksheet.Range("K3:K50").Locked = True
objTargetWorksheet.Protect Password:="12345", Contents:=True
Else
objTargetWorksheet.Cells.Locked = False
objTargetWorksheet.Range("K3:K50").Locked = True
objTargetWorksheet.Protect Password:="12345", Contents:=True
End If
Next
I am running two VBA formulas.
The first hides all cells with empty information the first column.
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim c As Range
On Error Resume Next
Application.ScreenUpdating = False
For Each c In Range("A3:A49")
If c.Value = vbNullString Then
c.EntireRow.Hidden = True
End If
Next c
For Each c In Range("A3:A47")
If c.Value <> vbNullString Then
c.EntireRow.Hidden = False
End If
Next c
Application.ScreenUpdating = True
End Sub
The second Formula strings data together and placeses this information in the next cell that is empty (aka the first hidden cell) when the button is clicked.
Option Explicit
Dim iwsh As Worksheet
Dim owsh As Worksheet
Dim output As String
Dim i As Integer
Sub Copy()
Set iwsh = Worksheets("Budget")
Set owsh = Worksheets("Release Burnup")
i = 3
While owsh.Cells(i, 1) <> ""
i = i + 1
Wend
output = "R" & iwsh.Cells(13, 2).Value & "-S" & iwsh.Cells(14, 2).Value
owsh.Cells(i, 1) = output
ActiveSheet.EnableCalculation = False
ActiveSheet.EnableCalculation = True
End Sub
Previously, this has been causing no problem... Something has happened that is causing the workbook to crash anytime I try to delete information out of one of the cells with the new data.
PS: This is the list of my other formulas. maybe there is something in these that is interacting with the formentioned code?
Private Sub NewMemberBut_Click()
'causes userform to appear
NewMember.Show
'reformats button because button kept changing size and font
NewMemberBut.AutoSize = False
NewMemberBut.AutoSize = True
NewMemberBut.Height = 40.25
NewMemberBut.Left = 303.75
NewMemberBut.Width = 150
End Sub
'Similar code to the problematic code in question, but this one works fine
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim c As Range
On Error Resume Next
Application.ScreenUpdating = False
For Each c In Range("A3:A35,A41:A80")
If c.Value = vbNullString Then
c.EntireRow.Hidden = True
End If
Next c
For Each c In Range("A3:A35,A41:A80")
If c.Value <> vbNullString Then
c.EntireRow.Hidden = False
End If
Next c
Application.ScreenUpdating = True
End Sub
'Code for UserForm
Option Explicit
Dim mName As String
Dim cName As String
Dim mRole As String
Dim cRole As String
Dim i As Integer
Dim x As Integer
Dim Perc As Integer
Dim Vac As Integer
Dim Prj As Worksheet
Dim Bud As Worksheet
Private Sub NewMember_Initialize()
txtName.Value = ""
cboRoleList.Clear
Scrum.Value = False
txtPercent.Value = ""
txtVacation.Value = ""
txtName.SetFocus
End Sub
Private Sub AddMember_Click()
If Me.txtName.Value = "" Then
MsgBox "Please enter a Member name.", vbExclamation, "New Member"
Me.txtName.SetFocus
Exit Sub
End If
If Me.cboRoleList = "Other" And Me.txtCustomRole = "" Then
MsgBox "Please provide a role name.", vbExclamation, "Other Role"
Exit Sub
End If
If Me.cboRoleList.Value = "" Then
MsgBox "Please select a Role.", vbExclamation, "Member Role"
Me.cboRoleList.SetFocus
Exit Sub
End If
If Me.cboRoleList <> "Other" And Me.txtPercent = "" Then
MsgBox "Please select a valid percentage to be applied to this sprint.", vbExclamation, "Sprint Percent"
Me.txtPercent.SetFocus
Exit Sub
End If
If Me.txtPercent.Value > 100 And Me.txtPercent <> "" Then
MsgBox "Please select a valid percentage to be applied to this sprint.", vbExclamation, "Sprint Percent"
Me.txtPercent.SetFocus
Exit Sub
End If
If Me.txtVacation.Value = "" Then
Me.txtVacation.Value = 0
End If
Dim i As Long
Set Prj = Worksheets("Project Team")
Set Bud = Worksheets("Budget")
Prj.Activate
i = 5
x = 1
If Me.cboRoleList.Value = "Other" Then
i = 46
End If
While Prj.Cells(i, 1) <> ""
i = i + 1
Wend
If cboRoleList = "Other" Then
Cells(i, x).Value = txtCustomRole.Value
End If
If cboRoleList <> "Other" Then
Cells(i, x).Value = cboRoleList.Value
End If
x = x + 1
Cells(i, x).Value = txtName.Value
x = x + 1
If Me.cboRoleList.Value <> "Other" Then
Cells(i, x).Value = txtPercent.Value
End If
Unload Me
End Sub
Private Sub CloseBut_Click()
Unload Me
End Sub
Change the event driven Worksheet_SelectionChange to Worksheet_Change and isolate further by only processing when something changes in A3:A49.
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range("A3:A49")) Is Nothing Then
On Error GoTo safe_exit
Application.EnableEvents = False
Application.ScreenUpdating = False
Dim c As Range
For Each c In Intersect(Target, Range("A3:A49"))
c.EntireRow.Hidden = CBool(c.Value = vbNullString)
Next c
End If
safe_exit:
Application.EnableEvents = True
Application.ScreenUpdating = True
End Sub
Caveat: A Worksheet_Change is not triggered on the change in a cell from the cell's formula. Only by typing, deleting or dragging a cell's contents. Adding or removing a formula will trigger it but not when a formula's result changes from another value somewhere in the workbook changing. This should not affect you as no formula can return vbNullString but it is worth mentioning for others.
I have created a report template that allows users to select various filters and then creates specific reports based on those filters. Below is the code for the filter selection button:
Sub Filter_Select()
rptSelect.Show
End Sub
After this, users are presented with UserForms to select different filters. Each UserForm calls the next user form until they reach the last UserForm whose code is such:
Private Sub UserForm_Activate()
With milSelect
.Top = Application.Top + 250
.Left = Application.Left + 250
End With
End Sub
--------------------------------------------------
Private Sub UserForm_Initialize()
milDV.RowSource = Range("Q1:Q8").Address
End Sub
--------------------------------------------------
Private Sub CancelmilSelect_Click()
Unload Me
End Sub
--------------------------------------------------
Private Sub OKmilSelect_Click()
Sheets("Report Selection").Unprotect
Range("B6").ClearContents
Range("B6") = milDV.Text
Unload Me
Call Create_Report
End Sub
Once they select the final filter, the Create_Report macro is run to determine which reports to create and what formulas to use based on the filters selected. The code is as such:
Option Explicit
Sub Create_Report()
'
' Macro to update fields in different reporting sections after user selects report type
'
'
Application.EnableEvents = False
Application.Calculation = xlCalculationManual
Application.ScreenUpdating = False
'
' Display Tabs
'
Dim z As Integer
For z = 2 To Worksheets.Count
Sheets(z).Visible = xlSheetHidden
Next z
If Range("B1").Value = "National" And Range("B6") = "Military" Then
Sheets("Program Summary").Visible = xlSheetVisible
Else
If Range("B1") = "National" Then
Sheets("Program Summary").Visible = xlSheetVisible
Sheets("Family & Household Demographics").Visible = xlSheetVisible
Sheets("Registered Member Dues").Visible = xlSheetVisible
Else
Sheets("Program Summary").Visible = xlSheetVisible
Sheets("Summary").Visible = xlSheetVisible
Sheets("Financial Summary").Visible = xlSheetVisible
End If
End If
'
' Financial Summary
'
If Sheets("Financial Summary").Visible = True Then
Sheets("Financial Summary").Select
Sheets("Financial Summary").Unprotect
'
' Name Ranges
'
Dim Operating_Expenses, Income_Private1, Income_Private2, Income_Private3, Income_Gov, Income_Other1, Income_Other2 As Range
Set Operating_Expenses = Range("C5:C7")
Set Income_Private1 = Range("C13")
Set Income_Private2 = Range("C14:C16")
Set Income_Private3 = Range("C17")
Set Income_Gov = Range("C19:C22")
Set Income_Other1 = Range("C25:C26")
Set Income_Other2 = Range("C27:C30")
'
' State Non-Military Financial Summary
'
If Worksheets("Report Selection").Range("B1").Value = "State" Then
If Worksheets("Report Selection").Range("B6").Value = "Non-Military" Then
Range("B1").Value = Worksheets("Report Selection").Range("B4").Value
Range("C1").Value = "Non-Military"
Operating_Expenses.Formula = "=SUMIFS(INDEX('Financial Data'!$BE:$BG, 0, ROW(1:1)),'Financial Data'!$E:$E,$B$1,'Financial Data'!$H:$H,""0"")"
Income_Private1.Formula = "=SUMIFS(INDEX('Financial Data'!$AO:$AO, 0, ROW(1:1)),'Financial Data'!$E:$E,$B$1,'Financial Data'!$H:$H,""0"")"
Income_Private2.Formula = "=SUMIFS(INDEX('Financial Data'!$AL:$AN, 0, ROW(1:1)),'Financial Data'!$E:$E,$B$1,'Financial Data'!$H:$H,""0"")"
Income_Private3.Formula = "=SUMIFS(INDEX('Financial Data'!$AQ:$AQ, 0, ROW(1:1)),'Financial Data'!$E:$E,$B$1,'Financial Data'!$H:$H,""0"")"
Income_Gov.Formula = "=SUMIFS(INDEX('Financial Data'!$BA:$BD, 0, ROW(1:1)),'Financial Data'!$E:$E,$B$1,'Financial Data'!$H:$H,""0"")"
Range("C24").Formula = "=SUMIFS('Financial Data'!$AP:$AP,'Financial Data'!$E:$E,$B$1,'Financial Data'!$H:$H,""0"")"
Income_Other1.Formula = "=SUMIFS(INDEX('Financial Data'!$AV:$AW, 0, ROW(1:1)),'Financial Data'!$E:$E,$B$1,'Financial Data'!$H:$H,""0"")"
Income_Other2.Formula = "=SUMIFS(INDEX('Financial Data'!$AR:$AU, 0, ROW(1:1)),'Financial Data'!$E:$E,$B$1,'Financial Data'!$H:$H,""0"")"
Range("C31").Formula = "=SUMIFS('Financial Data'!$AZ:$AZ,'Financial Data'!$E:$E,$B$1,'Financial Data'!$H:$H,""0"")"
Range("C32").Formula = "=SUMIFS('Financial Data'!$AY:$AY,'Financial Data'!$E:$E,$B$1,'Financial Data'!$H:$H,""0"")"
Range("C33").Formula = "=SUMIFS('Financial Data'!$AK:$AK,'Financial Data'!$E:$E,$B$1,'Financial Data'!$H:$H,""0"")"
End If
End If
End If
'
' Select First Sheet of Report
'
Dim i As Integer
Dim ws As Worksheet
For i = 1 To Worksheets.Count
If Sheets(i).Visible = True Then
Sheets(i).Protect
End If
Next i
For i = 2 To Worksheets.Count
If Sheets(i).Visible = True Then
Sheets(i).Select
Exit For
End If
Next i
Application.EnableEvents = True
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
End Sub
All of the code runs properly and the reports are created, but I'm having a bug where when I try to scroll on the sheet that is displayed after the code runs, the scroll bar moves but the cells seem stuck in place. If I try to select a cell and move with the arrow key, the selection jumps around. Both of these things are solved by going to another sheet and then coming back.
Additionally, after this code runs, I cannot close Excel with any method other than through Task Manager. Since none of this happens when I first open the workbook, I am left to assume that my above code is somehow causing this.
Sorry it took so long to get back to this. I've been swamped the past week. Anyways, I've finally solved the problem thanks to some direction from #Comintern. Basically, I took all of the grunt work out of each of my forms and put it in the Module that the filter button calls.
Not only is this a more streamlined and efficient way to work with the code, it also provides a centralized location to assess any errors that may crop-up essentially eliminating a few possible points of failure. Below is both the code for the filter button and the code for one of the filter forms.
New form code:
Private Sub UserForm_Activate()
With milSelect
.Top = Application.Top + 250
.Left = Application.Left + 250
End With
End Sub
---------------------------------------------------
Private Sub UserForm_Initialize()
milDV.RowSource = Range("Q1:Q8").Address
End Sub
Private Sub CancelmilSelect_Click()
Unload Me
End Sub
---------------------------------------------------
Private Sub OKmilSelect_Click()
Sheets("Report Selection").Unprotect
Range("B6").ClearContents
Range("B6") = milDV.Text
Me.Hide
End Sub
Filter button code:
Sub Filter_Select()
Dim ReportType As String
Dim Region As String
Dim ServiceUnit As String
Dim State As String
Dim Military As String
With New rptSelect
.Show vbModal
If Not Cancel = True Then
If Range("B1").Value = "National" Then
With New milSelect
.Show vbModal
If Not Cancel = True Then
Unload rptSelect
Unload milSelect
Call Create_Report
End If
End With
Else
If Range("B1").Value = "Service Unit" Then
With New SUSelect
.Show vbModal
If Not Cancel = True Then
With New milSelect
.Show vbModal
If Not Cancel = True Then
Unload rptSelect
Unload milSelect
Unload SUSelect
Call Create_Report
End If
End With
End If
End With
Else
If Range("B1").Value = "Regional" Then
With New rgnSelect
.Show vbModal
If Not Cancel = True Then
With New milSelect
.Show vbModal
If Not Cancel = True Then
Unload rptSelect
Unload milSelect
Unload rgnSelect
Call Create_Report
End If
End With
End If
End With
Else
If Range("B1").Value = "State" Then
With New stateSelect
.Show vbModal
If Not Cancel = True Then
With New milSelect
.Show vbModal
If Not Cancel = True Then
Unload rptSelect
Unload milSelect
Unload stateSelect
Call Create_Report
End If
End With
End If
End With
End If
End If
End If
End If
End If
End With
End Sub
I'm sure there is probably a cleaner way to write this other than how it appears here and welcome any suggestions anyone may have for making it look better, but for now at least, it is working like a charm. Thanks for everyone's input and patience.
So here is my initial code:
Option Explicit
Private Sub clearButton_Click()
ClearUFData 'clears the form
End Sub
Private Sub enterButton_Click()
If Not CheckInputs Then Exit Sub 'check for fields to have values
Process GetWs(Me.impactCombobox.Value) ' process data passing the proper worksheet got from GetWs() function
MsgBox "Project Entered Successfully"
ClearUFData 'clear the data
End Sub
Private Sub Process(ws As Worksheet)
Dim iRow As Long
Dim MonthNumber As Byte
Dim ColumnNumber As Long: ColumnNumber = 4
'find first empty row in database
iRow = ws.Cells.Find(What:="*", SearchOrder:=xlRows, _
SearchDirection:=xlPrevious, LookIn:=xlValues).row + 1
'copy the data to the database
'use protect and unprotect lines,
' with your password
' if worksheet is protected
With ws
'.Unprotect Password:="password"
.Cells(iRow, 1).Value = Me.nameTextbox.Value
.Cells(iRow, 2).Value = Me.projectTextbox.Value
.Cells(iRow, 3).Value = Me.audienceCombobox.Value
For MonthNumber = 0 To 11
If lengthListbox.Selected(MonthNumber) Then
.Cells(iRow, ColumnNumber).Value = "Yes"
Else
.Cells(iRow, ColumnNumber).Value = "No"
End If
'Increase the column Index for each time through the loop
ColumnNumber = ColumnNumber + 1
Next MonthNumber
If rvpCheckbox.Value = True Then
.Cells(iRow, 28).Value = "RVP"
End If
If uwCheckbox.Value = True Then
.Cells(iRow, 29).Value = "UW"
End If
If uaCheckbox.Value = True Then
.Cells(iRow, 30).Value = "UA"
End If
If umCheckbox.Value = True Then
.Cells(iRow, 31).Value = "UM"
End If
If baCheckbox.Value = True Then
.Cells(iRow, 32).Value = "BA"
End If
If otherCheckbox.Value = True Then
.Cells(iRow, 33).Value = "Other"
End If
End With
End Sub
Function CheckInputs() As Boolean
If Not CheckControl(Me.nameTextbox, "Please enter your name") Then Exit Function
If Not CheckControl(Me.projectTextbox, "Please enter a Project Name") Then Exit Function
If Not CheckControl(Me.audienceCombobox, "Please select an Audience") Then Exit Function
If Not CheckControl(Me.impactCombobox, "Please select Impact Type") Then Exit Function
CheckInputs = True
End Function
Function CheckControl(ctrl As MSForms.Control, errMsg As String) As Boolean
Select Case TypeName(ctrl)
Case "TextBox"
CheckControl = Trim(ctrl.Value) <> ""
Case "ComboBox"
CheckControl = ctrl.ListIndex <> -1
' Case Else
End Select
If CheckControl Then Exit Function
ctrl.SetFocus
MsgBox errMsg
End Function
Function GetWs(impact As String) As Worksheet
Select Case impact
Case "High"
Set GetWs = Worksheets("HI Project Database")
Case "Low"
Set GetWs = Worksheets("LI Project Database")
' Case Else
End Select
End Function
Sub ClearUFData()
Dim i As Integer
'clear the data
Me.nameTextbox.Value = ""
Me.projectTextbox.Value = ""
Me.nameTextbox.SetFocus
Me.audienceCombobox.Value = Null
Me.impactCombobox.Value = Null
Me.q1Checkbox.Value = False
Me.q2Checkbox.Value = False
Me.q3Checkbox.Value = False
Me.q4Checkbox.Value = False
For i = lengthListbox.ListCount - 1 To 0 Step -1
If lengthListbox.Selected(i) = True Then
lengthListbox.Selected(i) = False
End If
Next i
End Sub
Private Sub exitButton_Click()
' exits the form
Unload Me
End Sub
Private Sub q1Checkbox_Click()
lengthListbox.Selected(0) = True
lengthListbox.Selected(1) = True
lengthListbox.Selected(2) = True
If q1Checkbox.Value = False Then
lengthListbox.Selected(0) = False
lengthListbox.Selected(1) = False
lengthListbox.Selected(2) = False
End If
End Sub
Private Sub q2Checkbox_Click()
lengthListbox.Selected(3) = True
lengthListbox.Selected(4) = True
lengthListbox.Selected(5) = True
If q2Checkbox.Value = False Then
lengthListbox.Selected(3) = False
lengthListbox.Selected(4) = False
lengthListbox.Selected(5) = False
End If
End Sub
Private Sub q3Checkbox_Click()
lengthListbox.Selected(6) = True
lengthListbox.Selected(7) = True
lengthListbox.Selected(8) = True
If q3Checkbox.Value = False Then
lengthListbox.Selected(6) = False
lengthListbox.Selected(7) = False
lengthListbox.Selected(8) = False
End If
End Sub
Private Sub q4Checkbox_Click()
lengthListbox.Selected(9) = True
lengthListbox.Selected(10) = True
lengthListbox.Selected(11) = True
If q4Checkbox.Value = False Then
lengthListbox.Selected(9) = False
lengthListbox.Selected(10) = False
lengthListbox.Selected(11) = False
End If
End Sub
Private Sub q1Checkbox2_Click()
lengthListbox2.Selected(0) = True
lengthListbox2.Selected(1) = True
lengthListbox2.Selected(2) = True
If q1Checkbox2.Value = False Then
lengthListbox2.Selected(0) = False
lengthListbox2.Selected(1) = False
lengthListbox2.Selected(2) = False
End If
End Sub
Private Sub q2Checkbox2_Click()
lengthListbox2.Selected(3) = True
lengthListbox2.Selected(4) = True
lengthListbox2.Selected(5) = True
If q2Checkbox2.Value = False Then
lengthListbox2.Selected(3) = False
lengthListbox2.Selected(4) = False
lengthListbox2.Selected(5) = False
End If
End Sub
Private Sub q3Checkbox2_Click()
lengthListbox2.Selected(6) = True
lengthListbox2.Selected(7) = True
lengthListbox2.Selected(8) = True
If q3Checkbox2.Value = False Then
lengthListbox2.Selected(6) = False
lengthListbox2.Selected(7) = False
lengthListbox2.Selected(8) = False
End If
End Sub
Private Sub q4Checkbox2_Click()
lengthListbox2.Selected(9) = True
lengthListbox2.Selected(10) = True
lengthListbox2.Selected(11) = True
If q4Checkbox2.Value = False Then
lengthListbox2.Selected(9) = False
lengthListbox2.Selected(10) = False
lengthListbox2.Selected(11) = False
End If
End Sub
Private Sub UserForm_Initialize()
' sets name textbox to focus on load and loads combobox list
nameTextbox.SetFocus
audienceCombobox.AddItem "HR Activities/Initiatives"
audienceCombobox.AddItem "BI Underwriting"
audienceCombobox.AddItem "Product Management"
audienceCombobox.AddItem "CI Operations"
audienceCombobox.AddItem "UW Systems"
audienceCombobox.AddItem "Regional Initiatives"
audienceCombobox.AddItem "Other"
lengthListbox.AddItem "January"
lengthListbox.AddItem "February"
lengthListbox.AddItem "March"
lengthListbox.AddItem "April"
lengthListbox.AddItem "May"
lengthListbox.AddItem "June"
lengthListbox.AddItem "July"
lengthListbox.AddItem "August"
lengthListbox.AddItem "September"
lengthListbox.AddItem "October"
lengthListbox.AddItem "November"
lengthListbox.AddItem "December"
'New Year
lengthListbox2.AddItem "January"
lengthListbox2.AddItem "February"
lengthListbox2.AddItem "March"
lengthListbox2.AddItem "April"
lengthListbox2.AddItem "May"
lengthListbox2.AddItem "June"
lengthListbox2.AddItem "July"
lengthListbox2.AddItem "August"
lengthListbox2.AddItem "September"
lengthListbox2.AddItem "October"
lengthListbox2.AddItem "November"
lengthListbox2.AddItem "December"
impactCombobox.AddItem "High"
impactCombobox.AddItem "Low"
End Sub
Now, some specific areas I need to address are that I just added in a new lengthListbox2 that is an exact replica and does everything lengthListbox does, it just starts the data starting from ColumnNumber = 16 but I can't figure how to adjust the DIMs to address this.
I am also trying to figure out the proper way to error check the q1-q4 checkboxes and the lengthListbox(2) so that they have to have clicked either one of the q1-q4 boxes or one of the options in the lengthListbox.
Also another small addition I'm trying to add is that if they click the first 3 properties in the listbox (months) q1 is checked, and the next 3 then q2 is selected. Right now my code only does vice versa, if Q1 is selected then it selects the first 3 months.
Excuse the messiness in some areas, I've had a lot of help putting the code together for fluency in certain areas and my newbie skills did the rest.
EDIT:
Project length is now trying to pull a requirement from both current and next year when it just needs to be one or the other.
I've tried using this by setting up another control check but for lists specifically and separating two controlcheck situations but I need more so an or statement in there:
Function CheckInputs() As Boolean
If Not CheckControl(Me.nameTextbox, "Please enter your name") Then Exit Function
If Not CheckControl(Me.projectTextbox, "Please enter a Project Name") Then Exit Function
If Not CheckControl(Me.audienceCombobox, "Please select an Audience") Then Exit Function
If Not CheckControl(Me.impactCombobox, "Please select Impact Type") Then Exit Function
If Not CheckControlList(Me.lengthListbox, Me.lengthListbox2, "Please Select Project Length") Then Exit Function
CheckInputs = True
End Function
Private Function CountSelectedListBoxItems(lb As MSForms.ListBox) As Long
Dim i As Long
With lb
For i = 0 To .ListCount - 1
If .Selected(i) Then CountSelectedListBoxItems = CountSelectedListBoxItems + 1
Next i
End With
End Function
Function CheckControlList(ctrl As MSForms.Control, ctrl2 As MSForms.Control, errMsg As String) As Boolean
Select Case TypeName(ctrl)
Case "ListBox" '<--| add the case of a ListBox control passed to check
CheckControlList = CountSelectedListBoxItems(ctrl) > 0 '<--| call new function to check listboxes
' Case Else
End Select
Select Case TypeName(ctrl2)
Case "ListBox" '<--| add the case of a ListBox control passed to check
CheckControlList = CountSelectedListBoxItems(ctrl) > 0 '<--| call new function to check listboxes
' Case Else
End Select
If CheckControlList Then Exit Function
ctrl.SetFocus
MsgBox errMsg
End Function
Function CheckControl(ctrl As MSForms.Control, errMsg As String) As Boolean
Select Case TypeName(ctrl)
Case "TextBox"
CheckControl = Trim(ctrl.Value) <> ""
Case "ComboBox"
CheckControl = ctrl.ListIndex <> -1
Case "ListBox" '<--| add the case of a ListBox control passed to check
CheckControl = CountSelectedListBoxItems(ctrl) > 0 '<--| call new function to check listboxes
' Case Else
End Select
If CheckControl Then Exit Function
ctrl.SetFocus
MsgBox errMsg
End Function
I've tried using an OR statement to separate the two as well but it just ends up displaying "Please enter Project Length" prior to saying it was successfully entered:
Function CheckInputs() As Boolean
If Not CheckControl(Me.nameTextbox, "Please enter your name") Then Exit Function
If Not CheckControl(Me.projectTextbox, "Please enter a Project Name") Then Exit Function
If Not CheckControl(Me.audienceCombobox, "Please select an Audience") Then Exit Function
If Not CheckControl(Me.impactCombobox, "Please select Impact Type") Then Exit Function
If Not (CheckControl(Me.lengthListbox) Or (CheckControl(Me.lengthListbox2)) Then MsgBox "Please Enter Project Length": Exit Function
CheckInputs = True
End Function
to process two listboxes in a similar way but with some different parameters add a ProcessListBox() sub to handle a ListBox control processing, and specify as its parameters those that can change, like:
Sub ProcessListBox(lb As msforms.ListBox, ws As Worksheet, iRow As Long, ByVal iniCol As Long)
Dim MonthNumber As Byte
With ws
For MonthNumber = 0 To 11
If lb.Selected(MonthNumber) Then
.Cells(iRow, iniCol).Value = "Yes"
Else
.Cells(iRow, iniCol).Value = "No"
End If
iniCol = iniCol + 1 'Increase the column Index for each time through the loop
Next MonthNumber
End With
End Sub
so that your processing "core" of Process() sub would be:
With ws
'.Unprotect Password:="password"
.Cells(iRow, 1).Value = Me.nameTextbox.Value
.Cells(iRow, 2).Value = Me.projectTextbox.Value
.Cells(iRow, 3).Value = Me.audienceCombobox.Value
If rvpCheckbox Then .Cells(iRow, 28).Value = "RVP"
If uwCheckbox Then .Cells(iRow, 29).Value = "UW"
If uaCheckbox Then .Cells(iRow, 30).Value = "UA"
If umCheckbox Then .Cells(iRow, 31).Value = "UM"
If baCheckbox Then .Cells(iRow, 32).Value = "BA"
If otherCheckbox Then .Cells(iRow, 33).Value = "Other"
End With
ProcessListBox lengthListbox, ws, iRow, 4 '<--| process lengthListbox passing "4" as starting column
ProcessListBox lengthListbox2, ws, iRow, 16 '<--| process lengthListbox2 passing "16" as starting column
as for the listboxes and corresponding checkboxes cross checking, since you actually only care about the former, just check listboxes for any selected value
and you could that by means of a specific Function like:
Private Function CountSelectedListBoxItems(lb As msforms.ListBox) As Long
Dim i As Long
With lb
For i = 0 To .ListCount - 1
If .Selected(i) Then CountSelectedListBoxItems = CountSelectedListBoxItems + 1
Next i
End With
End Function
to add to your CheckControl() function Case block:
Function CheckControl(ctrl As msforms.Control, errMsg As String) As Boolean
Select Case TypeName(ctrl)
Case "TextBox"
CheckControl = Trim(ctrl.Value) <> ""
Case "ComboBox"
CheckControl = ctrl.ListIndex <> -1
Case "ListBox" '<--| add the case of a ListBox control passed to check
CheckControl = CountSelectedListBoxItems(ctrl) > 0 '<--| call new function to check listboxes
' Case Else
End Select
If CheckControl Then Exit Function
ctrl.SetFocus
MsgBox errMsg
End Function
and therefore update your CheckInputs() function
Function CheckInputs() As Boolean
If Not CheckControl(Me.nameTextbox, "Please enter your name") Then Exit Function
If Not CheckControl(Me.projectTextbox, "Please enter a Project Name") Then Exit Function
If Not CheckControl(Me.audienceCombobox, "Please select an Audience") Then Exit Function
If Not CheckControl(Me.impactCombobox, "Please select Impact Type") Then Exit Function
If Not CheckControl(Me.lengthListbox, "Please select a current year month") Then Exit Function '<--| check "lengthListbox"
If Not CheckControl(Me.lengthListbox2, "Please select a next year month") Then Exit Function '<--| check "lengthListbox2"
CheckInputs = True
End Function
I also think you need to update your ClearUFData() sub to handle both lengthListbox and lengthListbox2. and qXCheckbox2, too...
Sub ClearUFData()
'clear the data
With Me
.nameTextbox.Value = ""
.projectTextbox.Value = ""
.nameTextbox.SetFocus
.audienceCombobox.Value = Null
.impactCombobox.Value = Null
.q1Checkbox.Value = False
.q2Checkbox.Value = False
.q3Checkbox.Value = False
.q4Checkbox.Value = False
.q1Checkbox2.Value = False '<-- uncheck q1Checkbox2
.q2Checkbox2.Value = False '<-- uncheck q2Checkbox2
.q3Checkbox2.Value = False '<-- uncheck q3Checkbox2
.q4Checkbox2.Value = False '<-- uncheck q4Checkbox2
DeselectListBox lengthListbox '<-- deselect all listbox items
DeselectListBox lengthListbox2 '<-- deselect all lkistbox items
End With
End Sub
where I'd use a DeselectListBox() sub like follows:
Private Sub DeselectListBox(lb As msforms.ListBox)
Dim i As Long
With lb
For i = 0 To .ListCount - 1
.Selected(i) = False
Next i
End With
End Sub
Finally some little improvements
checkbox control default property is Value that returns True or False whether it is checked or not
so instead of
If q1Checkbox.Value = False Then
you can simply use
If Not q1Checkbox Then
and the likes
this can have you simplify and shorten the following code:
Private Sub q1Checkbox_Click()
lengthListbox.Selected(0) = True
lengthListbox.Selected(1) = True
lengthListbox.Selected(2) = True
If Not q1Checkbox Then
lengthListbox.Selected(0) = False
lengthListbox.Selected(1) = False
lengthListbox.Selected(2) = False
End If
End Sub
Private Sub q2Checkbox_Click()
lengthListbox.Selected(3) = True
lengthListbox.Selected(4) = True
lengthListbox.Selected(5) = True
If Not q2Checkbox Then
lengthListbox.Selected(3) = False
lengthListbox.Selected(4) = False
lengthListbox.Selected(5) = False
End If
End Sub
Private Sub q3Checkbox_Click()
lengthListbox.Selected(6) = True
lengthListbox.Selected(7) = True
lengthListbox.Selected(8) = True
If Not q3Checkbox Then
lengthListbox.Selected(6) = False
lengthListbox.Selected(7) = False
lengthListbox.Selected(8) = False
End If
End Sub
Private Sub q4Checkbox_Click()
lengthListbox.Selected(9) = True
lengthListbox.Selected(10) = True
lengthListbox.Selected(11) = True
If Not q4Checkbox Then
lengthListbox.Selected(9) = False
lengthListbox.Selected(10) = False
lengthListbox.Selected(11) = False
End If
End Sub
Private Sub q1Checkbox2_Click()
lengthListbox2.Selected(0) = True
lengthListbox2.Selected(1) = True
lengthListbox2.Selected(2) = True
If Not q1Checkbox2 Then
lengthListbox2.Selected(0) = False
lengthListbox2.Selected(1) = False
lengthListbox2.Selected(2) = False
End If
End Sub
Private Sub q2Checkbox2_Click()
lengthListbox2.Selected(3) = True
lengthListbox2.Selected(4) = True
lengthListbox2.Selected(5) = True
If q2Checkbox2.Value = False Then
lengthListbox2.Selected(3) = False
lengthListbox2.Selected(4) = False
lengthListbox2.Selected(5) = False
End If
End Sub
Private Sub q3Checkbox2_Click()
lengthListbox2.Selected(6) = True
lengthListbox2.Selected(7) = True
lengthListbox2.Selected(8) = True
If Not q3Checkbox2 Then
lengthListbox2.Selected(6) = False
lengthListbox2.Selected(7) = False
lengthListbox2.Selected(8) = False
End If
End Sub
Private Sub q4Checkbox2_Click()
lengthListbox2.Selected(9) = True
lengthListbox2.Selected(10) = True
lengthListbox2.Selected(11) = True
If Not q4Checkbox2 Then
lengthListbox2.Selected(9) = False
lengthListbox2.Selected(10) = False
lengthListbox2.Selected(11) = False
End If
End Sub
UserForm_Initialize can be also made more "codeable" and readable with the use of With statement as follows:
Private Sub UserForm_Initialize()
' sets name textbox to focus on load and loads combobox list
nameTextbox.SetFocus
With audienceCombobox
.AddItem "HR Activities/Initiatives"
.AddItem "BI Underwriting"
.AddItem "Product Management"
.AddItem "CI Operations"
.AddItem "UW Systems"
.AddItem "Regional Initiatives"
.AddItem "Other"
End With
With lengthListbox
.AddItem "January"
.AddItem "February"
.AddItem "March"
.AddItem "April"
.AddItem "May"
.AddItem "June"
.AddItem "July"
.AddItem "August"
.AddItem "September"
.AddItem "October"
.AddItem "November"
.AddItem "December"
End With
'New Year
With lengthListbox2
.AddItem "January"
.AddItem "February"
.AddItem "March"
.AddItem "April"
.AddItem "May"
.AddItem "June"
.AddItem "July"
.AddItem "August"
.AddItem "September"
.AddItem "October"
.AddItem "November"
.AddItem "December"
End With
With impactCombobox
.AddItem "High"
.AddItem "Low"
End With
End Sub
Hi i am trying to program a user form in excel that a user inputs the information and can select the worksheet that they want the information that was entered in to go to that spread sheet.
This is what i have so far.
Dim iRow As Long
Dim sheet As String
sheet = ComboBox1.Value
Worksheets(sheet).Activate
iRow = sheet.Cells.Find(what:="*", seatchOrder:=xlRows, searchdirection:=xlPrevious, LookIn:=xlValues).Row + 1
when i run the user form and select the worksheet in the combo box and hit the command button to run the form i get the error "invalid qualifier"
it highlights sheet.cells
here is the entire code if it helps:
Private Sub ComboBox1_Change()
End Sub
Private Sub CommandButton1_Click()
'get item button
Dim sheet As String
UserForm8.Hide
MsgBox ("Select an item to update")
sheet = ComboBox1.Value
Worksheets(sheet).Activate
Set ProjRng = Application.InputBox(Message, Title, "", 377, 58, , , 8)
ProjSel = ProjRng.Cells.Row
Label1.Enabled = True
Label2.Enabled = True
Label3.Enabled = True
Label4.Enabled = True
Label8.Enabled = True
Label10.Enabled = True
TextBox1.Enabled = True
TextBox2.Enabled = True
TextBox3.Enabled = True
TextBox4.Enabled = True
TextBox8.Enabled = True
TextBox10.Enabled = True
TextBox10.Locked = False
CommandButton1.Enabled = True
ComboBox1.Enabled = True
UserForm8.TextBox1.Value = ActiveSheet.Cells(ProjSel, 1).Value
UserForm8.TextBox2.Value = ActiveSheet.Cells(ProjSel, 2).Value
UserForm8.TextBox3.Value = ActiveSheet.Cells(ProjSel, 3).Value
UserForm8.TextBox4.Value = ActiveSheet.Cells(ProjSel, 4).Value
UserForm8.TextBox8.Value = ActiveSheet.Cells(ProjSel, 8).Value
UserForm8.TextBox11.Value = ActiveSheet.Cells(ProjSel, 6).Value
UserForm8.Show
End Sub
Private Sub CommandButton2_Click()
'Update button to update the remaing quantity amount
Dim iRow As Long
Dim sheet As String
sheet = ComboBox1.Value
Worksheets(sheet).Activate
iRow = sheet.Cells.Find(what:="*", seatchOrder:=xlRows, searchdirection:=xlPrevious, LookIn:=xlValues).Row + 1
With Worksheets("ChemLog")
.Cells(iRow, 6).Value = Me.TextBox12
End With
With sheet
.Cells(iRow, 1).Value = Me.TextBox1.Value
end with
'continue above with columns according to log
End Sub
Private Sub TextBox10_Change()
End Sub
Private Sub TextBox11_Change()
End Sub
Private Sub UserForm_Click()
End Sub
Private Sub UserForm_Initialize()
ComboBox1.AddItem ("Standards")
ComboBox1.AddItem ("Acids,Bases, and Buffers")
ComboBox1.AddItem ("Solvents and Flammables")
End Sub
As well as the spelling error, sheet is a string, so it requires:
Worksheets(sheet).Cells.Find(..
which is the reason for the specific error message you receive.