Requiring Listbox Selection for userform - excel

Private Sub CommandButton1_Click()
whichSheet = ListBox1.Value
Dim n As Integer
Do
n = n + 1
ListBox1.AddItem Sheets(n).Name
Loop Until n = Worksheets.Count
Worksheets(whichSheet).Activate
Dim lastrow
lastrow = ActiveSheet.Cells(Rows.Count, 1).End(xlUp).Row
lastrow = lastrow + 1
Cells(lastrow, 1) = TextBox1
answer = MsgBox("Are you sure you want to add the record?", vbYesNo + vbQuestion, "Add Record")
If answer = vbYes Then
Cells(lastrow, 1) = TextBox1.Text
Cells(lastrow, 2) = TextBox2.Text
Cells(lastrow, 3) = TextBox3.Value
Cells(lastrow, 4) = TextBox4.Text
Cells(lastrow, 5) = TextBox5.Text
Cells(lastrow, 6) = TextBox6.Text
Else
Cells(lastrow, 1) = ""
Exit Sub
End If
End Sub
Private Sub UserForm_Initialize()
Dim ws As Worksheet
For Each ws In ThisWorkbook.Worksheets
ListBox1.AddItem (ws.Name)
Next ws
End Sub
Hello guys, I am using the code above which works perfectly for my userform. The only issue I'm having is that when someone doesn't pick a choice from the listbox1 and submits the info, the "Runtime Error" window pops up. I would like to stop that from happening by making a message box appear that tells users to make a choice--->click ok on the message box---> and then resume. If the user doesn't select an option still the same procedure should occur every time. If you have any ideas, I would love to try them out. Thanks.

My preferred way of handling this situation is to disable CommandButton1 if nothing in the ListBox1 is selected. Or, in other words, enable the button when something is selected.
Private Sub UserForm_Initialize()
Dim ws As Worksheet
CommandButton1.Enabled = False ' <--- here.
For Each ws In ThisWorkbook.Worksheets
ListBox1.AddItem (ws.Name)
Next ws
End Sub
I don't have Excel open at the moment, but you want a corresponding listbox event to enable/disable the button. The following is an example and untested.
Private Sub ListBox1_Change()
CommandButton1.Enabled = ListBox1.ListIndex <> -1
End Sub
Another approach is to check to see if something has been selected when you enter the CommandButton1_Click routine and handle it there. But I prefer to prevent bad user input in the first place - less complicated.

Related

what if i double click on the listbox, then it displays the value in the userform

so the listbox is in the userform3. after I do a data search, it will appear in the listbox. when I double click on the listbox, it will show the value of the textbox in userform2. i used this code but it didn't work
Dim r, lr as integer
lr= sheet7. Cells(rows.count, 2).end(xlup).row
For r=2 to lr
If sheet7.cells(r, 1).value=listbox1.list(listbox1.listindex, 1) and sheet7.cells(r, 2).value=listbox1.list(listbox1.listindex, 2) then
Unload me
Userform2.Textbox2.value = sheet7.cells(r,1)
End if
End with
Next r
Why that code isn't working? Fyi there are 2 kriteria
too little context for the code you showed
maybe this will help you get on the route
Private Sub ListBox1_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
'define the criteria parameters
With Me ' reference the parent Userform object
With .ListBox1
Dim refVal1 As String, _
refVal2 As String
refVal1 = .List(.ListIndex, 1)
refVal2 = .List(.ListIndex, 2)
End With
End With
Dim r As Long, lr As Long
With Sheet7 ' reference "sheet7" sheet
lr = .Cells(.Rows.Count, 2).End(xlUp).Row
For r = 2 To lr
If .Cells(r, 1).Value = refVal1 And .Cells(r, 2).Value = refVal2 Then
UserForm2.TextBox2.Value = .Cells(r, 1) ' hoping UserForm2 has no "Initialize" event active...
Exit For
End If
Next
unload me 'are you sure you want to unload the parent userform?
End With
End Sub

