Excel VBA ComboBox1_DropButtonClick Event - vba

I got macro below which fires twice (showing same MessageBox twice). First when ComboBox1 opens and second when ComboBox1 closes.
Private Sub ComboBox1_DropButtonClick()
If Me.ComboBox2.Text = "" Then
MsgBox "Fill text box"
Else
'Do stuff
End If
End Sub
Is there any way to make it show MessageBox once. I want user to select the value in ComboBox1 first before clicking on ComboBox2 DropButton.

Here is a very unelegant work-around using a "count" variable that prompts the MsgBox only the first and not the second time.
Dim count As Integer
Private Sub ComboBox1_DropButtonClick()
count = count + 1
If Me.ComboBox2.Text = "" Then
If count = 1 Then
MsgBox "Fill text box"
Else
count = 0
End If
Else
'Do stuff
End If
End Sub
However, I highly suggest to use the ComboBox1_Change() event if it's not necessary to use the drop button one.
P.S.: the declaration of the "count" variable needs to stay out of the method. This is due to the fact that:
if it stays inside, it's a local variable of the method and so loses its modifications every time the method is ended;
if it stays outside, it will keep the modifications even once the method has ended its run.

I would do it using the combobox_enter event, but this only checks when the focus is switched
Private Sub ComboBox1_Change()
If ComboBox1.Text = "" Then
ComboBox2.ShowDropButtonWhen = fmShowDropButtonWhenNever
Else
ComboBox2.ShowDropButtonWhen = fmShowDropButtonWhenAlways
End If
End Sub
Private Sub ComboBox2_Enter()
If ComboBox1.Text = "" Then
MsgBox "Must first set value to combobox1"
ComboBox1.SetFocus
End If
End Sub
Private Sub UserForm_Initialize()
ComboBox1.AddItem "None", 0
ComboBox1.AddItem "Select Me", 1
ComboBox2.AddItem "None", 0
ComboBox2.AddItem "Select Me", 1
ComboBox2.ShowDropButtonWhen = fmShowDropButtonWhenNever
End Sub
My code does some extra things that I just think look pretty, you really only need the _Enter function

Related

Runtime Error 1004 - BeforePrint - Avoid printing if cells are empty

I am trying to create a macro to prevent users from printing a form if they don't fill out all cells. However, I am getting an error message:
Private Sub Workbook_BeforePrint(Cancel As Boolean)
If Application.Sheets("Form").Range("B4,C4,D4,E4,F4,G4,H4,I4,J4,K4,L4,M4,B5,C5,D5,E5,F5,G5,H5,I5,J5,K5,L5,M5,B6,C6,D6,E6,F6,G6,H6,I6,J6,K6,L6,M6,B7,C7,D7,E7,F7,G7,H7,I7,J7,K7,L7,M7,B8,C8,D8,E8,F8,G8,H8,I8,B9,C9,D9,E9,F9,G9,H9,I9,B11,C11,D11,E11,F11,G11,H11,I11,B12,C12,D12,E12,F12,G12,H12,I12,B13,C13,D13,E13,F13,G13,H13,I13,B14,C14,D14,E14,F14,G14,H14,I14,B16,C16,D16,E16,F16,G16,H16,I16,B17,C17,D17,E17,F17,G17,H17,I17").Value = "" Then
Cancel = True
MsgBox "Fill out all the cells"
End If
End Sub
I have another macro for another form that has fewer cells and that one works just fine:
Private Sub Workbook_BeforePrint(Cancel As Boolean)
If Application.Sheets("Form 2").Range("C4,C5,C6,D4,D5,D6,F4,F5,F6,B8,B9,B10,B11,C8,C9,C10,C11,D8,D9,D10,D11,E8,E9,E10,E11,C13,D13,C16,C17,C18,F16,F17,F18,C22,D22").Value = "" Then
Cancel = True
MsgBox "Fill out all the cells"
End If
End Sub
What can I do to solve this problem?
It seems that there is a limit to line length or to how long of a string you can put into a range(). But you can consolidate it like this. Also I think that the return value from a range() with more than one cell is an array so I am not sure if it is valid to compare it to a string like you did.
Try this:
Private Sub Workbook_BeforePrint(Cancel As Boolean)
For Each cell In Application.Sheets("Form").Range("B4:M7,B8:I9,B11:I14,B16:I17")
If cell.Value = "" Then
Cancel = True
MsgBox "Fill out all the cells"
Exit Sub
End If
Next
End Sub

