Looking for advice on the best way to pass an Id of a value into a parameter in excel VBA.
Essentially I'm trying to replicate getting the value rather than the text itself like for example in html:
<option value="1">Option one</option>
Would return 1. I could concatenate the Id to the start or end of the string with something like:
.additem varList(0, 1) & " | " & varList(1, 1)
But I'm looking for a 'cleaner' option if that makes sense?
Cheers
Create your combobox with at least 2 columns. This can be set using the ColumnCount property, via the VBE or through VBA code.
You can then adjust the ColumnWidths property to make one of the columns a width of 0 so it will not be displayed/visible to users.
WHen you populate the combobox, simply put the ID in one column of the ComboBox, and put the value in the other visible column. The interface will look like this, unless you adjust the columnwidths
Use the BoundColumn of the ComboBox to return the appropriate value, or you can do some iteration over the selected item(s) and refer to the indexed position:
Debug.Print Me.ComboBox.List(0, 0) '# Display the first row item in the first column
Debug.Print Me.ComboBox1.List(0, 1) '# Display the first row item in the SECOND column
Related
I have in my userform listbox which display 10 columns. All rows have an individual ListIndex.
I would like to display f.e. in Msgbox value after select some row and click button "Show".
But this value is not avalible in listbox. So, I thought that all rows have individual ListIndex, I can use VLOOKUP for finding my target.
For example: I selected row no. 1 then ListIndex is 1 and this is my Look up Value. In my database sheet I have the same individual ID values.
Then of course, I have to declarate range, number of column and parameter "False".
Theoretically, I expect the result after that but it doesn't work.
My code:
Dim indexno As Long 'this is my delcaration for finding Look up Value
Dim myVLookupResult As Long 'this is my declaration for VLookup Result
indexno = ListBoxResult.ListIndex 'my Lookup Value is dynamic and depend of selected row
myVLookupResult = Application.VLookup(indexno, Worksheets("DataBase").Range("A1:J100"), 5, False)
MsgBox myVLookupResult 'should display result of VLOOKUP
But the result is error: Run-Time error: 13 - Type mismatch.
I guess the problem is with convert type of Dim from int to string.
Someone could support me, please? Thanks in advance!
The lookup value of a VLOOKUP worksheet function must be of the same data type as the data in which it is to be found. In your code the lookup value is of Long data type. If the column in which you are looking for it has text, the number you are looking for will not be found. So, you change the lookup value to Variant and hope that Excel will be able to work out what you want. But the better way is to examine your data column and look up the type of value you actually have there.
Next, given you are looking for a number which you have assigned to a Variant and Excel, in consequence, managed to find the string-equivalent of that number, that would be the functions return value, a text string. In most cases Excel is quite generous in this sort of situations but if it does complain about "Data Type" then it's because you are trying to assign a text string to a variable of Long data type.
Other than that, as #Michal Palko already pointed out, the ListBox's ListIndex is 0-based. If the numbers in your worksheet are 1-based the return of VLOOKUP won't be "totally different" but it will be from the adjacent row and therefore unexpected.
But I want to alert you to another possibility. As you know, you can load many columns into your list box. You can show some of the columns and hide others but you can access them all with code like this:-
With ListBox1
Debug.Print .List(.ListIndex, 3)
End With
This snippet will print out the value of the 3rd column in the row of ListIndex. You might also assign this value to a variable and, perhaps, have no need for VLOOKUP.
I'm trying to list row labels of a pivot table but can't access them. They don't show up as row labels so I am not sure.
Example:
Row Labels Sum of Resources
---------- ----------------
item 1 1
item 2 4
item 3 2
I want to be able to access item1, item2, and item3.
The code I have so far is below and it does what I want except for access items 1 to 3:
Dim item As Variant
For Each item In ActiveSheet.PivotTables("Pivot1"). _
PivotFields("Sum of Resource").DataRange
Debug.Print item;
Next item
Refer directly to the cell
Further to our comments, this is not the best way to get a summary of data, but you seem determined, and without more information about what you have and what you're trying to do, I can only wonder why you don't just refer to the label cells "like any other cell".
Example:
In the example above, =D2 returns A, which is the first label of the PivotTable.
The GetPivotData setting & functions
Note that your formulas with the above examlpe might appear differently depending on your settings (in Options) for "Use GetPivotData functions for PivotTable references" (mine is unselected), but the end result is the same either way.
Click image to enlarge.
There is more information about GetPivotData in the documentation here.
The DataLabelRange property
There are several other ways of referring to [any] part of a PivotTable, some more reliable than others if the data is changing often. An alternative could be to use the DataLabelRange property.
More on the DataLabelRange property in the documentation here and examples here.
I was able to figure out how to do this. Not sure if anyone else has this issue but the code below will list all the row labels.
'Get Row labels
For Each item In ActiveSheet.PivotTables("Pivot-Table").RowRange
If Not count = 0 And Not count = ActiveSheet.PivotTables("Pivot-Table").RowRange.count - 1 Then
Debug.Print item
End If
count = count + 1
Next item
This code will print all row labels ignoraing the grand total and row label caption
I have had a look online for an answer to this but no joy with coming across one as of yet. Is it possible to have a text box in a UserForm be dynamic?
My current idea is to have 3 columns of text boxes, in Column 1 & 2 the user need to enter there data and was wondering if in Column 3 there is a way to show the value involving Column 1 and Column 2?
If this isn't possible, are you able to reference a cell on a sheet and then get the useform to display the cells value?
Ideally i would like this to be possible as it provides the user with a quick check to ensure they've entered the data right.
Edit 1
TextBox18.Value = (TextBox1.Value + TextBox10.Value) / 2
I found that this line of code allowed me to reference two text boxes dynamically but textbox 18 concatenating rather than added the numbers. Is there a way round this?
Thanks
Alternatively something like this could help, this will add the values and not concatenate them:
TextBox3.Value = (Val(TextBox1.Value) + Val(TextBox2.Value))
Use the TextBox_Change() event method to dynamically update values.
Example:
Sub TextBox46_Change()
TextBox46.Value=(TextBox1.Value + TextBox36.Value) / 2
End Sub
I can click on my ComboBox and see the values of Column1 and Column2, but after I click on off the ComboBox, the value in Column1 is always displayed and I want the value of Column2 displayed.
I tried this:
With ComboBox2
.Value = "None"
.ColumnHeads = True
.ColumnCount = 2
.ColumnWidths = "50;100"
.RowSource = "SetupQuestions!A42:B48"
.BoundColumn = 2
End With
That didn't set the value as I thought it would.
I tried this:
Private Sub ComboBox2_AfterUpdate()
ComboBox2.Value = ComboBox2.Column(2)
End Sub
That didn't set the value as I thought it would.
How can I force the ComboBox to display the value in Column2 after a selection is made?
The DropList of a ComboBox can show multiples columns, but after selecting a row, it can show only one column as Text. To show the second column use the property TexColumn.
Me.ComboBox1.TextColumn = 2
If you are only concerned with appearances, there is a workaround
Private Sub ComboBox2_Click()
With ComboBox2
.Text = .List(.ListIndex, 0) & " | " & .List(.ListIndex, 1)
End With
End Sub
Argh! It's not .Value
It's .Text
Private Sub ComboBox2_AfterUpdate()
Me.ComboBox2.text = Me.ComboBox2.Column(1)
End Sub
I just came across here because I was looking to solve this too. but other people's response helped me find the answer.
If you haven't gotten it yet, here is my solution.
Private Sub ComboBox_AfterUpdate()
ComboboxList.Text = ComboboxList.Column(0) & " " & ComboboxList.Column(1)
End Sub
An alternative you can use without VBA.
Combo row source (adjust for your situation):
SELECT Adults.aID, Trim([Adults].[LastName]) & ", " & Trim([Adults].[FirstName]) AS Expr1
FROM Adults WHERE ((Not (Adults.LastName)=("isNull")))
ORDER BY Adults.LastName, Adults.FirstName;
Basically, make your second column a composite single field via SQL.
Bound column: 1, Column count: 2, Column widths: 0cm;4cm
You can use this technique to display whatever you want by building the string representation as a single field.
The reason is in your setting of ColumnWidth. Your combobox shows two columns. The second one can't be displayed because the total width of your box is insufficient. Therefore you see the first column only. Set the ColumnWidth to "0;100" and you will see the second column. Make sure that there is a working relationship between the width of the box and that of the columns to be displayed within it.
Use a text field ond the right side of the combo box. Set the number of columns in the combo box to 2.
Set the list width the size of both combo and text together (a+b)
Set the columns width for the size of the combo and the size of the text (a;b)
Since the columns property is an 0 based array of columns, set the source of the text field to "=[MyCombo].Columns(1)" to display the second field.
When you drop down, the first column should be exactly under the combo box and the second column under the text box.
When you update the combo, the text box should update its value accordingly.
Additionally you may want to set the text box properties locked to true and enabled to false.
Open Design View
Open Property Sheet
Under the "Data" tab click on the three dots to the right of the "Row Source" item
In the Query Builder that opens, move the desired column you want to view in the combo box field where in the place where the currently viewed column is
Change any VBA code accordingly. For Example: If Column(1) was showing in the combo box field and you moved Column(2) to the place of Column(1), then Column(2) becomes Column(1) and Column(1) becomes Column(2). This will affect any VBA Code referring to Column numbers and also may affect the default value assessed for that Combo Box when a column number is not specified in the VBA code.
I'm unable to find out this information: Is it possible to show labels in these two type of lists rather than the real values ? of course when a label is selected, the value of the cell or the combobox (as a Form control) gets the real value.
Example:
* Data
Product A <------> 10
Product B <------> 11
Product C <------> 22
Combobox shows: Product A, Product B and Product C
If I select A I get the 10 value, B the 11 value and C the 22 value
Thank you in advance
Miloud B.
The typical way of doing this is to have a lookup table. There's a function named something like VLOOKUP (that's a partial name) that you can use in formulas to retrieve the value. I did something like this at my job, and I created a lookup table in a separate spreadsheet, and then called the lookup function in my main one.
You can also use macros, but that is too much bother in my opinion for the current problem.
Data Validation: You can't have two values per row. You can use a lookup table to convert one value to another. Or you can combine the values like "ProductA_10" and use a formula to extract the "10" where you need it.
Form Combobox: This also has limited options and doesn't really offer anything more than DV does for what you want.
Toolbox Combobox: This can do just about anything you want. You would set the ColumnCount property to 2, the BoundColumn property to 2, and the ColumnWidths property to something like "1;0" to hide the second column. If I had ProductA-C in A1:A3 and 10-12 in B1:B3, then I would use code like this in a standard module to fill the combobox
Sub LoadCombobox()
Dim rCell As Range
For Each rCell In Sheet1.Range("A1:A3").Cells
Sheet1.ComboBox1.AddItem rCell.Value
Sheet1.ComboBox1.List(Sheet1.ComboBox1.ListCount - 1, 1) = rCell.Offset(0, 1).Value
Next rCell
End Sub
And code like this in the sheet's module to put a value in a cell (F1 in this example)
Private Sub ComboBox1_Change()
Me.Range("F1").Value = Me.ComboBox1.Value
End Sub
Whenever a new value in the combobox is selected, F1 is updated. We can use the Value property of the combobox because we set the BoundColumn property to the column with the value we want.