Change list in ComboBox2 based on selected value in ComboBox1 - vba

I have the following Excel spreadsheet:
A B
1 Filter Selected 1 Filter Selected 2
2 Product A
3
4 List of ComboBox1 List of ComboBox2
5 Product A Brand A =IF($A$2=$A$5,"Brand A","Brand B")
6 Product B Brand A =IF($A$2=$A$5,"Brand A","Brand B")
7 Product C Brand A =IF($A$2=$A$5,"Brand A","Brand B")
8
In range A5:A7 you can find a list that I use in the the ComboBox1 within a UserForm. In range B5:B7 you can find a list that I use in the ComboBox2 within the UserForm. Once the user selects a value in one of the ComboBoxes it gets typed into either cell A2 or cell B2.
As you can see for the list of ComboBox2 I use an IF-Condition based on the selections of ComboBox1 so if the user selects Product A in CombobBox1 the list in range B5:B7 will be changed to Brand A.
However, this change is not immediately transferred to the ComboBox2 so instead of Brand A it is still showing Brand B unless I re-open the UserForm.
The code for my UserForm is:
Sub UserForm_Activate()
ComboBox1.List = Sheet1.Range("A5:A7").Value
ComboBox2.List = Sheet1.Range("B5:B7").Value
ComboBox1.Value = Sheet1.Range("A2")
ComboBox2.Value = Sheet1.Range("B2")
End Sub
Sub ComboBox1_Change()
Sheet1.Range("A2").Value = ComboBox1.Value
End Sub
Sub ComboBox2_Change()
Sheet1.Range("B2").Value = ComboBox2.Value
End Sub
Sub UserForm_Close()
Unload UserForm1
End Sub
What do I have to change in this code so the list in ComboBox2 is immediately updated after a value is selected in ComboBox1?

In the ComboBox1_Change event try to calculate the sheet to make sure the values in the formulas are updated before you reload the list in ComboBox2.
Sub ComboBox1_Change()
Sheet1.Range("A2").Value = ComboBox1.Value
Sheet1.Calculate 'update formula values
ComboBox2.List = Sheet1.Range("B5:B7").Value 'reload the values into the list
End Sub

Related

Save combobox value as global variable and select row of selected value