VBA if in text is in textbox then do something

I've written the following code so that if a certain text exists in my listbox and "ok" button is clicked a certain thing is done.
Private Sub CommandButton3_Click()
If (Me.ListBox2.Text) <> ("PA") Then
Call macro1
ElseIf (Me.ListBox2.Text) <> "menu" Then
Sheets("menu").Visible = xlSheetVisible
Worksheets("menu").Activate
Else
MsgBox "Nothing is selected"
End If
End Sub
The problem is that when "ok" is clicked all events are still carried out even if the specified text isn't in the textbox.
You probably want to use = operator, and not <> operator. Also note that ListBox.List(i) is the correct way of getting selected item for single selection mode:
Private Sub CommandButton3_Click()
Dim SelectedItem = ListBox1.List(ListBox1.ListIndex)
If SelectedItem = "PA" Then
Call macro1
ElseIf SelectedItem = "menu" Then
Sheets("menu").Visible = xlSheetVisible
Worksheets("menu").Activate
Else
MsgBox "Nothing is selected"
End If
End Sub
Edit
Following your comment, you can create a function that looks for the existence of that item:
Private Function TextExists(text as String) as Boolean
Dim i as Long
For i = 0 To ListBox1.ListCount - 1
If ListBox1.List(i) = text Then
TextExists = True
Exit Function
End If
Next
TextExists = False
End Function
And then use this function in the main code like this:
Private Sub CommandButton3_Click()
If TextExists("PA") Then
Call macro1
ElseIf TextExists("menu") Then
Sheets("menu").Visible = xlSheetVisible
Worksheets("menu").Activate
Else
MsgBox "Nothing is selected"
End If
End Sub
N.B. I have written this manually here, without an IDE. Please check for indexes and other little things.

VBA UserForm TextBox Only Allow Numbers and Empty Text

In my userform I want to MsgBox if TextBox not contain Numbers or empty.
This is my code but in another case when the TextBox = "" Empty the MsgBox appear to me, so the issue with me is the empty TextBox.
Private Sub TB1_Change()
If TypeName(Me.TB1) = "TextBox" Then
With Me.ActiveControl
L12.Caption = Val(TB1.Text) * Val(TB2.Text)
If Not IsNumeric(.Value) And .Value <> vbNullString Then
MsgBox "Sorry, only numbers allowed"
.Value = vbNullString
End If
End With
End If
End Sub
Use the Key Press event for this purpose.
Private Sub TB1_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)
If Not IsNumeric(Chr(KeyAscii)) Then KeyAscii = 0
End Sub
This procedure will just ignore anything you enter if it isn't a number, but you can modify both the condition and the output. For example, you might allow a decimal point to be entered, or you might wish to show a message box - perhaps only on the second try.
You may use the AfterUpdate event handler instead of the Change event, might also want to use the Exit event and cancel the exit if the user enters an invalid value:
Option Explicit
Private Sub TB1_AfterUpdate()
'Check whether the value is numeric or empty:
If Not IsValNumeric(Me.TB1.Value) Then
MsgBox "Sorry, only numbers allowed"
Me.TB1.Value = vbNullString
Else:
'Do something...
MsgBox val(TB1.Text) * val(TB2.Text)
End If
End Sub
Private Sub TB1_Exit(ByVal Cancel As MSForms.ReturnBoolean)
'Prevents the user from EXIT the TextBox if value is not numeric/empty
Cancel = Not IsNumeric(Me.TB1.Value)
End Sub
Private Function IsValNumeric(val$) As Boolean
Dim ret As Boolean
'check for numeric value only and allow empty value as a zero value
ret = IsNumeric(val) Or Len(val) = 0
IsValNumeric = ret
End Function
You can wait until the user finishes their input and then test the field.
For usability, the message box should be replaced with a caption and an icon/picture like this "A number must be entered here."
These would be displayed next to the text box when the input is incorrect. Then hidden when the input is corrected. The submission of the form can be blocked until all the errors have been corrected.
This allows the user to enter the request data and then fix any input errors. This is better than stopping them every time they make a mistake.
The event is changed from Change to Exit.
Private Sub TB1_Exit(ByVal Cancel As MSForms.ReturnBoolean)
If TypeName(Me.TB1) = "TextBox" Then
With Me.ActiveControl
L12.Caption = Val(TB1.Text) * Val(TB2.Text)
If Not IsNumeric(.Value) Or .Value = vbNullString Then
MsgBox "Sorry, only numbers allowed"
.Value = vbNullString
End If
End With
End If
End Sub
The vbNullString test has also been updated.
Since you are trying to allow only "Numeric" and "Blank" then the code below would deliver your needs.
Private Sub TB1_Change()
if IsNumeric(Me.TB1.Value) = True or Me.TB1.Value = vbNullString then
'Good data, nothing to MSG
Else
MsgBox "Your input data is not valid"
Endif
End Sub

