Private Sub Workbook_open()
With Sheet1.ComboBox1
.AddItem "Soccer"
.AddItem "Tennis"
End With
End Sub
I would like to make an if statement such that if the ComboBox1 value changes either from nothing to Soccer/tennis or from one item to another
then
Range("A1").Value = "This learner Plays Sport"
the problem is I don't know how to do the part where the combobox value changes either from nothing to Soccer/tennis or from one item to another
I have tried workbook.change and it gives me an error the closes the whole program.
Instead of workbook change event try the ComboBox change event like this:
Private Sub ComboBox1_Change()
If Sheet1.ComboBox1.Value = "Soccer" Or Sheet1.ComboBox1.Value = "Tennis" Then
Worksheets("Sheet1").Range("A1").Value = "This learner Plays Sport"
End If
End Sub
To get to this change event just double click the combobox from the Worksheet and it will open the VBA editor for you.
This only tells you what the newly selected value is. If you need to know what it was before the change it will be a bit more complicated. You'll need to create a variable to store/track the value to compare against once changed.
If you end up with a long list of sports, I'd suggest using Select Case instead of if statements. For example:
Private Sub ComboBox1_Change()
Select Case Sheet1.ComboBox1.Value
Case "Soccer", "Tennis"
Worksheets("Sheet1").Range("A1").Value = "This learner Plays Sports"
Case "Lacross"
Worksheets("Sheet1").Range("A1").Value = "Something Different"
Case Else
Debug.Print "value not in list"
End Select
End Sub
Related
This is a very simplified example to demonstrate my problem.
Create a userform with a combobox and commandbutton.
Set the style property of the combobox to "fmStyleDropDownList".
Add the code
Private Sub CommandButton1_Click()
ComboBox1.Value = "But then it errors sometimes if I change it here"
End Sub
Private Sub UserForm_Initialize()
ComboBox1.Value = "I can initialize to any value I choose"
End Sub
When I run the userform I can click the command button all day long without getting any errors.
But, when I click on the drop-down arrow of the combobox and the text in the box gets highlighted, then the next time I click the command button I get "Run-time error '380': Could not set the Value property. Invalid property value"
Using style="fmStyleDropDownCombo" is not an option I want to consider. I tried using ComboBox1.ListIndex = -1 to clear the selection but that did not work.
Any ideas on how I can reliably avoid this error?
When you use fmStyleDropDownList style, your ComboBox value must match one of the item in the list but because you did not add any item, your list is currently Null.
To test this, make another ComboBox in your Userform and put this in your Userform:
Private Sub CommandButton1_Click()
Debug.Print "=== Click ==="
Debug.Print "ComboBox1 Type: " & TypeName(ComboBox1.List)
Debug.Print "ComboBox2 Type: " & TypeName(ComboBox2.List)
ComboBox1.Value = "But then it errors sometimes if I change it here"
On Error Resume Next
ComboBox2.Value = "But then it errors sometimes if I change it here"
If Err.Number <> 0 Then Debug.Print "ComboBox2 - Error"
Debug.Print "============="
End Sub
Private Sub UserForm_Initialize()
ComboBox1.AddItem "I can initialize to any value I choose"
ComboBox1.AddItem "But then it errors sometimes if I change it here"
ComboBox1.Value = "I can initialize to any value I choose"
ComboBox2.Value = "I can initialize to any value I choose"
Debug.Print "ComboBox1 Type: " & TypeName(ComboBox1.List)
Debug.Print "ComboBox2 Type: " & TypeName(ComboBox2.List)
End Sub
When you run the Userform, you should see this in the immediate window:
ComboBox1 Type: Variant()
ComboBox2 Type: Null
Clicking the button (as many times as you like) before clicking ComboBox2 and you will notice that the output will still be the same. (and no error too because the List is still Null)
Now click ComboBox2 and click the button again, you will see that the type for ComboBox2.List has now changed from Null to Variant and will actually trigger the error.
===============
So, to avoid this, you need to populate the List first, below shows the AddItem method:
Private Sub CommandButton1_Click()
ComboBox1.Value = "But then it errors sometimes if I change it here"
End Sub
Private Sub UserForm_Initialize()
ComboBox1.AddItem "I can initialize to any value I choose"
ComboBox1.AddItem "But then it errors sometimes if I change it here"
ComboBox1.Value = "I can initialize to any value I choose"
End Sub
As far as I know, the preferred way to set a ComboBox value with such style is to loop through the ComboBox List property, check its value and change the ListIndex once found:
Private Sub CommandButton1_Click()
Dim i As Long
For i = 0 To ComboBox1.ListCount - 1
If ComboBox1.List(i) = "But then it errors sometimes if I change it here" Then
ComboBox1.ListIndex = i
Exit For
End If
Next i
End Sub
I have a ComboBox control on a custom CommandBar. I want to detect when a change has been made to the ComboBox and run some code.
This works fine when the user changes the value in the ComboxBox, but if some other VBA code changes it, the Event is not fired.
I have taken the code from here: https://learn.microsoft.com/en-us/office/vba/api/office.commandbarcombobox.change
and modified it slightly to delete a CommandBar with the same name so I can run it a number of times. I have then added another function to change the value of the ComboBox programmatically. When I change the value programmatically it can be seen to change on the Excel GUI, but the event code does not fire.
I have also tried the easier OnAction method, rather than hooking events, both seem to give the same result.
In a ClassModule called ComboBoxHandler I have the following code:
Private WithEvents ComboBoxEvent As Office.CommandBarComboBox
Public Sub SyncBox(box As Office.CommandBarComboBox)
Set ComboBoxEvent = box
If Not box Is Nothing Then
MsgBox "Synced " & box.Caption & " ComboBox events."
End If
End Sub
Private Sub Class_Terminate()
Set ComboBoxEvent = Nothing
End Sub
Private Sub ComboBoxEvent_Change(ByVal Ctrl As Office.CommandBarComboBox)
Dim stComboText As String
stComboText = Ctrl.Text
Select Case stComboText
Case "First Class"
FirstClass
Case "Business Class"
BusinessClass
Case "Coach Class"
CoachClass
Case "Standby"
Standby
End Select
End Sub
Private Sub FirstClass()
MsgBox "You selected First Class reservations"
End Sub
Private Sub BusinessClass()
MsgBox "You selected Business Class reservations"
End Sub
Private Sub CoachClass()
MsgBox "You selected Coach Class reservations"
End Sub
Private Sub Standby()
MsgBox "You chose to fly standby"
End Sub
In a module I have the following:
Private ctlComboBoxHandler As New ComboBoxHandler
Sub AddComboBox()
Set HostApp = Application
On Error Resume Next
CommandBars("Test CommandBar").Delete
Dim newBar As Office.CommandBar
Set newBar = HostApp.CommandBars.Add(Name:="Test CommandBar", Temporary:=True)
Dim newCombo As Office.CommandBarComboBox
Set newCombo = newBar.Controls.Add(msoControlComboBox)
With newCombo
.AddItem "First Class", 1
.AddItem "Business Class", 2
.AddItem "Coach Class", 3
.AddItem "Standby", 4
.DropDownLines = 5
.DropDownWidth = 75
.ListHeaderCount = 0
End With
ctlComboBoxHandler.SyncBox newCombo
newBar.Visible = True
End Sub
Sub test()
Dim newBar As Office.CommandBar
Set newBar = Application.CommandBars("Test CommandBar")
Dim cmbox As Office.CommandBarComboBox
Set cmbox = newBar.Controls(1)
cmbox.Text = "Business Class" ''<< I was hoping this would fire an event, but it does not! Same is true if I
End Sub
First I run AddComboBox and the events work fine if I manually change the ComboBox.
Then I run test() and the value displayed inside the ComboBox changes, but the event does not fire.
Say I had a userform with 3 options:
Listbox1: Item 1
Item 2
Item 3
I want to reference them in the main code, like:
If Listbox1 = *Item 1*
do something
or
*Item 1* = 400
How do I reference Item 1 in the code? Would it be Listbox1.1? Listbox1 = 1? "Item 1"?
Here is one simple example illustrating the concept. As Mathieu Guindon pointed out in a comment, you can use ListBox.Text.
Suppose you have the following user form which is opened by clicking the button "Show User Form". I assume from your question that you would like to do something like selecting an item in the list and then do something in the code when you click the OK button. In my example, clicking OK launches the Message Box showing which item was selected, but you could of course do whatever you want. The code that generates the messsage box is located in a regular module, while the code for the OK button and Listbox is located in the user form.
The button "Show User Form" simply calls the following sub in the regular module:
Public Sub ShowForm1()
UserForm1.Show
End Sub
This displays the user form, which is initialized with the following code:
Private Sub Userform_initialize()
With Me.ListBox1
.AddItem "Item 1"
.AddItem "Item 2"
End With
End Sub
The code below for the OK button includes the reference Me.ListBox1.Text that captures the selected item and stores it in a variable which is then passed to the subroutine ShowMsgBox in the regular module. Note the use of Me. which is shorthand for referencing the user form where the listbox is located (i.e. the same form as the OK button):
Private Sub okButton_Click()
sSelectedItem = Me.ListBox1.Text
ShowMsgBox (sSelectedItem)
Unload Me
End Sub
The code above calls ShowMsgBox, which is in the regular module:
Public Sub ShowMsgBox(sInput As String)
MsgBox "You selected " & sInput & ".", vbOKOnly
' Other code to do something with the selected item goes here.
End Sub
Note that in ShowMsgBox() you no longer reference the listbox, but rather work with the value sInput passed as an argument.
Hope you find this useful.
EDIT:
Following Skye's comment, here is a suggestion on how to open other forms instead of a message box. You must replace one line in okButton_Click()
, like this:
Private Sub okButton_Click()
sSelectedItem = Me.ListBox1.Text
ShowOtherUserForm (sSelectedItem)
Unload Me
End Sub
Then, in the regular module, add the sub ShowOtherUserForm(). This sub uses Select Case to check which item was selected. You can do the same job with If, but I prefer the Select style for this scenario. My example requires that you have two userforms called "OtherForm1" and "OtherForm2".
Sub ShowOtherUserForm(sInput As String)
Dim x As Object ' Must be "Object", declare "As UserForm" won't work.
Select Case sInput
Case "Item 1"
Set x = OtherForm1
Case "Item 2"
Set x = OtherForm2
End Select
x.Show
End Sub
Screenshot of result:
A basic simple VBA question that I havent been able to work out even though there are numerous tutorials about it.
I want a Userform to pop-up, give you two options (OptionButton1 and OptionButton2). You choose one, click ok. And depending on what Option is chosen a certain value is used (in an email, for which I DID finish the macro). For simplifying purposes i now just want the variable 'contents' to be printed in cell A1.
I have these parts so far:
Sub MailOption()
UserForm1.Show
End Sub
Private Sub OptionButton1_Click()
If OptionButton1.Value = True Then Var1 = "Text example 1"
End Sub
Private Sub OptionButton2_Click()
If OptionButton2.Value = True Then Var1 = "Text example 2"
End Sub
Private Sub SendEmail_Click()
Cells(1, 1).Value = Var1
End Sub
There are multiple problems: the variable is not shown in Cell A1 and when i press Send Email the Form is not closed. I am probably doing lots of stuff wrong but its the first time im using a userform. Ty very much
I would simply use this one without handling OptionButton_Click:
Private Sub SendEmail_Click()
Dim res As String
If OptionButton1.Value Then
res = "Text example 1"
ElseIf OptionButton2.Value Then
res = "Text example 2"
Else
res = "Nothing is selected"
End If
'write result in cell
ThisWorkbook.Worksheets("Sheet1").Range("A1").Value = res
'close form
Unload Me
End Sub
I have a question:
I need to create a user form that contain that usual OK and Cancel Buttons. It also should contain two sets of Options buttons, each set placed inside a frame. The captions on the first set should be basketball, baseball, football, the captions on the second set should be watch on TV and Go to games. I need to write the event handlers and code in a module so that when the program runs, the user sees the form. If the user makes a couple of choices and clicks OK, he should see a message like "Your favorite sport is basketball, and you usually watch on TV." If the user clicks Cancel, the message "Sorry you don't want to play" should appear.
I think I almost have it working, but I don't know why I cannot successfully execute the Macro.
My Code is :
Option Explicit
Private Sub CommandButton2_Click()
MsgBox ("sorry if you don't want to play")
End Sub
Private Sub commandbuttons_Click()
Dim optbasket As String, optbaseball As String, optfootball As String
Dim optwog As String, optgtg As String
Select Case True
Case optbasket
optbasket = True
Case optbaseball
optbaseball = True
Case optfootball
optfootball = True
End Select
If optwog Then
optwog = True
Else
optgtg = True
End If
btnok = MsgBox("you favorite sport is " & Frame1.Value & "you usually " & Frame2.Value & ",")
End Sub
Private Sub OptionButton1_Click()
End Sub
Private Sub btmcancel_Click()
End Sub
Private Sub btnok_Click()
End Sub
Private Sub Frame1_Click()
End Sub
Private Sub Frame2_Click()
End Sub
Private Sub optbaseball_Click()
End Sub
Private Sub optbasketball_Click()
End Sub
Private Sub optfootball_Click()
End Sub
Thank you very much!!!
There are a few things here:
You should name your buttons to be "OkButton" and "CancelButton" or something like that. They'll be easier to track later. Same thing for your radio buttons (baseball, basketball, etc.)
You don't need your select statement or your if statement
I don't think Frame1 and Frame2 have a .Value property you can call
Here is some sample code. You would add an object to your worksheet that could be clicked on. In this example I just inserted a rectangle object. form the Insert tab. Then in the UserForm code, I renamed the Ok Button to be OkButton and added the function OkButton_click. When it is clicked, I capture the values of the radio buttons. I named them baseball, basketball, and football accordingly as well as watch and go. If one of them is true, then I assign "game" which is a string I declared to be the appropriate title of the game. I did the same thing for whether the person likes to go to the game or watch it. Then I added the CancelButton_Click function to close the userForm.
Private Sub Rectangle1_Click()
UserForm1.Show
End Sub
Private Sub OkButton_Click()
Dim game as String, watchOrGo as String
If baseball Then game = "baseball"
If basketball Then game = "basketball"
If football Then game = "football"
If watch Then watchOrGo = "watch"
If go then watchOrGo = "go"
okbtn = Msg("Your favorite sport is " & game & ". You usually " & watchOrGo)
End Sub
Private Sub CancelButton_Click()
cnclbtn = Msg("Sorry you don't want to play")
Unload Me
End Sub
If you want the code in commandbuttons_Click() to run when you click OK, you need to put it in the click handler for the OK button: btnok_Click(); likewise for CommandButton2_CLick() and btncancel_Click().