Edit filtered listbox

Can anyone help me with a solution or a different method for this? I would like to edit the filtered listbox
I'm trying to get a listbox that is able to display my sheet1 and be able to filter all the blanks/not found in column A. I also want to be able to edit the listbox aswell
I would like my userform2 listbox to display the sheet1 information.
There will also be a checkbox which will filter the listbox to show “not found” or blank lines.
If i double click the selected item on the listbox i would like to edit the information
for userform2
Private Sub ListBox2_Click()
TextBox1.Enabled = True
TextBox1.Value = ListBox2.Value
End Sub
Private Sub TextBox1_Change()
Dim rCell As Range
With ListBox2
Set rCell = Range(.RowSource).Resize(1).Offset(.ListIndex)
rCell.Value = TextBox1.Value
End With
End Sub
Private Sub CheckBox1_Click()
OptimizedMode True
If userform2.CheckBox1.Value = True Then
Worksheets("Table").Range("A1").AutoFilter Field:=1, Criteria1:="Not Found", Operator:=xlOr, Criteria2:="="
userform2.ListBox2.RowSource = vbNullString
userform2.ListBox2.ColumnHeads = False
Dim rng As Range
Dim Cel1 As Range
Dim LR As Long
Dim ws As Worksheet
Set ws = Sheets("Table")
With ws
LR = .Cells(.Rows.Count, "A").End(xlUp).Row
Set rng = .Range("A2:A" & LR).SpecialCells(xlCellTypeVisible)
With userform2.ListBox2
.ColumnCount = 1
For Each Cel1 In rng
.AddItem CStr(Cel1.Value)
.List(.ListCount - 1, 1) = Cel1.Offset(0, 1).Value
Next Cel1
End With
End With
End If
If CheckBox1.Value = False Then
With userform2.ListBox2
.RowSource = "Table!A2:A1048576"
End With
End If
OptimizedMode False
End Sub
I've re-designed my code and I believe this will achieve what you are after.
NOTE: This code uses all default object names. You will need to modify it to target the names for your workbook, sheet, useform, controls etc, if you wish to implement into your project.
In designing this answer I used the following:
A new blank Workbook with 1 new Worksheet
A new UserForm (captioned "ListBox Editor") with 1 ListBox that has 2 columns (ColumnCount = 2) and 1 CheckBox (captioned "Show Blanks").
The sample data I used was in Range("A1:A10") filling only odd numbers from row 1. This allows testing for including/excluding blank/empty rows. Screenshots of the Worksheet and UserForm below.
Worksheet data:
UserForms both with and without blanks in the listbox:
All code is written in the code behind module for the UserForm
Most can be written into any other module with calls made to the subs/functions from the UserForm/ListBox events if you'd prefer not to have the working code in the UserForm module.
Code blocks with explanations below (full code block at the end for copy/paste):
Option Explicit
Option Explicit should be included at the top of each and every code module you use. It forces explicit declaration of all variables which helps significantly in avoiding typo's in your code etc.
Private Sub PopulateListBox(ByVal IncludeBlanks As Boolean)
Dim TargetCell As Range
Dim TargetWorksheet As Worksheet
Set TargetWorksheet = ThisWorkbook.Sheets("Sheet1")
With UserForm1.ListBox1
.Clear
For Each TargetCell In TargetWorksheet.Range("A1:A10")
If Not IncludeBlanks Then
If Not TargetCell.Value = "" Then
.AddItem TargetCell.Value
.List(.ListCount - 1, 1) = TargetCell.Row
End If
ElseIf IncludeBlanks Then
.AddItem TargetCell.Value
.List(.ListCount - 1, 1) = TargetCell.Row
End If
Next TargetCell
.ColumnWidths = ";0" 'Hides listbox column that holds row number
End With
End Sub
PopulateListBox is a subroutine I wrote to handle population of the items in the ListBox. It first clears the list, allowing each population of the listbox to be 'refreshed' data. Then it iterates through each TargetCell of the defined Range. If IncludeBlanks is True it has no conditions to meet and adds each cell value into the list, if IncludeBlanks is False it will only add the cell value to the list if the value is not "".
Private Sub CheckBox1_Click()
If Me.CheckBox1.Value = False Then
PopulateListBox False
ElseIf Me.CheckBox1.Value = True Then
PopulateListBox True
End If
End Sub
This _Click event simply updates the ListBox list based on if the CheckBox is checked or not. The CheckBox represents if you are including blanks/empty cells or not so it passes True or False respective to it's Value, to the IncludeBlanks argument in PopulateListBox.
Private Sub ListBox1_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
Dim NewValue As Variant
Dim TargetWorksheet As Worksheet
Set TargetWorksheet = ThisWorkbook.Sheets("Sheet1")
NewValue = InputBox("What is the new value to replace " & UserForm1.ListBox1 & "?")
If Not StrPtr(NewValue) = 0 Then 'Check user did NOT click cancel or [X]
With ListBox1
If NewValue = "" Then NewValue = vbNullString
TargetWorksheet.Cells(.List(.ListIndex, 1), 1).Value = NewValue
.AddItem NewValue, .ListIndex
.RemoveItem .ListIndex
End With
End If
End Sub
The _DblClick Event triggers the code when a list item is double clicked. This code first opens an InputBox to allow the user to enter a new value for the selected listbox item. When the user clicks OK or hit's Enter, the new value is first written to the Cell that the original value came from, then the new value is added as a new list item and finally the previous value is removed. If the user clicks [X] or 'Cancel' the code does nothing.
Private Sub UserForm_Initialize()
PopulateListBox False
End Sub
Much the same as the Checkbox_Change code, this simply populates the ListBox when the UserForm is first initialized. It's written to exclude blanks, specified by False for the IncludeBlanks argument.
Put it all together and you have:
Option Explicit
Private Sub CheckBox1_Click()
If Me.CheckBox1.Value = False Then
PopulateListBox False
ElseIf Me.CheckBox1.Value = True Then
PopulateListBox True
End If
End Sub
Private Sub ListBox1_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
Dim NewValue As Variant
Dim TargetWorksheet As Worksheet
Set TargetWorksheet = ThisWorkbook.Sheets("Sheet1")
NewValue = InputBox("What is the new value to replace " & UserForm1.ListBox1 & "?")
If Not StrPtr(NewValue) = 0 Then 'Check user did NOT click cancel or [X]
With ListBox1
If NewValue = "" Then NewValue = vbNullString
TargetWorksheet.Cells(.List(.ListIndex, 1), 1).Value = NewValue
.AddItem NewValue, .ListIndex
.RemoveItem .ListIndex
End With
End If
End Sub
Private Sub UserForm_Initialize()
PopulateListBox False
End Sub
Private Sub PopulateListBox(ByVal IncludeBlanks As Boolean)
Dim TargetCell As Range
Dim TargetWorksheet As Worksheet
Set TargetWorksheet = ThisWorkbook.Sheets("Sheet1")
With UserForm1.ListBox1
.Clear
For Each TargetCell In Range("A1:A10")
If Not IncludeBlanks Then
If Not TargetCell.Value = "" Then
.AddItem TargetCell.Value
.List(.ListCount - 1, 1) = TargetCell.Row
End If
ElseIf IncludeBlanks Then
.AddItem TargetCell.Value
.List(.ListCount - 1, 1) = TargetCell.Row
End If
Next TargetCell
.ColumnWidths = ";0"
End With
End Sub

