Conditional Combo Box Multiple Column - excel

I have a problem where I want to make Combobox2's result dependent on Combobox1's result.
For example:
a 1 x
a 2 y
b 2 z
b 3 x
c 3 z
d 4 z
Here's the code:
Private Sub Combobox1_Change()
Dim wslk As Worksheet
Set wslk = Worksheets("Sheet1")
Dim i As Integer
Combobox2.Clear
For i = 2 To wslk.Range("B" & Application.Rows.Count).End(xlUp).row
If wslk.Range("B" & i).Value = Combobox1.Value Then
Combobox2.AddItem wslk.Range("A" & i).Value
'The problem starts here
Combobox2.Column(1, i - 2) = wslk.Range("C" & i).Value
Combobox2.ColumnCount = 2
End If
Next i
End Sub
So far it has been able to populate Combobox2 with result from Combobox1.
For instance, if in Combobox1 I choose "a", Combobox2 will show "1" & "2".
However, the moment I choose anything in Combobox1 other than "a" it will crash saying:
Combobox2.Column(1, i - 2) <Could not get the Column property. Invalid property...
Thanks in advance!

Try the next code, please:
Private Sub Combobox1_Change()
Dim wslk As Worksheet, cb2 As MSForms.ComboBox
Set wslk = Worksheets("Sheet1")
Set cb2 = Me.ComboBox2
Dim i As Long
cb2.Clear
For i = 2 To wslk.Range("B" & Application.Rows.count).End(xlUp).Row
If wslk.Range("B" & i).Value = ComboBox1.Value Then
With cb2
.ColumnCount = 2
.AddItem wslk.Range("A" & i).Value
'The problem starts here (not anymore...)
cb2.Column(1, cb2.ListCount - 1) = wslk.Range("C" & i).Value
End With
End If
Next i
End Sub
Your code should add the item after the last existing one (cb2.ListCount - 1)...

Related

ComboBox from filtered list

I've tried for a while to find (search) a solution to this but can't seem to.
I'm trying to read a list from an excel document, and based on the "country" item (which is selected on another combobox) filter the list. If it is the right country I want to add the row (4 items) to the combobox row.
I can't use a array because the length changes by country, and since only the second dimension of the array can be dynamic it populates the list backwards.
I currently get this error:
Assignment to constant not permitted.
The code:
Private Sub P_Country_Change()
Dim LastR As Integer
LastR = ActiveWorkbook.Worksheets("M_DB").Range("A2", Worksheets("M_DB").Range("A2").End(xlDown)).Rows.Count
Dim j As Integer
j = 0
For i = 2 To LastR
If ActiveWorkbook.Worksheets("M_DB").Range("E" & i).Value = P_Country.Value Then
With Press_m
.AddItem = ActiveWorkbook.Worksheets("M_DB").Range("A" & i).Value
.List(j, 1) = ActiveWorkbook.Worksheets("M_DB").Range("B" & i).Value
.List(j, 2) = ActiveWorkbook.Worksheets("M_DB").Range("C" & i).Value
.List(j, 3) = ActiveWorkbook.Worksheets("M_DB").Range("D" & i).Value
End With
j = j + 1
End If
Next i
End Sub
Thanks for your help!
Ok, so I made it work. I'm not sure exactly what I did right, but to help anyone else using this as a referenace, one thing I did that may have been it was set the properties of the combobox to:
locked = False
Also I changed the code a little bit, but not so much, here it is now:
Private Sub P_Country_Change()
Dim LastR As Integer
LastR = ActiveWorkbook.Worksheets("M_DB").Range("A2", Worksheets("M_DB").Range("A2").End(xlDown)).Rows.Count
Dim j As Integer
j = 0
For s = P_m.ListCount - 1 To 0 Step -1
P_m.RemoveItem s
Next s
With P_m
.ColumnCount = 4
.ColumnWidths = "125;125;125;125"
.ColumnHeads = False
End With
For i = 2 To LastR
If ActiveWorkbook.Worksheets("M_DB").Range("E" & i).Value = Press_Country.Value Then
P_m.AddItem ActiveWorkbook.Worksheets("M_DB").Range("B" & i).Value ' Name
P_m.List(j, 1) = ActiveWorkbook.Worksheets("M_DB").Range("C" & i).Value ' Corporation
P_m.List(j, 2) = ActiveWorkbook.Worksheets("M_DB").Range("D" & i).Value ' Province
P_m.List(j, 3) = ActiveWorkbook.Worksheets("M_DB").Range("E" & i).Value ' City
j = j + 1
End If
Next i
End Sub
Finally, I found a great referance here. teach me right? RTFM first ;-)

