VBA Programming with multiple conditions using ComboBoxes - vba

I am new to VBA programming and working through excel VBA programming by myself and have a question involving multiple ComboBoxes that are being used to determine the value of a single cell.
I have 2 ComboBoxes.
Right now I am using something close to this syntax
Private Sub ComboBox1_Change()
If Me.ComboBox1.Value = "A" and Me.ComboBox2.Value = "2" Then
Range("A2").Value = Range ("B6").Value
Else Range("A2").Value = Range("B7")
End If
The code is not working. I am not getting anything return in what would be A2.
I am assuming that the entries in the ComboBoxes are strings of any sort and are correctly put into the code.
Any more troubleshooting help would be much appreciated.

You might try to capture the combobox2 value in a string variable
dim str_comboBox2 as string
str_comboBox2 = Me.ComboBox2.value
If Me.ComboBox1.value = "A" and str_comboBox2 ="2" then
As it might be interpreting your entry as a number thus not satisfying the IF statement.
Or change to:
If Me.ComboBox1.value = "A" and Me.ComboBox2.value = 2 then

Related

How to set up multiple choices list in Userform ComboBox code in Excel VBA?

Currently I am referencing excel cells to have drop down choice in my list in Userform. I would like to fix selection to few choices directly from VBA but not sure how to write list.. expression Me.ComboBox1.List = ('CIBSE','ASHRAE') does not work.
Private Sub UserForm_Initialize()
Me.ComboBox1.List = Worksheets("ControlSetUp").Range("b25:b26").Value
'Me.ComboBox1.List = ('CIBSE','ASHRAE')
Me.ComboBox1.Value = Worksheets("ControlSetUp").Range("d15").Value
End Sub
Me.ComboBox1.List = Array("CIBSE", "ASHRAE")
Combobox1.List = Split("CIBSE,ASHRAE", ",")
would also work, or even
Combobox1.List = Split("CIBSE ASHRAE")
using the default split separator which is a blank space.

VBA with if case for checkbox in excel

I am having an userform where I have 8 Checkboxes in it.
Each checkbox is assigned to an call function called autofilter.
I would like to have an vba,in such a way that more than one Checkbox is used, then it should Display the result of selected Checkbox.
How can I achieve in VBA. I am struck how i should proceed with this Problem.
Expecting an help from Forum.
This is my autofilter program
Sub autofilter()
Dim ws As Worksheet
Set ws = ThisWorkbook.Sheets("Result")
wslr = ws.Cells(Rows.Count, 1).End(xlUp).Row
Set myfilt = ws.Range("A1:AFU" & wslr)
myfilt.autofilter Field:=12, Criteria1:= _
"USA"
End Sub
similarly, i have them for other Locations as well till autofilter7.
Right now, i have the code working in such a way that, if check box 1 is true it calls autofilter1.
I would like to have a VBA, in such a way that, when i select 1 or more checkboxes, it should call their autofilter function together. How can i achieve this ?
[![I have userform with Checkboxes designed like this.in the command button i have the following code,
If CheckBox1.Value = True Then
Call autofilter
End If
similarly, I have it same for other checkboxes.
]1]1
Difficult to answer without all the exact details, but I think you are looking for something like:
In the command button _Click sub code, you should have this:
Edited : notice Dim i as String at the top.
Dim formControl As Control
Dim i As String
'loop through every control in the userform
For Each formControl In Me.Controls
'Test if the control is a checkbox
If LCase(TypeName(formControl)) = "checkbox" Then
If formControl.Value = True Then
'The below is very crude and you should find a better way of getting parameter from checkbox
'The below also assumes you use ONE filterFunction that takes a parameter
'You need to get the number from the checkbox, so take the number from the name of the checkbox
i = Right(formControl.Name, 1) - 1
'myFilterFunction i (Use this only if you have parameterised your function)
'change i to empty string if it was 0.
i = IIf(i = 0, "", i)
'This calls a function represented by the string
Application.Run "myFilterFunction" & i
End If
End If
Next formControl
At the moment, the away you've describe it, the code should work. Replace the name of the function with the name of your autofilter function....

VBA Form - Vlookup cell and assign value to that cell