Formatting Text Boxes in a Userform

I have a Userform that includes Text Boxes with multiple formats. I have the Initialize as blank ("") and then format them using afterupdate(). This all works fine, my issues come from the possibility of the user miss keying the data the first go around or just clicking aimlessly on there screen. After you input a value it formats it correctly when you move from the text box. But if you reselect the text box then move away again, it clears the value. And if you do this with the text box that is formatted as a percent it actually bugs out with a mismatch error.
Here is a slice of my current code:
Private Sub UserForm_Initialize()
ValueAnalysisTextBox.Value = ""
CapRateTextBox.Value = ""
End Sub
Private Sub ValueAnalysisTextBox_AfterUpdate()
ValueAnalysisTextBox.Value = Format(Val(ValueAnalysisTextBox.Value), "$#,###")
End Sub
Private Sub CapRateTextBox_AfterUpdate()
CapRateTextBox.Value = Format(Val(CapRateTextBox.Value) / 100, "Percent")
End Sub
Any thoughts on how to clean this up would be great.
Is this what you are trying?
Private Sub ValueAnalysisTextBox_AfterUpdate()
Dim amt As Double
amt = Val(Replace(ValueAnalysisTextBox.Value, "$", ""))
ValueAnalysisTextBox.Value = Format(amt, "$#,###")
End Sub
Private Sub CapRateTextBox_AfterUpdate()
Dim Perct As Double
Perct = Val(Replace(CapRateTextBox.Value, "%", "")) / 100
CapRateTextBox.Value = Format(Perct, "Percent")
End Sub
Note: I am not doing any other error handling. For example, user typing "Blah Blah" or pasting something else in the textbox. I am sure you can handle that.
I'd store the underlying values in the .Tag property of the TextBox, then use it to change the formatting back and forth in the Enter and Exit events:
Private Sub UserForm_Initialize()
ValueAnalysisTextBox.Value = vbNullString
ValueAnalysisTextBox.Tag = vbNullString
End Sub
Private Sub ValueAnalysisTextBox_Enter()
ValueAnalysisTextBox.Value = ValueAnalysisTextBox.Tag
End Sub
Private Sub ValueAnalysisTextBox_Exit(ByVal Cancel As MSForms.ReturnBoolean)
If IsNumeric(ValueAnalysisTextBox.Value) Then
ValueAnalysisTextBox.Tag = Val(ValueAnalysisTextBox.Value)
ValueAnalysisTextBox.Value = Format$(ValueAnalysisTextBox.Tag, "$#,###")
Else
ValueAnalysisTextBox.Tag = vbNullString
End If
End Sub

VBA - If scrollbar is changed left or right

I have a scrollbar in a userform and I would like to run some code if it is shifted left and run some different code if it is shifted right.
Something like this (obviously this doesn't work):
Private Sub ScrollBar1_Change()
If ScrollBar1 = Left Then
MsgBox "left"
ElseIf ScrollBar1 = Right Then
MsgBox "right"
End If
End Sub
Thank You
You need to use a module level variable to track the last position and compare it to the current:
Private mCurrentScrollPos As Long
Private Sub ScrollBar1_Change()
If (ScrollBar1.Value > mCurrentScrollPos) Then
MsgBox "Left"
Else
MsgBox "Right"
End If
mCurrentScrollPos = ScrollBar1.Value
End Sub
You would need to store a global variable. Set it when the Userform gets activated. And the do the code
Private Sub ScrollBar1_Change()
If (ScrollBar1.Value > scrollLoc) Then
MsgBox "Left"
Else
MsgBox "Right"
End If
scrollLoc= ScrollBar1.Value
end sub
Private Sub UserForm_Activate()
scrollLoc = Me.ScrollBar1.Value
End Sub
And have a global variable
private scrollLoc as long