Cycle through a loop in VBA - excel

I have a form in VBA where I want a combo box (cboIncluded) to change its dropdown values according to what's chosen in a different combo box(cboSelectParty).
It provides choices correctly the first time I choose something from cboSelectParty, and if I choose again from either my If or elseif.
My problem is, if I have chosen from either the if or elseif (Fun climb party or climbing party), if won't go back to giving me correct options if I choose anything else.
Private Sub cboSelectParty_AfterUpdate()
cboIncluded.Value = ""
If cboSelectParty.Value = "Fun Climb Party" Then
cboIncluded.List = Sheets("PartyImport").Range("N3:N4").Value
ElseIf cboSelectParty.Value = "Climbing Party" Then
cboIncluded.List = Sheets("PartyImport").Range("O3:O6").Value
Else
cboIncluded.Value = Application.WorksheetFunction.VLookup(cboSelectParty.Value,
Sheets("PartyImport").Range("E2:H37"), 4, False)
End If
End Sub

Related

Inputbox selection causing: "Text is not valid." Error [duplicate]

The current function I use to collect text InputBox can't accept more than 255 characters apparently, and I need to be able to collect more than that? Is there a parameter or different function I can use to increase this limit?
To be pedantic, the Inputbox will let you type up to 255 characters, but it will only return 254 characters.
Beyond that, yes, you'll need to create a simple form with a textbox. Then just make a little "helper function" something like:
Function getBigInput(prompt As String) As String
frmBigInputBox.Caption = prompt
frmBigInputBox.Show
getBigInput = frmBigInputBox.txtStuff.Text
End Function
or something like that...
Thanks BradC for the info that. My final code was roughly as follows, I have a button that calls the form that I created and positions it a bit as I was having some issues with the form being in the wrong spot the everytime after the first time I used.
Sub InsertNotesAttempt()
NoteEntryForm.Show
With NoteEntryForm
.Top = 125
.Left = 125
End With
End Sub
The userform was a TextBox and two CommandButtons(Cancel and Ok). The code for the buttons was as follows:
Private Sub CancelButton_Click()
Unload NoteEntryForm
End Sub
Private Sub OkButton_Click()
Dim UserNotes As String
UserNotes = NotesInput.Text
Application.ScreenUpdating = False
If UserNotes = "" Then
NoteEntryForm.Hide
Exit Sub
End If
Worksheets("Notes").ListObjects("Notes").ListRows.Add (1)
Worksheets("Notes").Range("Notes").Cells(1, 1) = Date
Worksheets("Notes").Range("Notes").Cells(1, 2) = UserNotes
Worksheets("Notes").Range("Notes").Cells(1, 2).WrapText = True
' Crap fix to get the wrap to work. I noticed that after I inserted another row the previous rows
' word wrap property would kick in. So I just add in and delete a row to force that behaviour.
Worksheets("Notes").ListObjects("Notes").ListRows.Add (1)
Worksheets("Notes").Range("Notes").Item(1).Delete
NotesInput.Text = vbNullString
NotesInput.SetFocus ' Retains focus on text entry box instead of command button.
NoteEntryForm.Hide
Application.ScreenUpdating = True
End Sub
I don't have enough rep to comment, but in the sub form_load for the helper you can add:
me.AutoCenter = True
Outside of that form, you can do it like this:
NoteEntryForm.Show
Forms("NoteEntryForm").AutoCenter = True
My Access forms get all confused when I go from my two extra monitors at work to my one extra monitor at home, and are sometimes lost in the corner. This AutoCenter has made it into the form properties of every one of my forms.

Problem with multiline string in userform

I am having a issue with multiline stings in a userform.
When a user selects a option, the code checks if the selected answer matches the correct answer and then shows if right or wrong. But in either case the code says it is wrong.
Example of a option is:
If you see the string, brush it off sideways
Place icepack/cold flannel to reduce swelling
Elevate area to reduce bloodflow
Private Sub OptionButton1_Click()
rowNum = Selection.Row - Selection.ListObject.Range.Row
DeclareVars
Column = examtable.ListColumns("Right ans").DataBodyRange(rowNum)
CorrectAns = examtable.ListColumns("Right ans").DataBodyRange(rowNum).Offset(0, Column)
RightWrong.Visible = True
If OptionButton1.Caption = CorrectAns Then
RightWrong.BackColor = &HFF00&
RightWrong.Caption = "Right"
Else
RightWrong.BackColor = &HFF&
RightWrong.Caption = "Wrong"
End If
End Sub
What i am expecting is that if correct, shows right, or wrong if incorrect
If I understand correctly you have multiple option buttons below one another? Option button one will always have the same caption. If it is selected it can become true (indicated by the black dot), but the caption will not change.
Lets say it looks like this
two option buttons
Then the upper is called OptionButton1, the lower OptionButton2.
You can check
If OptionButton1 then
RightWrong.BackColor = &HFF00&
RightWrong.Caption = "Right"
Else
RightWrong.BackColor = &HFF&
RightWrong.Caption = "Wrong"
End if
You could use a combobox (these are the drop down menus).
You could populate it with an array of the strings you want to test and ask if the answers concur.
When loading the user form use
Private Sub UserForm_Activate()
ComboBox1.list = Array("brush it off sideways", "Place icepack/cold flannel to reduce swelling", "Elevate area to reduce bloodflow")
End Sub
this will look as followed
The user form with the list open
Then you can say combobox.value = CorrectAns