Activation of sheets based on selection of checkbox in userform

I have checkboxes in my User form and based on selection Of ID from Checkboxes, I want to activate the sheets for particular user in my workbook. I came across some portions of the following code but it's not working properly.
Option Explicit
Private Sub Add_Click()
Dim ctrl As Control
For Each ctrl In UserForm1.Controls
If TypeName(ctrl) = "CheckBox" Then
TransferValues ctrl
End If
Next
End Sub
Sub TransferValues(cb As MSForms.CheckBox)
Dim ws As Worksheet
Dim emptyRow As Long
If cb.Value = True Then
'Define the worksheet based on the CheckBox.Name property:
Set ws = Sheets(Left(cb.Name, 1))
emptyRow = WorksheetFunction.CountA(ws.Range("F:F")) + 1
With ws
If Trim(Me.ComboBox3.Value) = "" Or Trim(Me.ComboBox6.Value) = "" Then
MsgBox ("Please enter text in all fields")
Exit Sub
End If
If WorksheetFunction.CountIf(ws.Range("F:F"), ComboBox3.Value) = 0 Or WorksheetFunction.CountIf(ws.Range("G:G"), ComboBox6.Value) = 0 Then
Cells(emptyRow, 6).Value = ComboBox3.Value
Cells(emptyRow, 7).Value = ComboBox6.Value
Cells(emptyRow, 8).Value = TextBox1.Value
Else
MsgBox ("Warning:Duplicate Entries found. Please update the existing entries")
End If
End With
End If
End Sub
Found solution by own. Please use the following code for such kind of issues if anyone face.
Private Sub CommandButton1_Click()
Dim ctrl As Control
For Each ctrl In Userform1.Controls
If TypeName(ctrl) = "CheckBox" Then
TransferValues ctrl
End If
Next
End Sub
Sub TransferValues(cb As MSForms.CheckBox)
Dim ws As Worksheet
Dim emptyRow As Long
'Dim ID As String
If cb.Value = True Then
Set ws = Sheets(Left(cb.Caption, 6))
If Trim(Me.ComboBox3.Value) = "" Or Trim(Me.ComboBox6.Value) = "" Then
MsgBox ("Please Enter the text in All Fields")
End If
emptyRow = WorksheetFunction.CountA(ws.Range("F:F")) + 1
With ws
If WorksheetFunction.CountIf(ws.Range("F:F"), ComboBox3.Value) = 0 Or WorksheetFunction.CountIf(ws.Range("G:G"), ComboBox6.Value) = 0 Then
.Cells(emptyRow, 6).Value = ComboBox3.Value
.Cells(emptyRow, 7).Value = ComboBox6.Value
.Cells(emptyRow, 8).Value = TextBox1.Value
Else
MsgBox ("Warning:Duplicate Entries Found. Please edit existing entries")
End If
End With
End If
End Sub