Encountering an issue in a VBA regarding vlookup function.
I have 2 comboboxes and 6 Textboxs for user input.
I want to use a vlookup (or index,Match(),Match()) to look up a cell in a data table and assign the values from the textboxes to these cells.
When I run the code for what I believe should work, it is returning object errors.
Private Sub CommandButton2_Click()
Dim MonthlyTable As Range
Set MonthlyTable = Sheets("DATA Monthly").Range("A6:AE400")
Dim ColumnRef As Range
Set ColumnRef = Sheets("Drivers").Range("N11")
' Assign CB2 value to M11 cell reference so it can be converted to a column ref in N11.
Sheets("Drivers").Range("M11").Value = ComboBox2.Value
Dim CB1Value As String
CB1Value = "Joiners" & ComboBox1.Value
Dim CB2Value As String
CB2Value = ComboBox2.Value
MsgBox CB1Value & " " & CB2Value
Dim tb1value As Range
tb1value = Application.WorksheetFunction.VLookup(CB1Value, MonthlyTable, ColumnRef, False)
tb1value.Value = TextBox1.Value
Unload Me
End Sub
I am at a loss for what to do here as I feel like it should be this simple!
Thanks in advance.
Edit. Further digging indicates that you cannot select a cell you are vlookup'ing as this commands only returns a value it does not actually select the cell for my intents and purposes.
not really clear to me you actual aim, but just following up your desire as stated by:
I want to use a vlookup (or index,Match(),Match()) to look up a cell
in a data table and assign the values from the textboxes to these
cells
you may want to adopt the following technique:
Dim tb1value As Variant '<--| a variant can be assigned the result of Application.Match method and store an error to be properly cheeked for
tb1value = Application.Match(CB1Value, MonthlyTable.Column(1), 0) '<--| try finding an exact match for 'CB1Value' in the first column of your data range
If Not IsError(tblvalue) Then MonthlyTable(tb1value, columnRef.Value).Value = TextBox1.Value '<--| if successful then write 'TextBox1' value in data range cell in the same row of the found match and with `columnRef` range value as its column index
Excel uses worksheet functions to manipulate data, VBA has different tools, and when you find yourself setting cell values on a sheet via VBA so that some worksheet function can refer to them it is time to look for a true VBA solution. I suggest the following which, by the way, you might consider running on the Change event of Cbx2 instead of a command button.
Private Sub Solution_Click()
' 24 Mar 2017
Dim MonthlyTable As Range
Dim Rng As Range
Dim Lookup As String
Dim Done As Boolean
Set MonthlyTable = Sheets("DATA Monthly").Range("A2:AE400")
' take the lookup value from Cbx1
Lookup = ComboBox1.Value
Set Rng = MonthlyTable.Find(Lookup)
If Rng Is Nothing Then
MsgBox Chr(34) & Lookup & """ wasn't found.", vbInformation, "Invalid search"
Else
With ComboBox2
If .ListIndex < 0 Then
MsgBox "Please select a data type.", vbExclamation, "Missing specification"
Else
TextBox1.Value = MonthlyTable.Cells(Rng.Row, .ListIndex + 1)
Done = True
End If
End With
End If
If Done Then Unload Me
End Sub
There are two points that need explanation. First, the form doesn't close after a rejected entry. You would have to add a Cancel button to avoid an unwanted loop where the user can't leave the form until he enters something correct. Note that Done is set to True only when the search criterion was found And a value was returned, and the form isn't closed until Done = True.
Second, observe the use of the ListIndex property of Cbx2. All the items in that Cbx's dropdown are numbered from 0 and up. The ListIndex property tells which item was selected. It is -1 when no selection was made. If you list the captions of your worksheet columns in the dropdown (you might do this automatically when you initialise the form) there will be a direct relationship between the caption selected by the user (such as "Joiners") and the ListIndex. The first column of MonthlyTable will have the ListIndex 0. So you can convert the ListIndex into a column of MonthlyTable by adding 1.
I think it is better to use "find" in excell vba to select a cell instead of using vlookup or other methods.

Use VLOOKUP to pass cell reference to a public variable?

I have a userform that opens on cell change in a column.
That userform contains checkboxes, which all trigger a second userform with a text box which looks up a cell on a hidden sheet for its contents. (The checkbox that's ticked determines which cell the textbox looks for). The user then edits the box, clicks a button, and the new text is written back to the same cell.
This is the VBA for when the checkbox is ticked. It works great. Hooray!
Dim vln As Variant
Dim reta As Worksheet
Set reta = ActiveWorkbook.Sheets("RetailerActivity")
Set vln = ActiveCell.Offset(-1, -3)
UserForm2.TextBox1.Text = Application.WorksheetFunction.VLookup(vln, reta.Range("A1:Z100"), 3, False)
UserForm2.TescoSave.Visible = True
UserForm2.Show
End Sub
When the textbox has been edited, I would like to write it back to the same cell it came from. I figure the easiest way to do that is to have a public variable (as range), and to pass the result of the vlookup into that variable so the second userform can have a line which reads
Private Sub ASave_Click()
publicvariable.Value = TextBox1.Value
userform1.hide
End Sub
Nice and easy, rather than doing a VLookup again. Right?
Either way, I can't seem to set the public variable as the lookup.
Outside of any sub I have
Public bums As Range
And in the code above, after the bit where I've set the text box, I've tried to add the line
Set bums = Application.WorksheetFunction.VLookup(vln, reta.Range("A1:Z100"), 3, False)
But the code errors with a "type mismatch".
If I try
Set bums = Range(Application.WorksheetFunction.VLookup(vln, reta.Range("A1:Z100"), 3, False))
I get method "Range" of object "_global" failed.
I code by cobbling bits off the internet, as you can probably tell, so this is I don't doubt a complete kludge.
Any advice would be super appreciated.
VLookup returns a value, not a Range. You could use Match to find the row and then Cells to get the actual reference - for example:
Dim vMatch
vMatch = Application.Match(vln, reta.Range("A1:A100"),0)
If Not IsError(vMatch) then
Set bums = reta.Cells(vMatch, "C")
else
msgbox "No match for " & vln
Exit Sub
End If
Personally I would also not use a public variable, but create a property for Userform2 to which you can assign the range.

Switch off R1C1 reference style for recorded VBA macros

In recorded VBA macros, it seems that their formulas use R1C1 reference style. For instance, to fill in B4 with B2+1:
Range("B4").Select
ActiveCell.FormulaR1C1 = "=R[-2]C+1"
Does anyone know if it is possible to switch off this mode? For instance, let recorded macro look like:
Range("B4").Select
ActiveCell.Formula = "=B2+1"
I believe you cannot do that. The macro will always record in R1C1 style.
You can always switch the style but it will only be applied to the worksheet and if you record a macro it will still show R1C1 reference style.
It is very easy to understand the R1C1 style
In R1C1 reference style, the range is referred by how far the cells are located from the cell you are calling. For example, if you have 5 values from R1C1 to R5C1 and the range is called from R7C2, then the range would be R[-6]C[-1]:R[-2]C[-1]. Here the first cell in the range is 6 rows before the cell R7C2 and 1 column before the cell R7C2 and similarly for the last cell in the range.
If I take your example then "=R[-2]C+1" means that the formula is referring to a row which is two rows up (-2) and in the same column (0). Your formula is same as "=R[-2]C[0]+1"
EDIT
Here is a small function that I wrote which can help you convert R1C1 to A1 string
Sub Sample()
'~~> This will give you $B$2
Debug.Print R1C12A1("B4", "R[-2]C")
'~~> This will give you E227
Debug.Print R1C12A1("O9", "R[218]C[-10]", True)
'~~> This will give you $Y$217
Debug.Print R1C12A1("O9", "R[208]C[10]")
End Sub
Function R1C12A1(baseCell As String, sRC As String, Optional RemDollar As Boolean = False) As String
Dim MyArray() As String
Dim r As Long, c As Long
sRC = Replace(sRC, "R", "")
If Left(sRC, 1) = "C" Then
r = 0
Else
r = Replace(Replace(Split(sRC, "C")(0), "[", ""), "]", "")
End If
If Right(sRC, 1) = "C" Then
c = 0
Else
c = Replace(Replace(Split(sRC, "C")(1), "[", ""), "]", "")
End If
If RemDollar = False Then
R1C12A1 = Range(baseCell).Offset(r, c).Address
Else
R1C12A1 = Replace(Range(baseCell).Offset(r, c).Address, "$", "")
End If
End Function
Note: I have not done any error handling here. I am sure you can incorporate that if needed.
There used to be a facility to toggle relative reference when recording a macro.
When you have started recording, in the macro toolbar - near the stop button - there was a button to toggle relative reference; is this not the same as toggling R1C1 ? or isn't this available anymore?
I never bothered toggling it myself as like Siddharth says the R1C1 isn't too tricky to understand plus, irrespective of whatever you do, the VBA will need some editing so at the same time if you wish to use other syntax it's easy enough to change.
I've just played around with the following but it doesn't seem to help so maybe I'm mixing up the use of this button with R1C1...