Question : VBA Control (Box) Design Questions

I need a VBA control that will let uses select multiple choices from a drop down menu as well as enter their own free text.  This control must exist in a cell for multiple range of cells (i.e. C2:C100).  This is not being used in a form, but in an excel worksheet.

I assume the control should be a combo box.  But:  Q1: what is the vba code or property settings to extend it across all the cells in a range.  Q2:  What is the property settings to allow multiple selections and user input?


William

Answer : VBA Control (Box) Design Questions

You will need to put the base list SOMEWHERE - we can't just pull them out of the air. They can be on a hidden sheet if you don't want them on the main sheet.

Create a template list box control on the workhsheet. Name it "ListBox1". Do not fill in the LinkedCell or ListFillRange properties. Select cells C2:C100 and name them "ListBoxArea". Create a list of base selection values somewhere, anywhere, on a hidden sheet if need be, and name them "ListBoxSource".

After adding the code below to the worksheet module, any time you click on a cell in C2:C100, the list box will appear to the right of the cell with that cell's values selected. Click in another cell and the list box will move and be reset accordingly. Changes made using the list box will be saved in the selected cell. Click anywhere outside C2:C100 and the list box is hidden. Click on "Custom..." to enter a custom value. Working example: http://www.zorvek.com/downloads/ee-22138225-vba-control-box.xls.

The code below goes into the worksheet code module. To add VBA code to a worksheet module in an Excel workbook, right-click on the worksheet tab at the bottom of the window and select View Code. Paste the code into the document window that appears. Press ALT+F11 to return to the Excel workbook. To find a worksheet module when already in the VBE, press CTRL+R to open the VBE project explorer. Find the worksheet module in which the code will be placed - each worksheet module is pre-assigned a name such as "Sheet1 (Sheet1)" where the name inside the parenthesis is the worksheet's tab name. Double-click the desired module and paste the code into the document window that appears. Press ALT+F11 to return to the Excel workbook.

[Begin Code Segment]

Private mIgnoreEvents As Boolean

Private Sub ListBox1_Change()

' Handle the list box change event.

   Dim Result As String
   Dim Index As Long
   Dim CustomValue As String
   Dim RefreshList As Boolean
   
   If mIgnoreEvents Then Exit Sub

   Application.EnableEvents = False
   For Index = 1 To ListBox1.ListCount - 1
      If ListBox1.Selected(Index - 1) Then
         Result = Result & ListBox1.List(Index - 1) & "|"
      End If
   Next Index
   If ListBox1.Selected(ListBox1.ListCount - 1) Then
      CustomValue = InputBox("Enter custom value:")
      If Len(CustomValue) > 0 Then
         Result = Result & CustomValue & "|"
         RefreshList = True
      End If
   End If
   If Len(Result) > 0 Then Result = Left(Result, Len(Result) - 1)
   ActiveCell = Result
   If RefreshList Then LoadListBox ListBox1, ActiveCell
   Application.EnableEvents = True

End Sub

Public Sub LoadListBox( _
      ByVal ListBox As msForms.ListBox, _
      ByVal LinkedCell As Range _
   )

' Load the list box using the values in the linked cell.

   Dim Selections As Variant
   Dim Selection As Variant
   Dim Cell As Range
   Dim Index As Long
   Dim Found As Boolean
   
   Application.EnableEvents = False
   mIgnoreEvents = True
   ListBox.Clear
   For Each Cell In [ListBoxSource]
      ListBox.AddItem Cell
   Next Cell
   Selections = Split(LinkedCell, "|")
   For Each Selection In Selections
      Found = False
      For Index = 1 To ListBox.ListCount
         If ListBox.List(Index - 1) = Selection Then
            ListBox.Selected(Index - 1) = True
            Found = True
            Exit For
         End If
      Next Index
      If Found = False Then
         ListBox.AddItem Selection
         ListBox.Selected(ListBox.ListCount - 1) = True
      End If
   Next Selection
   ListBox.AddItem "Custom..."
   mIgnoreEvents = False
   Application.EnableEvents = True

End Sub

Private Sub Worksheet_SelectionChange(ByVal Target As Range)

   Dim FocusRange As Range
   
   Set FocusRange = Intersect(UsedRange, Target, [ListBoxArea])
   If Not FocusRange Is Nothing Then
      ListBox1.Visible = True
      With Target.Cells(1, 1)
         ListBox1.Top = .Top
         ListBox1.Left = .Left + .Width
         LoadListBox ListBox1, Target.Cells(1, 1)
      End With
   Else
      ListBox1.Visible = False
   End If

End Sub

[End Code Segment]

Kevin
Random Solutions  
 
programming4us programming4us