Have macro for loop, need to throttle and only move to next i when a new button is pressed

Pretty much I have a loop that I want to run through, however I don't want it to go to the next "i" until a button is pressed. My code is as follows. I believe my trouble is the location of the "If GoGo" but I have tried it in many places.
Sub GoGo()
Public GoGo As Boolean
GoGo = True
End Sub
Sub Runn()
Dim lastrow As Long, i As Long
For i = 23 To 32
DoEvents
If GoGo = True Then
If Cells(i, 1) <> 0 Then
Range("B5").Value = Cells(i, 2).Value
Range("E5").Value = Cells(i, 3).Value
Range("E11").Value = Range("C33").Value
Application.Run ("Realcount")
Application.Run ("Realcount2")
End If
End If
Next i
End Sub
Is this what you are trying?
Public GoGo As Boolean
Sub GoGoProc()
GoGo = True
End Sub
Sub Runn()
Dim lastrow As Long, i As Long
i = 23
Do
DoEvents
If GoGo = True Then
If Cells(i, 1) <> 0 Then
Range("B5").Value = Cells(i, 2).Value
Range("E5").Value = Cells(i, 3).Value
Range("E11").Value = Range("C33").Value
Application.Run ("Realcount")
Application.Run ("Realcount2")
End If
i = i + 1
GoGo = False
End If
Loop
End Sub
FOLLOWUP (From Comments)
Instead of using a loop, the best way I can think of is using a modeless userform (so that you want work with the Workbook/Worksheet at the same time) with a Next button. The Next button will increment the row value and then run the code. This way you will not keep Excel busy if you had to leave say for a cup of coffee ;)
Create Userform (UNTESTED) which should look like this
Paste this code in the userform
'~~> Next Button
Private Sub CommandButton1_Click()
Range("B5").Value = Cells(rw, 2).Value
Range("E5").Value = Cells(rw, 3).Value
Range("E11").Value = Range("C33").Value
Application.Run ("Realcount")
Application.Run ("Realcount2")
rw = rw + 1
End Sub
'~~> Canecel Button
Private Sub CommandButton2_Click()
Unload Me
End Sub
Create a Module and paste this code there
Public rw As Long
Sub Launch()
rw = 23
UserForm1.Show vbModeless
End Sub
To run your code, you can either run Sub Launch() directly or create a Command Button (Form Control - I guess that is what you are using) on your worksheet and assign Sub Launch() to it.