Use a TextBox to filter a Listbox Script problem

I have a UserForm intarface with a listbox with 20 column and a text box, I need tanta when I type in a text box the word is searched in every column and row and the result of row are displayed in listbox1. I have put this code but when I add a second column script it doesn’t work yet.
In a nutshell:
I need to find the result of a keyword put in the text box1 in 20 column and put the result in a listbox1
Many thanks
Private Sub Textbox1_Change()
Dim o As Long
Dim arrList As Variant
Me.ListBox1.Clear
If Worksheets(“Sheet1”).Range("A" & Worksheets(“Sheet1”). Rows.Count).End(xlUp).Row > 1 And Trim(Me.TextBox1.Value) <> vbNullString Then arrList = Worksheets(“Sheet1”). Range("A1:A" & Worksheets(“Sheet1”).Range("A" & Worksheets(“Sheet1”).Rows.Count).End(xlUp).Row).Value2
If Worksheets(“Sheet1”).Range("B" & Worksheets(“Sheet1”). Rows.Count).End(xlUp).Row > 1 And Trim(Me.TextBox1.Value) <> vbNullString Then arrList = Worksheets(“Sheet1”). Range("B1:" & Worksheets(“Sheet1”).Range("A" & Worksheets(“Sheet1”).Rows.Count).End(xlUp).Row).Value2
For o = LBound(arrList) To UBound(arrList)
If InStr(1, arrList(o, 1), Trim(Me.TextBox1.Value), vbTextCompare) Then
Me.ListBox1.AddItem arrList(o, 1)
End If
Next o
End If
If Me.ListBox1.ListCount = 1 Then Me.ListBox1.Selected(0) = True
End Sub

Autofill combobox from userform

I am new to VBA and my problem that I'm struggling with is to autofill a combobox in my form.
For example, my combobox has listed these values:
"apple", "tree", "juice"
I'm asking how to make it search through my list and when I write "app" to provide me with the "apple" result.
This is my code:
Private Sub ComboBox3_Change()
If Me.ComboBox3.Value <> "" Then
Dim sh As Worksheet
Set sh = ThisWorkbook.Sheets("11")
Set ph = ThisWorkbook.Sheets("22")
Dim i As String
i = Application.Match((Me.ComboBox3.Value), sh.Range("A:A"), 0)
Me.TextBox8.Value = ph.Range("D" & i).Value
Me.TextBox13.Value = ph.Range("P" & i).Value
Me.TextBox41.Value = ph.Range("B" & i).Value
End If
End Sub
Private Sub UserForm_Activate()
Dim i As Integer
Me.ComboBox3.Clear
Me.ComboBox3.AddItem ""
For i = 2 To sh.Range("A" & Application.Rows.Count).End(xlUp).Row
Me.ComboBox3.AddItem sh.Range("A" & i).Value
Next i
I cannot reproduce your issue. I made a ComboBox with the items as shown below:
If I start typing App it looks like below, where it selected Apple automatically
So it does exactly what you are asking for by default.

Run time Error 91 object variable or with block variable not set when showing userform