Choosing a listbox from multiple list boxes

I am somewhat new to excel vba and I am in search of an answer on how to choose a list box by using a variable.
For instance the code I found is as follows:
Me.ListBox2.AddItem Me.LB_JobList.List(iCtr)
Instead of ListBox2 I would like the 2 to be another number selected by the user from a combo box.
Current code is:
FrameNumber = CMB_FrameNumber.Value 'number selected by user
lb = ("ListBox" & FrameNumber) 'this would = ListBox#
Therefore I would like something similar to
Me.lb.AddItem Me.LB_JobList.List(iCtr)
The comment above is good, but if you want to do something a little safer (in case you have more numbers available than controls, say), you could loop through the available controls and check against their name.
For Each contr In UserForm1.Controls
If TypeName(contr) = "ListBox" And contr.Name = ("ListBox" & FrameNumber) Then
lb = contr
End If
Next

Validate a TextBox before the _Change event is fired

I've got a form that has 3 TextBox controls on it: stock code, quantity, certificate number. The stock code TextBox is set to focus automatically when the form is loaded.
I've also attached a bar code scanner to my PC, as the user wants to be able to either scan a bar code to populate the TextBox, or manually type the data in.
The labels being scanned contain two bar codes. One is a certificate number and the other a stock code.
The stock bar code has a prefix of "SBC/", whilst a certificate bar code is prefixed with "C/".
When the user scans a bar code, if the TextBox in focus is the stock code TextBox, then I want to run a check as below.
Private Sub txtStockCode_Change()
On Error GoTo errError1
If Len(txtStockCode.Text) >= 5 Then
If bChangeCode Then
If Left(txtStockCode.Text, 2) = "C/" Then
msgbox "You have scanned the certificate barcode; please scan the stock barcode."
txtStockCode.Text = ""
Else
bChangeCode = False
txtStockCode.Text = Replace(txtStockCode.Text, "SBC/", "")
txtStockCode.Text = Replace(txtStockCode.Text, "*", "")
End If
End If
End If
Exit Sub
Let's say the focus is currently on the stock code TextBox.
If the stock bar code is scanned, the following should happen:
Stock code length is greater than 5
Left 5 characters do not = "C/", so correct code has been scanned
TextBox text value is updated to remove all * and the prefix of "SBC/"
E.g. "SBC/A12-TR0*" becomes "A12-TRO"
and
Certificate number length is greater than 5
Left 5 characters do = "C/", so incorrect code has been scanned
MsgBox to user
TextBox value is reset to ""
However, no matter which code is scanned into the stock code TextBox, the value is never validated.
E.g. "SBC/A12-TR0*" remains as "SBC/A12-TR0*" and "C/29760" remains as "C/29760"
As the validation code is the same in the certificate TextBox, the same pattern is repeated vice versa.
Why are my values not updating, or how can I validate the input before the _Change is fired?
EDIT
I've now changed my code to
Private Sub txtStockCode_Change
If txtStockCode.Text <> "" Then
txtStockCode.Text = Replace(txtStockCode.Text, "SBC/", "")
txtStockCode.Text = Replace(txtStockCode.Text, "*", "")
End If
End Sub
But it still displays the prefix of SBC/, yet is removing the two * characters (at the start and end of the barcode as is required for the scanner to read it as a barcode)
You could try to set the barcode reader to return Enter key at the end of the scanned barcode and then use the Keypress event to check it and make your changes.
Sub txtStockCode_KeyPress(KeyAscii As Integer)
If KeyAscii = vbKeyReturn Then
If Len(txtStockCode.Text) >= 5 Then
If bChangeCode Then
If Left(txtStockCode.Text, 2) = "C/" Then
msgbox "You have scanned the certificate barcode; please scan the stock barcode."
txtStockCode.Text = ""
Else
bChangeCode = False
txtStockCode.Text = Replace(txtStockCode.Text, "SBC/", "")
txtStockCode.Text = Replace(txtStockCode.Text, "*", "")
End If
End If
End If
End If
End Sub

