Option Explicit
Private Sub butClose_Click()
Unload Me
End Sub
Private Sub butOK_Click()
Me.Tag = "x"
Me.Hide
End Sub
Function FromList(chooseFrom As Variant, _
Optional Prompt As String, _
Optional Title As String = "Choose from list", _
Optional Default As Variant = "", _
Optional MultiSelect As Boolean = False, _
Optional Delimiter As String = ",") As String
Dim oneItem As Variant
Dim returnString As String
With Me
.Caption = Title
.lblPrompt.Caption = Prompt
With .Label1
With .Font
.Size = Me.ListBox1.Font.Size
.Name = Me.ListBox1.Font.Name
End With
End With
End With
If TypeName(chooseFrom) = "Range " Then
With chooseFrom
chooseFrom = IIf(.Cells.Count = 1, Array(.Value), .Value)
End With
End If
With Me.ListBox1
For Each oneItem In chooseFrom
Rem put in listbox
.AddItem CStr(oneItem)
Rem add line to dummy label
Label1.Caption = Label1.Caption & vbCr & CStr(oneItem)
Next oneItem
Label1.Caption = Mid(Label1.Caption, 2)
.MultiSelect = IIf(MultiSelect, fmMultiSelectMulti, fmMultiSelectSingle)
If MultiSelect Then
If Not TypeName(Default) Like "*()" Then
If Not Default = vbNullString Then
Default = Array(Default)
End If
End If
For oneItem = 0 To .ListCount - 1
If IsNumeric(Application.Match(.List(oneItem), Default, 0)) Then
.Selected(oneItem) = True
End If
Next oneItem
Else
On Error Resume Next
.Value = Default
On Error GoTo 0
End If
End With
Me.Show
With Choose
With .ListBox1
If MultiSelect Then
Rem multiselect
If .Parent.Tag = vbNullString Then
Rem canceled
Else
returnString = "x"
For oneItem = 1 To .ListCount
If .Selected(oneItem - 1) Then
returnString = returnString & Delimiter & .List(oneItem - 1)
End If
Next oneItem
returnString = Mid(returnString, 2)
If returnString <> vbNullString Then
returnString = Mid(returnString, Len(Delimiter) + 1)
End If
End If
'FromList = returnString
Else
Rem single select
If .ListIndex > -1 Then
returnString = ListBox1.Value
End If
'FromList = returnString
End If
FromList = returnString
End With
End With
Unload Choose
End Function
Private Sub ListBox1_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
Me.Hide
End Sub
Private Sub UserForm_Activate()
Rem size and positioning
With lblPrompt
.WordWrap = False
.AutoSize = True
.AutoSize = False
If .Width > 300 Then
.Width = 370
.WordWrap = True
.AutoSize = True
.AutoSize = False
End If
.BackColor = Me.BackColor
If .Width < 202 Then .Width = 202
End With
With ListBox1
Rem size matches auto-size dummy label
ListBox1.Height = Label1.Height + 3
ListBox1.Width = Label1.Width + 80
ListBox1.Height = Application.Min(ListBox1.Height, 200)
Rem postion matches prompt
.Left = lblPrompt.Left
.Top = lblPrompt.Top + lblPrompt.Height + 12
End With
With butOK
.Left = lblPrompt.Left + lblPrompt.Width - .Width
.Top = ListBox1.Top + ListBox1.Height + 20
End With
With butClose
.Left = butOK.Left - 80
.Top = butOK.Top
End With
With Me
.Width = butOK.Left + butOK.Width + 20
.Height = butOK.Top + butOK.Height + 23 + 20
.Repaint
End With
End Sub
Private Sub UserForm_Initialize()
With Me.Label1
.WordWrap = False
.AutoSize = True
.Visible = False: Rem alter
.Caption = vbNullString
End With
End Sub