I have problem with closing one userform and going to next. UserForm3 after clicking command button should be closed and UserForm4 should be shown. Unfortunately I get "Run time Error 91 object variable or with block variable not set". I've dug deep into internet and I am pretty sure that problem is with Userform4, although code for UserForm3 is highlighted as bugged. Basicly I want UserForm4 to be displayed and have all the textboxes filled with data from sheet "Log", based on choice from Combobox from UserForm3. Choice from UserForm3 is saved to cell E1 on "Log" Sheet.
Code from UserForm3
Private Sub CommandButton1_Click()
Sheets("Log").Range("E1") = ComboBox2.Text
Unload Me
UserForm4.Show <- ERROR DISPLAYED HERE
End Sub
In UserForm4 I want to find value from E1 in cells below and later on fill textboxes in Userform4 with data from the row, in which E1 value was found.
Code for UserForm4
Private Sub UserForm_Initialize()
Dim Name As String
Dim rng As Range
Dim LastRow As Long
Dim wart As Worksheet
wart = Sheets("Log").Range("E1")
LastRow = ws.Range("B3" & Rows.Count).End(xlUp).Row + 1
Name = Sheets("Log").Range("E1")
UserForm4.TextBox8.Text = Name
nazw = Application.WorksheetFunction.VLookup(wart, Sheets("Log").Range("B3:H" & LastRow), 1, False)
UserForm4.TextBox1.Text = ActiveCell.Offset(, 1)
UserForm4.TextBox2.Text = ActiveCell.Offset(, 1)
UserForm4.TextBox3.Text = ActiveCell.Offset(, 1)
UserForm4.TextBox4.Text = ActiveCell.Offset(, 1)
UserForm4.TextBox5.Text = ActiveCell.Offset(, 1)
UserForm4.ComboBox1.Text = ActiveCell.Offset(, 1)
UserForm4.TextBox6.Text = ActiveCell.Offset(, 1)
UserForm4.TextBox7.Text = ActiveCell.Offset(, 1)
End Sub
The code below is to avoid to run-time errors mentioned in the code above, it's not debugged for the VLookup function part.
Option Explicit
Private Sub UserForm_Initialize()
Dim Name As String
Dim LastRow As Long
Dim wart As Variant
Dim ws As Worksheet
Dim nazw As Long
' set ws to "Log" sheets
Set ws = Sheets("Log")
With ws
wart = .Range("E1")
' method 1: find last row in Column "B" , finds last row even if there empty rows in the middle
LastRow = .Cells(.Rows.Count, "B").End(xlUp).Row + 1
' method 2 to find last row, equivalent to Ctrl + Shift + Down
' LastRow = .Range("B3").CurrentRegion.Rows.Count + 1
' a little redundant with the line 2 above ?
Name = .Range("E1")
End With
With Me
.TextBox8.Text = Name
' ****** Need to use Match instead of Vlookup VLookup Section ******
If Not IsError(Application.Match(wart, ws.Range("B1:B" & LastRow - 1), 0)) Then
nazw = Application.Match(wart, ws.Range("B1:B" & LastRow - 1), 0)
Else ' wart record not found in range
MsgBox "Value in Sheet " & ws.Name & " in Range E1 not found in Column B !", vbInformation
Exit Sub
End If
.TextBox1.Text = ws.Range("B" & nazw).Offset(, 1)
.TextBox2.Text = ws.Range("B" & nazw).Offset(, 1)
.TextBox3.Text = ws.Range("B" & nazw).Offset(, 1)
.TextBox4.Text = ws.Range("B" & nazw).Offset(, 1)
.TextBox5.Text = ws.Range("B" & nazw).Offset(, 1)
.ComboBox1.Text = ws.Range("B" & nazw).Offset(, 1)
.TextBox6.Text = ws.Range("B" & nazw).Offset(, 1)
.TextBox7.Text = ws.Range("B" & nazw).Offset(, 1)
End With
End Sub

copying rows with checked checkboxes