Using excel vba to change the value of a dropdown menu on a website

I am writing an Excel macro to fill out a form on a website. I have written the code that populate the text boxes easily enough, and found code to chose radio boxes, but I am having problems with choosing info from dropdown menus.
Example 'Gender':
The combo box has three options:
Select / Male / Female
I've tried a few variations on this:
doc.getElementsByName("xs_r_gender").Item(0).Value="Male"
...but with no luck.
This is the web source code:
<td> <select name="xs_r_gender" id="xs_r_gender">
<option value="" selected>Select</option>
<option value="male">Male</option>
<option value="female">Female</option> </select></td>
Thanks.
doc.getElementById("xs_r_gender").selectedindex=1
seems to do the trick. (Where 1 represents male)
Though it means I will need to do alot of lookups to determine what the value is for the items in my dropdown. (Easy enough for Sex, where there are only two options, but I have some comboboxes with up to 50 options). If anyone knows of a faster solution, that'd be great. In the meantime, Ill start doing up some tables!!!
thanks.
Try below code assuming doc = ie.document
doc.getElementById("xs_r_gender").value = "Male"
Use this in your code to call the function below.
xOffset = SetSelect(IE.Document.all.Item("shipToStateValue"), "Texas")
doc.getElementById("shipToStateValue").selectedindex = xOffset
Then use this for your function
Function SetSelect(xComboName, xComboValue) As Integer
'Finds an option in a combobox and selects it.
Dim x As Integer
For x = 0 To xComboName.options.Length - 1
If xComboName.options(x).Text = xComboValue Then
xComboName.selectedindex = x
Exit For
End If
Next x
SetSelect = x
End Function
Thanks Stack, works for me! My solution to operate an IE HTML combobox drop down turned out to be two parts.
Part 1 was to click the pull down, here's code:
Dim eUOM1 As MSHTML.HTMLHtmlElement
Set eUOM1 = ie.document.getElementsByTagName("input")(27).NextSibling
eUOM1.Focus
eUOM1.Click
Part 2 was to choose and click the value, like this (*actual element name changed):
Dim eUOM2 As MSHTML.HTMLHtmlElement
Set eUOM2 = ie.document.getElementsByName("[*PutNameHere]")(0)
eUOM2.Value = "EA"
eUOM2.Click
Here are references:refs
You can try the querySelector method of document to apply a CSS selector of option tag with attribute value = 'male':
doc.querySelector("option[value='male']").Click
or
doc.querySelector("option[value='male']").Selected = True
Function SetSelect(s, val) As Boolean
'Selects an item (val) from a combobox (s)
'Usage:
'If Not SetSelect(IE.Document.all.Item("tspan"), "Custom") Then
'something went wrong
'Else
'continue...
'End If
Dim x As Integer
Dim r As Boolean
r = False
For x = 0 To s.Options.Length - 1
If s.Options(x).Text = val Then
s.selectedIndex = x
r = True
Exit For
End If
Next x
SetSelect = r
End Function
Try this code :
doc.getElementById("xs_r_gender").value = "Male"
doc.getElementById("xs_r_gender").FireEvent("onchange")
You can do something like this:
doc.getElementsByName("xs_r_gender").Item(1).Selected=True
or
doc.getElementById("xs_r_gender").selectedindex = 1
Where 1 is the male option (in both cases).
If the dropbox needs to fire some event in order to aknowledge your choice, it is likely that it will be the "onchange" event. You can fire it like so:
doc.getElementById("xs_r_gender").FireEvent("onchange")
If you ever want to be able to select an option based on the option's text you can use the function given by Lansman (here) .
Based on the same answer, if you want to call the option by it's value property (instead of the text, you can just change the line If xComboName.Options(x).Text = xComboValue Then to If xComboName.Options(x).value = xComboValue Then).
This should cover all bases.
Copy from Here till last line:
Sub Filldata()
Set objShell = CreateObject("Shell.Application")
IE_count = objShell.Windows.Count
For X = 0 To (IE_count - 1)
On Error Resume Next ' sometimes more web pages are counted than are open
my_url = objShell.Windows(X).document.Location
my_title = objShell.Windows(X).document.Title
If my_title Like "***Write your page name***" Then
Set IE = objShell.Windows(X)
Exit For
Else
End If
Next
With IE.document.forms("***write your form name***")
' Assuming you r picking values from MS Excel Sheet1 cell A2
i=sheet1.range("A2").value
.all("xs_r_gender").Item(i).Selected = True
End with
End sub

Resources