VBA Excel - Function Stuck

I am new ti VBA and i would like to perform a function as follows i hope someone could help me out
I need to set a macro that starts at Cell A2 when i click my function a dialog box appears which i can enter relevant information into and it inserts into the relevant cells
inserts data into 3 fields (B2, C2, D2)
then selects B3 where i can press my button again to do the same thins again
heres my code so far
Dim StartCell As Integer
Private Sub Cancel_Click()
Unload GarageDimensions
End Sub
Private Sub LengthBox_Change()
If LengthBox.Value >= 15 Then
MsgBox "Are you sure? You do realise it is just a garage!"
Exit Sub
End If
End Sub
Private Sub Submit_Click()
'This code tells the text entered into the job reference textbox to be inserted _
into the first cell in the job reference column.
StartCell = Cells(1, 2)
Sheets("Data").Activate
If IsBlankStartCell Then
ActiveCell(1, 1) = JobRef.Text
ActiveCell.Offset(0, 1).Select
ActiveCell(1, 1) = LengthBox.Value
ActiveCell.Offset(0, 1).Select
ActiveCell(1, 1) = ListBox1.Value
ActiveCell.Offset(0, 1).Select
ActiveCell(1, 1) = ListBox1.Value * LengthBox.Value
Else
Range("A1").End(xlDown).Offset(1, 0).Select
End If
Unload GarageDimensions
End Sub
Private Sub UserForm_Initialize()
With ListBox1
.AddItem "2.2"
.AddItem "2.8"
.AddItem "3.4"
End With
ListBox1.ListIndex = 0
End Sub
Thanks for your answers in advance
Adam
You don't need the Private Sub LengthBox_Change() event. You can set the MAX characters of the TextBox LengthBox either in the Design Mode or in the UserForm_Initialize() event as I have done below.
Also if you hard-code the Startcell then every time you run the UserForm the data will start from A2 and if there is any data there, then that will be overwritten. Instead try and find the last available row where you can write.
BTW, is this what you are trying (UNTESTED)?
Option Explicit
Dim StartCell As Integer
Dim ws As Worksheet
Private Sub UserForm_Initialize()
Set ws = Sheets("Data")
With ListBox1
.AddItem "2.2"
.AddItem "2.8"
.AddItem "3.4"
.ListIndex = 0
End With
LengthBox.MaxLength = 14
End Sub
Private Sub Submit_Click()
With ws
'~~> Find the first empty row to write
StartCell = .Range("A" & Rows.Count).End(xlUp).Row + 1
.Range("A" & StartCell).Value = Val(Trim(ListBox1.Value)) _
* Val(Trim(LengthBox.Value))
.Range("B" & StartCell).Value = JobRef.Text
.Range("C" & StartCell).Value = LengthBox.Value
.Range("D" & StartCell).Value = ListBox1.Value
End With
Unload Me
End Sub
Private Sub Cancel_Click()
Set ws = Nothing
Unload Me
End Sub

Resources