I would like to consolidate rows with checked checkboxes from three sheets (“Liver”, ”Lung” and “Kidney”) into one sheet "Report". I would like to grab rows that do not contain word "sample" in column A. When I paste the data into "Report" I would like to label each group of rows with the corresponding originating sheet name by adding a row in between that contains the sheet name, in column A.
I came up with this code which goes into an infinite loop and I have to kill Excel to stop it. This is just for "Lung" sheet only but I'm hoping to reproduce it for the other two sheets.
Ideally, I would like to use arrays to transfer the data but I'm not sure how to work it out. Any suggestions on how to fix what I already have or to improve it would be greatly appreciated.
Thank you
For Each chkbx In ActiveSheet.CheckBoxes
If chkbx.Value = 1 Then
For r = 2 To Rows.count
If Cells(r, 1).Top = chkbx.Top And InStr(Cells(r, 1).Value, "Sample") < 0 Then
'
With Worksheets("Report")
LRow = .Range("A" & Rows.count).End(xlUp).Row + 1
.Range("A" & LRow & ":P" & LRow) = _
Worksheets("Lung").Range("A" & r & ":P" & r).Value
End With
Exit For
End If
Next r
End If
Next
The code bellow will generate the following reports (details bellow):
.
There are 3 sections, but all code should be pasted into one user module:
.
Subs to execute:
Option Explicit
Private Const REPORT As String = "Report_"
Private Const EXCLUDE As String = "Sample"
Private Const L_COL As String = "P"
Private wsRep As Worksheet
Private lRowR As Long
Public Sub updateSet1()
updateSet 1
End Sub
Public Sub updateSet2()
updateSet 2
End Sub
Public Sub updateSet3()
updateSet 3
End Sub
Public Sub updateSet(ByVal id As Byte)
Application.ScreenUpdating = False
showSet id
Application.ScreenUpdating = True
End Sub
Public Sub consolidateAllSheets()
Application.ScreenUpdating = False
With ThisWorkbook
consolidateReport .Worksheets("COLON"), True 'time stamp to 1st line of report
consolidateReport .Worksheets("LUNG")
consolidateReport .Worksheets("MELANOMA")
wsRep.Rows(lRowR).Borders(xlEdgeBottom).LineStyle = xlContinuous
End With
Application.ScreenUpdating = True
End Sub
.
showSet() - use 1 for Set1, 2 for Set2, 3 for Set2 edited:
Public Sub showSet(ByVal id As Byte)
Dim ws As Worksheet, cb As Shape, lft As Double, mid As Double, thisWs As Worksheet
Dim lRed As Long, lBlu As Long, cn As String, cbo As Object, s1 As Boolean
If id <> 1 And id <> 2 And id <> 3 Then Exit Sub
lRed = RGB(255, 155, 155): lBlu = RGB(155, 155, 255)
Set thisWs = ThisWorkbook.ActiveSheet
For Each ws In ThisWorkbook.Worksheets
If InStr(1, ws.Name, REPORT, vbTextCompare) = 0 Then
lft = ws.Cells(1, 2).Left
mid = lft + ((ws.Cells(1, 2).Width / 2) - 5)
For Each cb In ws.Shapes
cn = cb.Name
Set cbo = cb.OLEFormat.Object
s1 = InStr(1, cn, "set1", 1) > 0
If id < 3 Then
cb.Visible = IIf(s1, (id = 1), (id <> 1))
cb.Left = IIf(cb.Visible, mid, lft)
cbo.Interior.Color = IIf(s1, lBlu, lRed)
Else
cb.Visible = True
cb.Left = IIf(s1, lft + 3, mid + 6.5)
cbo.Interior.Color = IIf(s1, lBlu, lRed)
End If: ws.Activate
With cbo
.Width = 15
.Height = 15
End With
Next
Else
ws.Visible = IIf((id = 3), -1, IIf(InStr(1, ws.Name, id) = 0, 0, -1))
End If
Next
thisWs.Activate 'to properly update checkbox visibility
End Sub
.
consolidateReport()
Public Sub consolidateReport(ByRef ws As Worksheet, Optional dt As Boolean = False)
Dim fRowR As Long, vSetID As Byte, vSetName As String
Dim lRow As Long, thisRow As Long, cb As Variant
vSetID = IIf(ws.Shapes("cbSet2_03").Visible, 2, 1)
vSetName = "Set" & vSetID
Set wsRep = ThisWorkbook.Worksheets(REPORT & vSetID)
fRowR = wsRep.Range("A" & wsRep.Rows.count).End(xlUp).Row
If Not ws Is Nothing Then
With ws
lRow = .Range("A" & .Rows.count).End(xlUp).Row
lRowR = fRowR + 1
With wsRep.Cells(lRowR, 1)
.Value2 = ws.name
.Interior.Color = vbYellow
If dt Then .Offset(0, 2) = Format(Now, "mmm dd yyyy, hh:mm AMPM")
End With
For Each cb In .Shapes
If InStr(1, cb.name, vSetName, 0) Then
If cb.OLEFormat.Object.Value = 1 Then
thisRow = cb.TopLeftCell.Row
If InStr(1, .Cells(thisRow, 1).Value2, EXCLUDE, 1) = 0 Then
lRowR = lRowR + 1
wsRep.Range("A" & lRowR & ":" & L_COL & lRowR).Value2 = _
.Range("A" & thisRow & ":" & L_COL & thisRow).Value2
End If
End If
End If
Next
If fRowR = lRowR - 1 Then
wsRep.Cells(lRowR, 1).EntireRow.Delete
lRowR = lRowR - 1
MsgBox "No checkboxes checked for sheet " & ws.name
End If
End With
End If
End Sub
.
The process starts with one file, expected to have 2 sets of checkboxes on each sheet (column 2):
cbSet1_01, cbSet1_02, cbSet1_03...
cbSet2_01, cbSet2_02, cbSet2_03...
as in this image
(check-box colors will be reset by code as long as they follow the naming convention above)
.
Generate two files, one for Set1, the other for Set2 by running Sub updateSet()
showSet 1 hides Set2 (Report_2 and all checkboxes, on all sheets) - Save File1
showSet 2 hides Set1 (Report_1 and all checkboxes, on all sheets) - Save File2
Distribute, then retrieve the updated files
Open File1 and run Sub consolidateAllSheets() to generate Report_1
Open File2 and run Sub consolidateAllSheets() to generate Report_2
Compare Report_1 to Report_2
Generate Set 2 for editing by running Sub updateSet()
showSet 3 shows Set1 and Set2 (all checkboxes, and both reports) - Save File3
Compare File1, File2, and File3

Resources