Creating a Multi Selection Checkbox List in Side-by-Side Cell Across Row in Excel - excel

I'm using VB code created by L42 on 4/27/14 that creates a checkbox list in a single cell.
Option Explicit
Dim fillRng As Range
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim LBColors As MSForms.ListBox
Dim LBobj As OLEObject
Dim i As Long
Set LBobj=Me.OLEObjects("LB_Colors")
Set LBColors = Target
If Not Intersect(Target, [B2]) Is Nothing Then
Set fillRng = Target
With LBobj
.Left = fillRng.Left
.Top = fillRng.Top
.Width = fillRng.Width
.Visible = True
End With
Else
LBobj.Visible = False
If Not fillRng Is Nothing Then
fillRng.ClearContents
With LBColors
If .ListCount <> 0 Then
For i = 0 To .ListCount -1
If fillRng.Value = Then
If .Selected(i) Then fillRng.Value = .List(i)
Else
If .Selected(i) Then fillRng.Value = _
fillRng.Value & "," & .List(i)
End If
Next
End With
Set fillRng = Nothing
End If
End If
End Sub
The code works perfectly and I was able to extend the checkbox list to the cells in complete column by changing the (Target, [B1:B40]). Following this logic, I thought that I could extend checkboxes C and D columns by (Target, [B1:D40]. However, after selecting desired items in B column and clicking or tabing over to C column, the entire checkbox moves with selected items without writing in the previous cell. I would like to be able to tab over or click to the next cell in the row and have same checkbox items that populates that cell with item selected, independent of the previous cell. Then tab or click to succeeding cells and do the same and have cells retain and display selected the items. Can this code be modified to do that?
Thank you.

to always put the values in the cell, just change your code to something like this:
Option Explicit
Dim fillRng As Range
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim LBColors As MSForms.ListBox
Dim LBobj As OLEObject
Dim i As Long
Set LBobj = Me.OLEObjects("LB_Colors")
Set LBColors = Target
LBobj.Visible = False
If Not fillRng Is Nothing Then
fillRng.ClearContents
With LBColors
If .ListCount <> 0 Then
For i = 0 To .ListCount - 1
If .Selected(i) Then
If fillRng.Value = "" Then
fillRng.Value = .List(i)
Else
fillRng.Value = fillRng.Value & "," & .List(i)
End If
End If
Next
End If
End With
Set fillRng = Nothing
End If
If Not Intersect(Target, [B1:D40]) Is Nothing Then
Set fillRng = Target
With LBobj
.Left = fillRng.Left
.Top = fillRng.Top
.Width = fillRng.Width
.Visible = True
End With
End If
End Sub

Related

Delete checkbox from a Specific Cell with VBA

I'm putting together a spreadsheet that should populate checkboxes in a specific column when the spreadsheet opens if the appropriate A Column/Row is not empty. It should also remove checkboxes when it finds that same A column to be empty. My VB is correctly creating the checkboxes, but I cannot figure out how to tell the code to delete the checkbox from a specific cell.
Most articles I find mention removed ALL checkboxes, but I'm looking to do it conditionally. Any guidance would be greatly appreciated.
Private Sub Workbook_Open()
'declare a variable
Dim ws As Worksheet
Set ws = Worksheets("Sheet1")
'calculate if a cell is not blank across a range of cells with a For Loop
For x = 2 To 1000
If ws.Cells(x, 1) <> "" Then
Call Add_CheckBox(CInt(x))
Else
Call Delete_CheckBox(CInt(x))
End If
Next x
End Sub
Private Sub Add_CheckBox(Row As Integer)
ActiveSheet.CheckBoxes.Add(Cells(Row, "T").Left, Cells(Row, "T").Top, 72, 12.75).Select
With Selection
.Caption = ""
.Value = xlOff '
.LinkedCell = "AA" & Row
.Display3DShading = False
End With
End Sub
Private Sub Delete_CheckBox(Row As Integer)
Dim cb As CheckBox
If cb.TopLeftCell.Address = (Row, "T") Then cb.Delete
End Sub
Naming the CheckBoxes will make it easier to maintain your code.
Private Sub Workbook_Open()
Const CheckBoxPrefix As String = "Sheet1TColumnCheckBox"
'declare a variable
Dim CheckBoxName As String
Dim ws As Worksheet
Set ws = Worksheets("Sheet1")
'calculate if a cell is not blank across a range of cells with a For Loop
Dim r As Long
For r = 2 To 1000
CheckBoxName = CheckBoxPrefix & r
If Len(ws.Cells(r, 1)) > 0 Then
If Not WorksheetContainsCheckBox(CheckBoxName, ws) Then Add_CheckBox CheckBoxName, ws.Cells(r, 1), ws.Cells(r, "AA")
Else
If WorksheetContainsCheckBox(CheckBoxName, ws) Then ws.CheckBoxes(CheckBoxName).Delete
End If
Next
End Sub
Private Sub Add_CheckBox(CheckBoxName As String, Cell As Range, LinkedCell As Range)
With Cell.Worksheet.CheckBoxes.Add(Cell.Left, Cell.Top, 72, 12.75)
.Caption = ""
.Value = xlOff '
.LinkedCell = LinkedCell
.Display3DShading = False
.Name = CheckBoxName
End With
End Sub
Function WorksheetContainsCheckBox(CheckBoxName As String, ws As Worksheet)
Dim CheckBox As Object
On Error Resume Next
Set CheckBox = ws.CheckBoxes(CheckBoxName)
WorksheetContainsCheckBox = Err.Number = 0
On Error GoTo 0
End Function
Try something like this (put a checkbox "in" A1 but not C1)
Sub tester()
Debug.Print Delete_CheckBox([A1])
Debug.Print Delete_CheckBox([C1])
End Sub
'Return True if able to delete a checkbox from range `rng`
Private Function Delete_CheckBox(rng As Range) As Boolean
Dim cb As CheckBox
For Each cb In rng.Worksheet.CheckBoxes
If Not Application.Intersect(cb.TopLeftCell, rng) Is Nothing Then
Debug.Print "Deleting checkbox in " & cb.TopLeftCell.Address
cb.Delete
Delete_CheckBox = True
Exit For 'if only expecting one matched checkbox
End If
Next cb
End Function

VBA how to Create Multi Select ListBoxes in qualifying cells

I am trying to achieve code where multi-select ListBoxes are added if Column 4 or 5 are selected and Column 2 in the same row has the string "has options".
The Listboxes contain values from named ranges called "option1" and "option2". Current Selections are output to the respective cell in Column 4 or 5 separated by commas.
This is the code I have in "This Workbook" object. It needs to work on all sheets.
Private Sub Workbook_SheetSelectionChange(ByVal Sh As Object, ByVal Target As Range)
If Target.Cells.Count > 1 Then Exit Sub
If Target.Column = 4 And Target.OFFSET(0, -1).Value = "has options" Then
CreateOpt1PopUp Target
End If
If Target.Column = 5 And Target.OFFSET(0, -2).Value = "has options" Then
CreateOpt2PopUp Target
End If
Else
DeleteAllOpt1PopUps Target
DeleteAllOpt2PopUps Target
End If
End If
End Sub
This is the code I have in a Module. The criteria has evolved and therefore I have amended the code multiple times to the point where it no longer works.
Private opt1SelectCell As Range
Public Function Opt1Area(ByRef ws As Worksheet) As Range
Const OPT1_COL As Long = 4
Dim lastOpt1Row As Long
With ws
lastOpt1Row = .Cells(.Rows.Count, 1).End(xlUp).Row - 1
If lastOpt1Row = 0 Then
Set Opt1Area = Nothing
Else
Set Opt1Area = .Cells(2, OPT1_COL).Resize(lastOpt1Row, 1)
End If
End With
End Function
Public Sub Opt1BoxClick()
Dim opt1BoxName As String
opt1BoxName = Application.Caller
Dim opt1Box As ListBox
Set opt1Box = ActiveSheet.ListBoxes(opt1BoxName)
Dim opt1List As String
Dim i As Long
For i = 1 To opt1Box.ListCount
If opt1Box.Selected(i) Then
opt1List = opt1List & opt1Box.List(i) & ","
End If
Next i
If Len(opt1List) > 0 Then
opt1List = Left$(opt1List, Len(opt1List) - 1)
End If
opt1SelectCell.Value = opt1List
End Sub
Public Function Opt1ListArea() As Range
Set Opt1ListArea = ActiveSheet.Range("option1")
End Function
Public Sub DeleteAllOpt1PopUps(ByRef selectedCell As Range)
Dim opt1Box As ListBox
For Each opt1Box In selectedCell.Parent.ListBoxes
opt1Box.Delete
Next opt1Box
End Sub
Public Sub CreateOpt1PopUp(ByRef selectedCell As Range)
Set opt1SelectCell = selectedCell
Dim Opt1PopUpCell As Range
Set Opt1PopUpCell = opt1SelectCell.OFFSET(1, 0)
DeleteAllOpt1PopUps selectedCell
'--- now create listbox
Const OPT1_POPUP_WIDTH As Double = 75
Const OPT1_POPUP_HEIGHT As Double = 110
Const OPT1_OFFSET As Double = 5#
Dim opt1Box As ListBox
Set opt1Box = ActiveSheet.ListBoxes.Add(Opt1PopUpCell.Left + OPT1_OFFSET, _
Opt1PopUpCell.Top + OPT1_OFFSET, _
OPT1_POPUP_WIDTH, _
OPT1_POPUP_HEIGHT)
With opt1Box
.ListFillRange = Opt1ListArea().Address(external:=True)
.LinkedCell = ""
.MultiSelect = xlSimple
.Display3DShading = True
.OnAction = "Module1.Opt1BoxClick"
End With
'--- is there an existing list of options selected?
Dim selectedOptions1() As String
selectedOptions1 = Split(opt1SelectCell.Value, ",")
Dim opt1 As Variant
For Each opt1 In selectedOptions1
Dim i As Long
For i = 1 To opt1Box.ListCount
If opt1Box.List(i) = opt1 Then
opt1Box.Selected(i) = True
Exit For
End If
Next i
Next opt1
End Sub
This is an example of the excel data.
How can I make this work and even improve it?

Edit filtered listbox

Can anyone help me with a solution or a different method for this? I would like to edit the filtered listbox
I'm trying to get a listbox that is able to display my sheet1 and be able to filter all the blanks/not found in column A. I also want to be able to edit the listbox aswell
I would like my userform2 listbox to display the sheet1 information.
There will also be a checkbox which will filter the listbox to show “not found” or blank lines.
If i double click the selected item on the listbox i would like to edit the information
for userform2
Private Sub ListBox2_Click()
TextBox1.Enabled = True
TextBox1.Value = ListBox2.Value
End Sub
Private Sub TextBox1_Change()
Dim rCell As Range
With ListBox2
Set rCell = Range(.RowSource).Resize(1).Offset(.ListIndex)
rCell.Value = TextBox1.Value
End With
End Sub
Private Sub CheckBox1_Click()
OptimizedMode True
If userform2.CheckBox1.Value = True Then
Worksheets("Table").Range("A1").AutoFilter Field:=1, Criteria1:="Not Found", Operator:=xlOr, Criteria2:="="
userform2.ListBox2.RowSource = vbNullString
userform2.ListBox2.ColumnHeads = False
Dim rng As Range
Dim Cel1 As Range
Dim LR As Long
Dim ws As Worksheet
Set ws = Sheets("Table")
With ws
LR = .Cells(.Rows.Count, "A").End(xlUp).Row
Set rng = .Range("A2:A" & LR).SpecialCells(xlCellTypeVisible)
With userform2.ListBox2
.ColumnCount = 1
For Each Cel1 In rng
.AddItem CStr(Cel1.Value)
.List(.ListCount - 1, 1) = Cel1.Offset(0, 1).Value
Next Cel1
End With
End With
End If
If CheckBox1.Value = False Then
With userform2.ListBox2
.RowSource = "Table!A2:A1048576"
End With
End If
OptimizedMode False
End Sub
I've re-designed my code and I believe this will achieve what you are after.
NOTE: This code uses all default object names. You will need to modify it to target the names for your workbook, sheet, useform, controls etc, if you wish to implement into your project.
In designing this answer I used the following:
A new blank Workbook with 1 new Worksheet
A new UserForm (captioned "ListBox Editor") with 1 ListBox that has 2 columns (ColumnCount = 2) and 1 CheckBox (captioned "Show Blanks").
The sample data I used was in Range("A1:A10") filling only odd numbers from row 1. This allows testing for including/excluding blank/empty rows. Screenshots of the Worksheet and UserForm below.
Worksheet data:
UserForms both with and without blanks in the listbox:
All code is written in the code behind module for the UserForm
Most can be written into any other module with calls made to the subs/functions from the UserForm/ListBox events if you'd prefer not to have the working code in the UserForm module.
Code blocks with explanations below (full code block at the end for copy/paste):
Option Explicit
Option Explicit should be included at the top of each and every code module you use. It forces explicit declaration of all variables which helps significantly in avoiding typo's in your code etc.
Private Sub PopulateListBox(ByVal IncludeBlanks As Boolean)
Dim TargetCell As Range
Dim TargetWorksheet As Worksheet
Set TargetWorksheet = ThisWorkbook.Sheets("Sheet1")
With UserForm1.ListBox1
.Clear
For Each TargetCell In TargetWorksheet.Range("A1:A10")
If Not IncludeBlanks Then
If Not TargetCell.Value = "" Then
.AddItem TargetCell.Value
.List(.ListCount - 1, 1) = TargetCell.Row
End If
ElseIf IncludeBlanks Then
.AddItem TargetCell.Value
.List(.ListCount - 1, 1) = TargetCell.Row
End If
Next TargetCell
.ColumnWidths = ";0" 'Hides listbox column that holds row number
End With
End Sub
PopulateListBox is a subroutine I wrote to handle population of the items in the ListBox. It first clears the list, allowing each population of the listbox to be 'refreshed' data. Then it iterates through each TargetCell of the defined Range. If IncludeBlanks is True it has no conditions to meet and adds each cell value into the list, if IncludeBlanks is False it will only add the cell value to the list if the value is not "".
Private Sub CheckBox1_Click()
If Me.CheckBox1.Value = False Then
PopulateListBox False
ElseIf Me.CheckBox1.Value = True Then
PopulateListBox True
End If
End Sub
This _Click event simply updates the ListBox list based on if the CheckBox is checked or not. The CheckBox represents if you are including blanks/empty cells or not so it passes True or False respective to it's Value, to the IncludeBlanks argument in PopulateListBox.
Private Sub ListBox1_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
Dim NewValue As Variant
Dim TargetWorksheet As Worksheet
Set TargetWorksheet = ThisWorkbook.Sheets("Sheet1")
NewValue = InputBox("What is the new value to replace " & UserForm1.ListBox1 & "?")
If Not StrPtr(NewValue) = 0 Then 'Check user did NOT click cancel or [X]
With ListBox1
If NewValue = "" Then NewValue = vbNullString
TargetWorksheet.Cells(.List(.ListIndex, 1), 1).Value = NewValue
.AddItem NewValue, .ListIndex
.RemoveItem .ListIndex
End With
End If
End Sub
The _DblClick Event triggers the code when a list item is double clicked. This code first opens an InputBox to allow the user to enter a new value for the selected listbox item. When the user clicks OK or hit's Enter, the new value is first written to the Cell that the original value came from, then the new value is added as a new list item and finally the previous value is removed. If the user clicks [X] or 'Cancel' the code does nothing.
Private Sub UserForm_Initialize()
PopulateListBox False
End Sub
Much the same as the Checkbox_Change code, this simply populates the ListBox when the UserForm is first initialized. It's written to exclude blanks, specified by False for the IncludeBlanks argument.
Put it all together and you have:
Option Explicit
Private Sub CheckBox1_Click()
If Me.CheckBox1.Value = False Then
PopulateListBox False
ElseIf Me.CheckBox1.Value = True Then
PopulateListBox True
End If
End Sub
Private Sub ListBox1_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
Dim NewValue As Variant
Dim TargetWorksheet As Worksheet
Set TargetWorksheet = ThisWorkbook.Sheets("Sheet1")
NewValue = InputBox("What is the new value to replace " & UserForm1.ListBox1 & "?")
If Not StrPtr(NewValue) = 0 Then 'Check user did NOT click cancel or [X]
With ListBox1
If NewValue = "" Then NewValue = vbNullString
TargetWorksheet.Cells(.List(.ListIndex, 1), 1).Value = NewValue
.AddItem NewValue, .ListIndex
.RemoveItem .ListIndex
End With
End If
End Sub
Private Sub UserForm_Initialize()
PopulateListBox False
End Sub
Private Sub PopulateListBox(ByVal IncludeBlanks As Boolean)
Dim TargetCell As Range
Dim TargetWorksheet As Worksheet
Set TargetWorksheet = ThisWorkbook.Sheets("Sheet1")
With UserForm1.ListBox1
.Clear
For Each TargetCell In Range("A1:A10")
If Not IncludeBlanks Then
If Not TargetCell.Value = "" Then
.AddItem TargetCell.Value
.List(.ListCount - 1, 1) = TargetCell.Row
End If
ElseIf IncludeBlanks Then
.AddItem TargetCell.Value
.List(.ListCount - 1, 1) = TargetCell.Row
End If
Next TargetCell
.ColumnWidths = ";0"
End With
End Sub

For loop with multiple listboxes

I pulled the code from a Mr. Excel post and tried to repurpose it for multiple listboxes.
I want the data entered to go across multiple rows based on different variables.
That is for it to make a row of the various combinations that are selected under the listbox.
Image link: https://imgur.com/a/cWcDwNx
I'd like the options in Screenshot 1 to return Screenshot 2, but it returns Screenshot 3.
I'd like the options in Screenshot 4 to return Screenshot 5, but it returns Screenshot 6.
Private Sub CommandButton1_Click()
Dim rng As Range
Dim i As Long
Dim A As Long
Set rng = Range("A" & Rows.Count).End(xlUp).Offset(1)
For A = 0 To ListBox2.ListCount - 1
If ListBox2.Selected(A) = True Then
rng.Resize(, 5).Value = Array(TextBox1.Value, TextBox2.Value, TextBox3.Value, ListBox2.List(A))
Set rng = rng.Offset(1)
End If
For i = 0 To ListBox1.ListCount - 1
If ListBox1.Selected(i) = True Then
rng.Resize(, 5).Value = Array(TextBox1.Value, TextBox2.Value, TextBox3.Value, ListBox1.List(i), ListBox2.List(A))
Set rng = rng.Offset(1)
End If
Next i
Next A
End Sub
Private Sub UserForm_Initialize()
With ListBox1
.List = Array("A", "B", "C")
.ListStyle = fmListStyleOption
.MultiSelect = fmMultiSelectMulti
End With
With ListBox2
.List = Array("Kappa", "Keepo")
.ListStyle = fmListStyleOption
.MultiSelect = fmMultiSelectMulti
End With
End Sub
Where am I going wrong, is it the Syntax or the entire approach?
How could do this for multiple listboxes, maybe even 4?
You need nested loops (untested)
Private Sub CommandButton1_Click()
Dim rng As Range, i As Long, j As Long, ar
Set rng = Range("A" & Rows.Count).End(xlUp).Offset(1).Resize(, 5)
ar = Array(TextBox1.Value,TextBox2.Value,TextBox3.Value,"","")
For i = 0 To ListBox1.ListCount - 1
If ListBox1.Selected(i) = True Then
ar(3) = ListBox1.List(i)
For j = 0 To ListBox2.ListCount - 1
If ListBox2.Selected(j) = True Then
ar(4) = ListBox2.List(j)
rng.Value = ar
Set rng = rng.Offset(1)
End If
Next
End If
Next
End Sub

Adjust Listbox.Height problems

I have a userform with a textbox and a listbox with the following plan:
Users input text in Textbox1.
Every time Textbox1.Text changes, a search with the following features is performed:
Textbox1.Text is searched in a specific range in a worksheet.
Textbox1.Text can be found more than once.
Listbox1 is populated with the results of the search.
So far so good. Due to having large set of data, the list can get many items. In this case the list reaches out of the screen and I had to limit Listbox1.Height. This is the code for the above:
Private Sub TextBox1_Change()
Dim srchWord As String, firstAddress As String
Dim srchRng As Range, cell As Range
Dim maxRow As Integer
ListBox1.Clear
If TextBox1.Value = "" Then
ListBox1.Height = 0
Else
With ThisWorkbook.Worksheets(1)
maxRow = .Cells(.Rows.Count, 2).End(xlUp).Row
Set srchRng = .Range("A2:A" & maxRow)
End With
srchWord = TextBox1.Value
Set cell = srchRng.Find(srchWord, LookIn:=xlValues, lookat:=xlPart)
With ListBox1
If Not cell Is Nothing Then
firstAddress = cell.Address
Do
If Not cell.Value Like "*(*" Then
.AddItem (cell.Value)
Select Case .ListCount
Case Is < 2
.Height = 17
Case Is < 21
.Height = 15 * .ListCount
Case Else
.Height = 272.5
End Select
Me.Height = 500
End If
Set cell = srchRng.FindNext(cell)
Loop While Not cell.Address = firstAddress
End If
End With
End If
End Sub
The problem was in Case Else when scroll was enabled I couldn't reach the last item of the list. By searching on the net I found some potential solutions:
set Listbox1.IntegralHeight = False set the height and then set again Listbox1.IntegralHeight = True
set Listbox1.MultiSelect = fmMultiSelectSingle and then set again Listbox1.MultiSelect = fmMultiSelectExtended.
do both of the above.
Application.Wait (Now + TimeValue("0:00:01") * 0.5) and then set the height.
None of these worked.
To be able to scroll to the last item, this worked:
Listbox1.IntegralHeight = False
Listbox1.Height= x
Listbox1.IntegralHeight = False
Listbox1.Height= x
but this also set the Listbox1.Height to this of one single item. (with arrows at the right)
Does anybody know how on earth am I going to control the Listbox1.Height without all this unwanted behaviour? Also if somebody can suggest another structure that could follow the plan mentioned at first, I 'm willing to discard the listbox.
This seems to be a not completely explored behaviour.
In my experience just redefine some listbox arguments.
Try the recommended sets of .IntegralHeight to False and True.
Another possible measure can help in some cases: try to choose heights for your listbox that come close to the following multiplication:
listbox height = (font size + 2 pts) * (maximum items per page)
Insert the following code after With ListBox1:
With ListBox1
.Top = 18 ' << redefine your starting Point
.Font.Size = 10 ' << redefine your font size
.IntegralHeight = False ' << try the cited recommendation :-)
Insert the following code before End With:
.Height = .Height + .Font.Size + 2
.IntegralHeight = True
End With
Hope that helps.
Link
See another faster approach to filter listboxes at How to speed up filling of listbox values on userform excel
#T.M.: Thank you for your quick response and for your time. Your answer gave me exactly what I wanted and that's why I'm marking it as such. I'm posting this just for future reference.
What I finaly did to implement the plan.
First of all I inserted:
this
With ListBox1
.Top = 18
.Font.Size = 10
.IntegralHeight = False
and this
.Height = .Height + .Font.Size + 2
.IntegralHeight = True
End With
and I linked .Height with .Font.Size as you suggested. As long as there was no need to assign absolute values to the height, there was no need to have a Select Case statement in my code.
Moreover I realized that there was no need to change the height every time an item was added but only at the end of the process, so I took it out of the loop.
Finally I added a piece of code that would make the list invisible when Textbox1 was empty. The code is now like this:
Final Userform code:
Option Compare Text
Option Explicit
Private bsdel As Boolean 'indicates if backspace or delete keys have been hit.
Private Sub ListBox1_Click()
Dim cell As Range
Dim maxRow As Integer
With ThisWorkbook.Worksheets(1)
maxRow = .Cells(.Rows.Count, 2).End(xlUp).Row
Set cell = .Range("A1:A" & maxRow).Find(UserForm11.ListBox1.Text, LookIn:=xlValues, lookat:=xlWhole)
If Not cell Is Nothing Then
cell.Select
'do other stuff also.
End If
End With
End Sub
Private Sub TextBox1_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
bsdel = False
If KeyCode = 8 Or KeyCode = 46 Then _
bsdel = True
End Sub
Private Sub TextBox1_Change()
Dim srchWord As String, firstAddress As String
Dim srchRng As Range, cell As Range
Dim maxRow As Integer
ListBox1.Clear
ListBox1.Visible = True
If bsdel And TextBox1.Value = "" Then
ListBox1.Visible = False
Me.Height = 130
Else
With ThisWorkbook.Worksheets(1)
maxRow = .Cells(.Rows.Count, 2).End(xlUp).Row
Set srchRng = .Range("A1:A" & maxRow)
End With
srchWord = TextBox1.Value
Set cell = srchRng.Find(srchWord, LookIn:=xlValues, lookat:=xlPart)
With ListBox1
'.Top = 84 'test made: deleting this made no difference.
'.Font.Size = 10 'test made: deleting this made no difference.
.IntegralHeight = False
If Not cell Is Nothing Then
firstAddress = cell.Address
Do
If Not cell.Value Like "*(*" Then 'this range includes notes within parenthesis and I didn't need them.
.AddItem (cell.Value)
End If
Set cell = srchRng.FindNext(cell)
Loop While Not cell.Address = firstAddress
If .ListCount < 21 Then 'the size is adjusted.
.Height = (.Font.Size + 2) * .ListCount
Else 'the size stays fixed at maximum.
.Height = (.Font.Size + 2) * 20
End If
End If
Me.Height = .Height + 130
.Height = .Height + .Font.Size + 2
.IntegralHeight = True
End With
End If
bsdel = False
End Sub
Private Sub UserForm_Activate()
TextBox1.SetFocus
End Sub
Private Sub UserForm_Initialize()
ListBox1.Visible = False
End Sub

Resources