|
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
|
|
|
|