I want to save selected combobox value as global variable and select row of selected value.
I have an Excel file, where I want to make calculations based on inputs in sheet1 and data on sheet2.
Inputs are provided by combobox1 (list of names from column A in sheet 2), combobox2 (case yes/no) and combobox3 (values 1,2,3).
After I select value in combobox1 (for example: ABC which is value A7 from sheet2), I want to calculate from data in row 7 in sheet2:
B7 (sheet2) + C7 (sheet2) * combobox3 value + D7 (sheet2) * (combobox2(yes = 2 / no = 0).
Can anyone help me with that?
Public SelectedComboBox1 As String
Public SelectedComboBox2 As String
Public SelectedComboBox3 As integer
Public calculate2 As Integer
Private Sub ComboBox1_DropButtonClick()
Sheet1.ComboBox1.List = Sheet2.Range("A3:A46").Value
SelectedComboBox1 = Me.ComboBox1.Value
End Sub
Private Sub ComboBox2_DropButton()
With Me.ComboBox2
.AddItem "YES"
.AddItem "NO"
End With
SelectedComboBox2 = Me.ComboBox2.Value
End Sub
Private Sub ComboBox3_DropButton()
With Me.ComboBox3
.AddItem "1"
.AddItem "2"
.AddItem "3"
End With
SelectedComboBox3 = Me.ComboBox3.Value
End Sub
Public Sub Calculate2_click()
calculate2 = Sheet2.Range("B7") * Sheet2.Range("C7") * SelectedComboBox3+Sheet2.Range("D7")*??
Sheet1.Range("H10").Value = calculate2
End Sub
It seems like you added a ActiveX combobox. You might want to use a form-combobox instead for Excel Sheets. Nevertheless: in the Editor you can add varioous actions to events in the combobox. What you did is add a reaction to the button-down-click Event. There you told excel to fill the list and set the SelectedCombobox variable to the - as of yet undefined - value of the combobox.
What you might want is one sub to fill the list as you did and another sub reacting to the change event of the combobox. That sub will be called as soon as someone changes the value of the box:
Private Sub ComboBox1_DropButtonClick()
Sheet1.ComboBox1.List = Sheet2.Range("A3:A46").Value
End Sub
Private Sub ComboBox1_Change()
SelectedComboBox1 = Me.ComboBox1.Value
End Sub
This should get you a good start. There are plenty of resources out-there that teach you how to write effective macros in Excel.
If you just need a result that uses the value of these three comboboxes, you could also connect a simple form-comboboxes with respective cells and claculate the result out of those cells.
But if you still want to use vba, think about using just one button to trigger a sub and access the values immediately:
Private Sub Button1_click
cells("A1").value=Me.ComboBox1.Value * Me.ComboBox2.Value...
End Sub

Run time error 424 Object Required working with UserForm

I'm trying to link a user form I built in VBA editor for MS Excel 2010 to the data in an excel worksheet, but I'm getting a
run-time error 424: Object required.
I referred to the active worksheet explicitly in my code to try and remedy this, but it still comes up with the same error. My code is:
Private Sub GetData()
Dim r As Long
r = ActiveSheet.Range("B2").Value
If IsNumeric(RowNumber.Text) Then
r = CLng(RowNumber.Text)
Else
ClearData
MsgBox "Invalid row number"
Exit Sub
End If
If r > 1 And r <= LastRow Then
cboFilterResultId.Text = FormatNumber(Cells(r, 1), 0)
txtFolderPaths.Text = Cells(r, 2)
txtFileName.Text = Cells(r, 3)
txtDeletedDate.Text = Cells(r, 4)
txtReason.Text = Cells(r, 5)
txtcboAdd.Text = Cells(r, 6)
txtcboView.Text = Cells(r, 7)
txtcboChange.Text = Cells(r, 8)
DisableSave
ElseIf r = 1 Then
ClearData
Else
ClearData
MsgBox "Invalid row number"
End If
End Sub
Where RowNumber is a textbox where the user can enter the row number for the data they want.
Please help!
I rarely use ActiveSheet just in case that isn't the sheet I'm after. Generally better to be explicit which sheet you're referring to:
r=ThisWorkbook.WorkSheets("Sheet1").Range("B2")
Right, pulling data from a worksheet to a userform... as you haven't said which line your error occurs on and you haven't given us the code for ClearData or DisableSave I'll start from scratch.
Example Form Design
I create a blank userform and add three text boxes and a spin button to it:
txtRowNumber holds the row number that the data is pulled from.
TextBox1 and TextBox2 will hold my sample values.
In the Tag property of TextBox1 I enter 1 and in the Tag property of TextBox2 I enter 2. These are the column numbers that the data will be pulled from.
In reality I usually add extra stuff, for example, 8;CPER;REQD. I'd then use some code to pull it apart so it pastes in column 8, must have a percentage and is a required entry.
spnButton is used to quickly move up or down a row.
We'll need two procedures to populate the form from the given row number and to clear all controls on the form (ready for the next row to be brought in).
Any textbox or combobox that has something in it's Tag property is cleared:
Private Sub ClearForm()
Dim frmCtrl As Control
For Each frmCtrl In Me.Controls
If frmCtrl.Tag <> "" Then
Select Case TypeName(frmCtrl)
Case "TextBox", "ComboBox"
frmCtrl.Value = Null
Case Else
'Do nothing.
End Select
End If
Next frmCtrl
End Sub
Any control that has a Tag value (it's assumed the value is correct) is populated from the specified RowNumber and column (from the Tag value). The value is always taken from the sheet called MyDataSheet in the workbook containing the VBA code (ThisWorkbook) no matter which is currently active:
Private Sub PopulateForm(RowNumber As Long)
Dim frmCtrl As Control
For Each frmCtrl In Me.Controls
With frmCtrl
If .Tag <> "" Then
.Value = ThisWorkbook.Worksheets("MyDataSheet").Cells(RowNumber, CLng(.Tag))
End If
End With
Next frmCtrl
End Sub
Whenever txtRowNumber changes the form should update with values from the indicated row. To do this we'll need to clear the form of current data and then repopulate it:
Private Sub txtRowNumber_Change()
ClearForm
PopulateForm CLng(Me.txtRowNumber)
End Sub
The spin button should increase/decrease the value in .txtRowNumber. I've added checks that it doesn't go below 1. You should also add checks that it doesn't go higher than the last populated row.
Private Sub spnButton_SpinDown()
With Me
.txtRowNumber = CLng(.txtRowNumber) + 1
End With
End Sub
Private Sub spnButton_SpinUp()
With Me
If CLng(.txtRowNumber) > 1 Then
.txtRowNumber = CLng(.txtRowNumber) - 1
End If
End With
End Sub
Finally, the form should be populated when it is first opened:
Private Sub UserForm_Initialize()
With Me
.txtRowNumber = 2
.spnButton = .txtRowNumber
PopulateForm .txtRowNumber
End With
End Sub

Excel VBA: Accessing the individual fields in a selected ListBox row

I am trying to access the individual cells in a selected/highlighted ListBox "lstData" row so I can reference their values elsewhere.
When I set a watch for Me.lstData.SelectedItem, I get Expression not defined in context. Same with Me.lstData.SelectedIndex and Me.lstData.Rows(1). The only thing that kind of works for me is Me.lstData.Value, but it ONLY returns the leftmost cell. When I try to plug it into the =OFFSET function
=Offset(Me.lstData.Value, ,1,1)
to access the cell immediately to the right, I get Expression not defined in context again.
How can I reference the other selected cells?
I don't think you can use Offset on a ListBox form control. The way to reference a 'cell' in a multi-column ListBox is by indexing the List property.
Here, i returns the row of the selected item, and 1 represents the second column (base 0) of the listbox:
Option Explicit
Private Sub CommandButton1_Click()
Dim i As Long
With Me.ListBox1
i = .ListIndex
MsgBox .List(i, 1)
End With
End Sub
Private Sub UserForm_Initialize()
With Me.ListBox1
.AddItem "A"
.List(0, 1) = "Alpha"
.AddItem "B"
.List(1, 1) = "Beta"
End With
End Sub

Listbox Modification in VBA

I created a Userform in Word which imports 3 columns of data from an excel sheet, inserts it into bookmarks and in the name of the word document and saves it as a pdf.
Now I wanted to add a Listbox into the form to be able to add, modify and delete the inputs manually which are usually imported from the excel sheet .
I already figured out how to add data from 3 textboxes into a 3 Column Listbox but even after googling for hours I can't find a good way to modify selected data.
VB.net has the .selectedItem property, VBA does not. Can anybody give me an example how to modify a multi column listbox with the values of 3 textboxes?
Thanks in advance
You need to iterate through ListBox.Selected and check if it is True. Once you get a True one, you can process that item.
Sample code adds some items with columns and sets up a click event to run through the Selected items.
Private Sub ListBox1_Click()
Dim i As Integer
For i = 0 To ListBox1.ListCount - 1
If ListBox1.Selected(i) Then
Debug.Print ListBox1.List(i, 0)
End If
Next i
End Sub
Private Sub UserForm_Initialize()
ListBox1.AddItem "test"
ListBox1.AddItem "test1"
ListBox1.AddItem "test2"
ListBox1.ColumnCount = 3
ListBox1.ColumnHeads = True
ListBox1.List(1, 0) = "change to 1,0"
ListBox1.List(1, 1) = "change to 1,1"
ListBox1.List(1, 2) = "change to 1,2"
End Sub
Picture of form with Immediate window after clicking each item in turn.

Select a option from a filtered cell

I am new in VBA so i am unable to do this.
I have 21 sheets in a workbook. I want to select a cell in 3rd sheet (which contains a Pivot Table) which I am able to do. This cell B3 contains a filter and I can select from the filtered drop menu on how to sort my data. It contains whether I want to filter by first name OR last name OR all.
My usual routine is first to select by first name, then copy the filtered data and paste it on another sheet. Then come back to the same sheet and filter by last name and then copy the filtered data and paste it on the sheet I pasted the earlier data.
What I need help with is the following:
If any or all check boxes are selected then deselect them.
Select the first_name checkbox in the filter drop down
De-select the first_name box and select the last_name box
Finally deselect last_name and then select all checkbox
I have used the following code
Public Sub Open_Sheet3()
Workbooks("MASTER.xlsx").Activate
ActiveWorkbook.Sheets("Sheet3").Activate
ActiveSheet.PivotTables("PivotTable1").PivotFields("Technology").CurrentPage = _
"(All)"
With ActiveSheet.PivotTables("PivotTable1").PivotFields("Technology")
.PivotItems("Mobility").Visible = False
.PivotItems("(blank)").Visible = False
.PivotItems("Enterprise Messaging Tech").Visible = False
End With
End Sub
This code should do what you want. Just replace the names of worksheet/pivot table/pivot field and fill in the copyStuff sub.
Private Sub YourProcedure()
SelectItem "first_name"
CopyStuff
SelectItem "last_name"
CopyStuff
SelectItem "all" 'in case you have an element called "all"
CopyStuff
SelectAll 'In case you mean the "(All)" 'element', i.e. include everything
CopyStuff
End Sub
Private Sub SelectItem(strItemName As String)
Dim i As Integer
'Change to your worksheet/pivot talbe/pivot field name!
With Worksheets("Sheet 1").PivotTables("PivotTable1").PivotFields("a")
.PivotItems(1).Visible = True 'at least one item always needs to be visible
For i = 2 To .PivotItems.Count
.PivotItems(i).Visible = False
Next
.PivotItems(strItemName).Visible = True
If .PivotItems(1).Name <> strItemName Then .PivotItems(1).Visible = False
End With
End Sub
Private Sub SelectAll()
Dim i As Integer
'Change to your worksheet/pivot talbe/pivot field name!
With Worksheets("Sheet 1").PivotTables("PivotTable1").PivotFields("a")
For i = 1 To .PivotItems.Count
.PivotItems(i).Visible = True
Next
End With
End Sub
Private Sub CopyStuff()
'Your code goes here
End Sub
Some explanation:
If you want to deselect items of a pivot field, you need to make sure that there's at least on item selected at any time. Therefore you cannot unselect all and then select your desired item - but rather select the first item, unselect all other, select your item and unselect the first item unless it is your item. That's what SelectItem is doing