I have a userform and a Click button on it. On click of this button a combobox is dynamically created. I want to do something when a particular value is selected from this combobox but the change event is not getting triggered. What could be the reason.
Here is my code which is put in the UserForm1 module.
Private WithEvents ComboBox1 As MSForms.ComboBox
Private Sub ClickButton_Click()
'Create combo box
Dim ComboBox1 As MSForms.ComboBox
Set ComboBox1 = Me.Controls.Add("Forms.ComboBox.1")
With ComboBox1
.Left = 160
.Top = 50
.Width = 70
.Height = 20
.AddItem ("> than")
.AddItem ("< than")
.AddItem ("Max")
.AddItem ("Min")
.Enabled = True
.BackColor = RGB(255, 255, 255)
.ForeColor = RGB(0, 0, 0)
.SpecialEffect = fmSpecialEffectFlat
.Font.Size = 12
.Font.Bold = False
.Font.Name = "Arial"
.TabIndex = 2
End With
DoEvents
ComboBox1.SetFocus
End Sub
Private Sub ComboBox1_Change()
Dim inputNumber As Variant
If ComboBox1.Value = "> than" Then
inputNumber = InputBox("Enter a number:")
'Check if the input is valid number
If IsNumeric(inputNumber) Then
ComboBox1.Value = ComboBox2.Value & " " & inputNumber
Else
MsgBox "Invalid input"
End If
End If
End Sub
The method you need to use is described here: https://stackoverflow.com/a/8986622/9852011 , but for your particular case, here is what you need to do:
This is the code that should be in the module of your UserForm:
Private m_oCollectionOfEventHandlers As Collection
Private Sub UserForm_Initialize()
Set m_oCollectionOfEventHandlers = New Collection
End Sub
Private Sub CommandButton1_Click()
Dim ComboBox1 As MSForms.ComboBox
Set ComboBox1 = Me.Controls.Add("Forms.ComboBox.1")
With ComboBox1
.Left = 160
.Top = 50
.Width = 70
.Height = 20
.AddItem ("> than")
.AddItem ("< than")
.AddItem ("Max")
.AddItem ("Min")
.Enabled = True
.BackColor = RGB(255, 255, 255)
.ForeColor = RGB(0, 0, 0)
.SpecialEffect = fmSpecialEffectFlat
.Font.Size = 12
.Font.Bold = False
.Font.Name = "Arial"
.TabIndex = 2
End With
DoEvents
ComboBox1.SetFocus
Dim cb1EventHandler As comboboxeventhandler
Set cb1EventHandler = New comboboxeventhandler
Set cb1EventHandler.ComboBox = ComboBox1
m_oCollectionOfEventHandlers.Add cb1EventHandler
End Sub
Then, insert a new class module into your project, name it "ComboBoxEventHandler" and put this code into it:
Private WithEvents m_oComboBox As MSForms.ComboBox
Public Property Set ComboBox(ByVal oComboBox As MSForms.ComboBox)
Set m_oComboBox = oComboBox
End Property
Private Sub m_oComboBox_Change()
Dim inputNumber As Variant
With m_oComboBox
If .Value = "> than" Then
inputNumber = InputBox("Enter a number:")
'Check if the input is valid number
If IsNumeric(inputNumber) Then
.Value = .Parent.ComboBox2.Value & " " & inputNumber
Else
MsgBox "Invalid input"
End If
End If
End With
End Sub
I don't know what "ComboBox2" is but for the sake of this example, I just assumed it is a ComboBox which already exists in the UserForm somewhere.
Related
I need to create an Object representing a UserForm, with methods to add Controls, and a method to present the UserForm.
I'm having a hard time wrapping my head around object-oriented VBA, and the tutorials/answers/documentation aren't helping me.
Here's how I imagine the Object and an example of its methods.
Sub UI_Window(caption as String)
Dim Form As Object
' This is to stop screen flashing while creating form
Application.VBE.MainWindow.Visible = False
Set Form = ThisWorkbook.VBProject.VBComponents.Add(1)
With Form
.Properties("Caption") = caption
.Properties("Width") = 600
.Properties("Height") = 50
End With
return Form
Sub addButton(action as String, code as String)
Set NewButton = Form.designer.Controls.Add("Forms.commandbutton.1")
With NewButton
.Name = "cmd_1"
.Caption = action
.Accelerator = "M"
.Top = Form.Height
.Left = 50
.Width = 500
.Height = 100
.Font.Size = 14
.Font.Name = "Tahoma"
.BackStyle = fmBackStyleOpaque
End With
' Adjust height of Form to added content
With Form
.Properties("Height") = Form.Height + NewButton.Height + 50
End With
' Should loop through code argument, line-by-line
Form.codemodule.insertlines 8, "Private Sub cmd_1_Click()"
Form.codemodule.insertlines 9, "msgbox (""Button clicked!"")"
Form.codemodule.insertlines 10, "End Sub"
End Sub
Sub present()
'Show the form
VBA.UserForms.Add(Form.Name).Show
'Delete the form
ThisWorkbook.VBProject.VBComponents.Remove Form
End Sub
End Sub
And here's how it would be used
Sub SampleWindow()
Set Window = UI_Window "Window Title"
Window.addButton "Click me", "msgbox (""Button clicked!"")"
Window.present()
End Sub
Please, try this adapted way:
Copy the next code on top of module where the following code exists:
Public frm As Object 'to use it even after the UserForm has been created
'to avoid it deletion when tested the code
Copy the next code in the same standard module:
Sub CreateAFormWithAButton()
Const formName As String = "MyNewForm"
Const formCaption As String = "My Form"
removeForm formName 'remove the previously created form, if the case
UI_Window formCaption, formName 'create the new form
addButton frm, "myFirstButton", "Click Me" 'add a button
VBA.UserForms.Add(frm.Name).Show 'show the newly created form
End Sub
Function formExists(frmName As String) As Boolean
Dim fr As Variant
For Each fr In ThisWorkbook.VBProject.VBComponents
If fr.Type = vbext_ct_MSForm Then
If frmName = fr.Name Then
Set frm = fr
formExists = True: Exit Function
End If
End If
Next
End Function
Sub UI_Window(frmCaption As String, frmName As String)
Set frm = ThisWorkbook.VBProject.VBComponents.Add(vbext_ct_MSForm) '3
With frm
.Properties("Caption") = frmCaption
.Properties("Width") = 500
.Properties("Height") = 200
.Properties("Name") = frmName
End With
End Sub
Sub addButton(form As Object, btName As String, btCaption As String)
Dim NewButton As MSForms.CommandButton
If buttonExists(btName) Then MsgBox "A button named """ & btName & """ already exists...": Exit Sub
Set NewButton = form.Designer.Controls.Add("Forms.commandbutton.1")
With NewButton
.Name = btName
.caption = btCaption
.top = 0
.left = 50
.width = 100
.height = 40
.Font.size = 14
.Font.Name = "Tahoma"
End With
' Should loop through code argument, line-by-line
form.CodeModule.InsertLines 8, "Private Sub " & btName & "_Click()"
form.CodeModule.InsertLines 9, " msgbox (""Button clicked!"")"
form.CodeModule.InsertLines 10, "End Sub"
End Sub
Function buttonExists(btName As String) As Boolean
Dim ctrl As Variant
For Each ctrl In frm.Designer.Controls
If ctrl.Name = btName Then buttonExists = True: Exit Function
Next
End Function
Sub removeForm(frmName As String)
Dim i As Long, strName As String
If Not formExists(frmName) Then Exit Sub
strName = "TestName"
tryAgain:
On Error Resume Next
frm.Name = strName
If err.Number = 75 Then 'a previously used name...
err.Clear 'clear the error
strName = strName & i: i = i + 1 'increment the new string
frm.Name = strName: GoTo tryAgain 'test the new name again
End If
On Error GoTo 0
ThisWorkbook.VBProject.VBComponents.Remove frm
End Sub
If you will try running the code for the second time, you cannot create a button with the same name. The code check if the name exists and warn. It can be adapted to propose another name (adding an incremented number), but it needs also to set other positioning, making the code more complicated and this does not make the object of the question, I would say...
Please, run/test it and send some feedback.
I have Microsoft Office 365 2019.
First of all i want to tell how code works:
Insert Note.
Click on Cell who has inserted Note.
Press Ctrl+N
Then you will see "PopUp-Menu".
I have VBA code (to work put in ThisWorkbook):
Private Sub Workbook_Open()
Application.OnKey "^{n}", CodeName & ".ContextMenu"
End Sub
Private Sub Workbook_BeforeClose(Cancel As Boolean)
Application.OnKey "^{n}"
End Sub
Private Sub ContextMenu()
If ActiveCell Is Nothing Then Exit Sub
If ActiveCell.Comment Is Nothing Then Exit Sub
On Error Resume Next 'Can be and without inadequate to, but then with brute force(cycle) CommandBars.
Dim cb As CommandBar
Set cb = Application.CommandBars("vbaPopup")
If cb Is Nothing Then CreateContextMenu
Application.CommandBars("vbaPopup").ShowPopup
End Sub
Private Sub CreateContextMenu()
Dim a1_icon, a1_file, a2, a3, i&, m$, p$, f$: m = CodeName & ".": p = Path & "\Image\"
a1_icon = Array(76, 72, 178, 53)
a1_file = Array("NoteZoom_200x110.jpg", "NoteZoom_600x400.jpg", "Full Screen.jpg", "NoteZoom_InputBox.jpg", "Copy Text.jpg")
a2 = Array("NoteZoom 200x110", "NoteZoom 600x400", "Note <Full Screen>", "NoteZoom InputBox", "Скопировать текст примечания")
a3 = Array("NoteZoom1", "NoteZoom2", "NoteZoom3", "NoteZoom_InputBox", "NoteTextToClipboard")
With Application.CommandBars.Add("vbaPopup", msoBarPopup, , True) 'You can also not do to make the context menu temporary.
For i = 0 To UBound(a1_file) 'Ubound(a1_ico)
With .Controls.Add
f = p & a1_file(i)
If Len(Dir(f)) Then
.Picture = LoadPicture(f)
Else
.FaceId = a1_icon(i) 'If the file is not found, the icon. But it's not necessary.
End If
.Caption = a2(i)
.OnAction = m & a3(i)
End With
Next
End With
End Sub
Private Sub NoteZoom1(): NoteChangeSize 200, 110: End Sub
Private Sub NoteZoom2(): NoteChangeSize 600, 400: End Sub
Private Sub NoteZoom3()
With ActiveWindow.VisibleRange
NoteChangeSize .Width, .Height, True
'With .Resize(.Rows.Count - 1, .Columns.Count - 1) 'Without check
' NoteChangeSize .Width, .Height, True
'End With
End With
End Sub
Private Sub NoteChangeSize(w!, h!, Optional scr As Boolean)
With ActiveCell.Comment.Shape
.Width = w: .Height = h
If scr Then .Top = 0: .Left = 0: .Visible = msoTrue
End With
End Sub
'To create a `Note` with `InputBox`.
Private Sub NoteZoom_InputBox()
'Ниже 2 строчки для проверки наличия `Примечания`.
If ActiveCell Is Nothing Then Exit Sub
If ActiveCell.Comment Is Nothing Then Exit Sub
Dim lH As Long 'height
Dim lW As Long 'width
lH = Application.InputBox("Choose the HEIGHT of the notes ")
lW = Application.InputBox("Choose the WIDTH of the notes ")
With ActiveCell.Comment
' .Text Text:="Note:" & Chr(10) & ""
.Shape.Height = lH
.Shape.Width = lW
End With
End Sub
Private Sub NoteTextToClipboard()
With New DataObject
.SetText ActiveCell.Comment.Text
.PutInClipboard
End With
End Sub
For more details you can download my Excel Workbook to see how it's implemented!
Also i find code on this site Ron de Bruin. I wish to add "Submenu" in my "Menu"! Wrote out only those codes which can help to create "Submenu". But how to combine I don't know!?
Dim MenuItem As CommandBarPopup
'Add PopUp menu
With Application.CommandBars.Add(Name:=Mname, Position:=msoBarPopup, _
MenuBar:=False, Temporary:=True)
'Add menu with two buttons
Set MenuItem = .Controls.Add(Type:=msoControlPopup)
With MenuItem
.Caption = "My Special Menu"
With .Controls.Add(Type:=msoControlButton)
.Caption = "Button 1 in menu"
.FaceId = 71
.OnAction = "'" & ThisWorkbook.Name & "'!" & "TestMacro"
End With
In the end I want to get this:
0Key finally i find some solution for this. Right now it's looks like this:
Looks cool right? Download full code link.
I have Microsoft Office 365 2019.
I asked a question with an answer about "Insert Note" with .Fill.UserPicture.
I still have some error.
See Screencast.
I found the problem and it is SendKeys "+{F2}" (after inserting note it's open Note).
Sub Special_Note2_FillPicture(control As IRibbonControl)
Dim img As FileDialog
Dim i_add As String
Set img = Application.FileDialog(msoFileDialogFilePicker)
img.AllowMultiSelect = False
img.Title = "Select the Image!"
img.Show
If img.SelectedItems.Count < 1 Then
MsgBox "No Image Selected"
Exit Sub
Else
i_add = img.SelectedItems(1)
End If
Dim myComm As Comment
If Not ActiveCell.Comment Is Nothing Then
If MsgBox("The cell already contains a note, delete?", 4) - 7 Then
ActiveCell.Comment.Delete
Else: Exit Sub
End If
End If
Set myComm = ActiveCell.AddComment
With myComm.Shape
.Height = 110
.Width = 200
.AutoShapeType = 1 'form
' .Fill.UserTextured
.Fill.UserPicture i_add
.Line.ForeColor.RGB = RGB(255, 0, 0)
.DrawingObject.Font.Name = "Consolas"
.DrawingObject.Font.FontStyle = "normal"
.DrawingObject.Font.Size = 8
End With
'emulate the choice of "Change note"
SendKeys "+{F2}"
End Sub
0Key i find solution. I rewrote the code a little bit:
Sub Note_FiilPictureDialog(control As IRibbonControl)
Dim img As FileDialog
Dim i_add As String
Dim myComm As Comment
Set img = Application.FileDialog(msoFileDialogFilePicker)
img.AllowMultiSelect = False
img.Title = "Select the Image!"
img.Show
If img.SelectedItems.Count < 1 Then
Exit Sub
Else
i_add = img.SelectedItems(1)
End If
'If the cell contains a `Note` delete!
If Not ActiveCell.Comment Is Nothing Then
ActiveCell.Comment.Delete
End If
On Error GoTo nexterr
ActiveCell.ClearComments
Set myComm = ActiveCell.AddComment
With myComm.Shape
.Height = 110
.Width = 200
.AutoShapeType = 1 'form
' .Fill.UserTextured
.Fill.UserPicture i_add
.Line.ForeColor.RGB = RGB(255, 0, 0)
.DrawingObject.Font.Name = "Consolas"
.DrawingObject.Font.FontStyle = "normal"
.DrawingObject.Font.Size = 8
'emulate the choice of "Change note".
SendKeys "+{F2}"
Exit Sub
nexterr:
MsgBox "You can only select images!", vbCritical, "Error"
ActiveCell.ClearComments
End With
End Sub
UPDATE: Upon further research in the object browser... it appears that an MSForms.TextBox implements neither the .Name property or _Exit events - only _Change events. Is there a way to determine which specific TextBox generated a change event?
Alternately is it possible to use the MSForms.Control with this technique? The Control object implements the .Name property and _Exit event.
Can you listen for a TextBox exit event? Similarly to how a normal TextBox event would work? E.g.
Private Sub TextBox1_Exit(ByVal Cancel As MSForms.ReturnBoolean)
'Update a certain label based on the value of the TextBox
End Sub
The following doesn't catch the exit event. Moreover, while I can see the .Name property of the TextBox which generated the event for MyTextBox in the locals window, I cannot access that info to determine which label to act on.
This class technique was adapted from this post, and this post, which caught the change events.
Class clsTextBox:
Private WithEvents MyTextBox As MSForms.TextBox
Public Property Set Control(tb As MSForms.TextBox)
Set MyTextBox = tb
End Property
' Want to handle this event, but it's not caught when exiting the TextBox control
Private Sub MyTextBox_Exit(ByVal Cancel As MSForms.ReturnBoolean)
'Debug.Print me.Control.name
'Update a certain label based on the value of the TextBox
Stop
End Sub
' Catching this event but can't identify the control which triggered it
Private Sub MyTextBox_Change()
Debug.Print MyTextBox.Value ' <--- This prints the correct value
Debug.Print Me.Control.Name ' <--- ERROR here on any variation of Me or MyTextBox
'Update a certain label based on the value of the TextBox
Stop
End Sub
I have a series of dynamically created controls which need listeners. Code follows:
Option Explicit
Dim tbCollection As Collection
Private Sub UserForm_Initialize()
Dim ctrl As MSForms.Control
Dim obj As clsTextBox
Dim acftNumber As Long
Dim mPage As MSForms.MultiPage ' Control
Dim lbl_acftName As MSForms.Label
Dim lbl_currentHrs As MSForms.Label
Dim lbl_hrsDUE As MSForms.Label
Dim lbl_dateXFRIn As MSForms.Label
Dim lbl_dateXFROut As MSForms.Label
Dim lbl_hrsOnXFROut As MSForms.Label
Dim txb_currentHrs As MSForms.TextBox
Dim txb_hrsDUE As MSForms.TextBox
Dim txb_dateXFRIn As MSForms.TextBox
Dim txb_dateXFROut As MSForms.TextBox
Dim txb_hrsOnXFROut As MSForms.TextBox
Dim i As Double
Dim pgName As String
Dim acftName As String
' Correct for border size calculations bug in Excel 2016
Me.Height = 249.75
Me.Width = 350.25
acftNumber = Range("aircraft").Count 'Unknown value from 3 to 10
Set mPage = Me.multipage_file_week 'set Multipage variable
For i = 1 To acftNumber
'set name/title for new page
pgName = "pg_acft_" & i
acftName = Range("aircraft").Cells(i, 1).Value
'mPage.Pages.Add pgName, pgTitle
With mPage 'add acft tab
' add the aircraft page to the multipage
.Pages.Add pgName, acftName
' Aircraft Name Label
Set lbl_acftName = .Pages(i).Controls.Add("Forms.Label.1", "lbl_acftName_" & i, True)
With lbl_acftName
.Caption = acftName
.Font = "Arial"
.Font.Size = 12
.Font.Bold = True
.Left = 10
.Width = 55
.Top = 0
End With
' Current Hours Label and TextBox
Set lbl_currentHrs = .Pages(i).Controls.Add("Forms.Label.1", "lbl_currentHrs_" & i, True)
With lbl_currentHrs
.Caption = "Current Asset Hours:"
.TextAlign = fmTextAlignRight
.Font = "Arial"
.Font.Size = 10
.Font.Bold = False
.Left = 20
.Width = 120
.Top = 25
End With
Set txb_currentHrs = .Pages(i).Controls.Add("Forms.TextBox.1", "txb_currentHrs_" & i, True)
With txb_currentHrs
.Value = "16004.5"
.Text = "16004.5"
.Font = "Arial"
.Font.Size = 10
.Font.Bold = False
.Left = 150
.Width = 70
.Top = 25
End With
' Hours DUE Label and TextBox
Set lbl_hrsDUE = .Pages(i).Controls.Add("Forms.Label.1", "lbl_hrsDUE_" & i, True)
With lbl_hrsDUE
.Caption = "Hours next HMC DUE:"
.TextAlign = fmTextAlignRight
.Font = "Arial"
.Font.Size = 10
.Font.Bold = False
.Left = 20
.Width = 120
.Top = 50
End With
Set txb_hrsDUE = .Pages(i).Controls.Add("Forms.TextBox.1", "txb_hrsDUE_" & i, True)
With txb_hrsDUE
.Value = "16004.5"
.Text = "16004.5"
.Font = "Arial"
.Font.Size = 10
.Font.Bold = False
.Left = 150
.Width = 70
.Top = 50
End With
' Date XFR In Label and TextBox
Set lbl_dateXFRIn = .Pages(i).Controls.Add("Forms.Label.1", "lbl_dateXFRIn_" & i, True)
With lbl_dateXFRIn
.Caption = "Estimated arrival date:"
.TextAlign = fmTextAlignRight
.Font = "Arial"
.Font.Size = 10
.Font.Bold = False
.Left = 20
.Width = 120
.Top = 75
End With
Set txb_dateXFRIn = .Pages(i).Controls.Add("Forms.TextBox.1", "txb_hrsDUE_" & i, True)
With txb_dateXFRIn
.Value = "4/16/2019"
.Text = "4/16/2019"
.Font = "Arial"
.Font.Size = 10
.Font.Bold = False
.Left = 150
.Width = 70
.Top = 75
End With
' Date XFR Out Label and TextBox
Set lbl_dateXFROut = .Pages(i).Controls.Add("Forms.Label.1", "lbl_dateXFROut_" & i, True)
With lbl_dateXFROut
.Caption = "Estimated departure date:"
.TextAlign = fmTextAlignRight
.Font = "Arial"
.Font.Size = 10
.Font.Bold = False
.Left = 20
.Width = 120
.Top = 100
End With
Set txb_dateXFROut = .Pages(i).Controls.Add("Forms.TextBox.1", "txb_hrsDUE_" & i, True)
With txb_dateXFROut
.Value = "4/16/2019"
.Text = "4/16/2019"
.Font = "Arial"
.Font.Size = 10
.Font.Bold = False
.Left = 150
.Width = 70
.Top = 100
End With
' Hours on XFR Out Label and TextBox
Set lbl_hrsOnXFROut = .Pages(i).Controls.Add("Forms.Label.1", "lbl_hrsOnXFROut_" & i, True)
With lbl_hrsOnXFROut
.Caption = "Desired hours remaining on departure:"
.TextAlign = fmTextAlignLeft
.Font = "Arial"
.Font.Size = 10
.Font.Bold = False
.Left = 20
.Width = 170
.Top = 125
End With
Set txb_hrsOnXFROut = .Pages(i).Controls.Add("Forms.TextBox.1", "txb_hrsDUE_" & i, True)
With txb_hrsOnXFROut
.Value = "35"
.Text = "35"
.Font = "Arial"
.Font.Size = 10
.Font.Bold = False
.Left = 200
.Width = 35
.Top = 125
End With
End With
'Debug
Debug.Print Me.multipage_file_week.Pages(i).Name & ":"
For Each ctrl In Me.multipage_file_week.Pages(i).Controls
Debug.Print " - " & ctrl.Name
Next ctrl
Next i
mPage.Value = 0
Me.Caption = FILE_WEEK_FORM_TITLE
Set tbCollection = New Collection
For Each ctrl In Me.Controls
If TypeOf ctrl Is MSForms.TextBox Then
Set obj = New clsTextBox
Set obj.Control = ctrl
tbCollection.Add obj
End If
Next ctrl
Set obj = Nothing
End Sub
MSForms.Control defines the Enter and Exit events: if you need to handle TextBox.Change, then you need two WithEvents variables:
Private WithEvents TextBoxEvents As MSForms.TextBox
Private WithEvents ControlEvents As MSForms.Control
Public Property Set Control(ByVal tb As Object)
Set TextBoxEvents = tb
Set ControlEvents = tb
End Property
MSForms.Control is also the interface through which you get to access properties like Name, Top, Left, Visible, etc.
Tip: Never type event handler procedure signatures by hand. Select the source interface from the dropdown in the upper-left corner of the code pane, then select an event to handle from the upper-right dropdown; let the VBE generate the members with the correct signature. If you're in a handler procedure and the upper-left dropdown says "(general)", you're not in an event handler.
EDIT
While the above code compiles fine and the MSForms.Control interface does expose the events we're looking to handle...
?TypeOf tb Is MSForms.Control
True
?TypeOf tb Is MSForms.TextBox
True
...there's a bit of COM hackery going on behind the scenes; there's enough smokes & mirrors for VBA to successfully compile the above, but, basically, you're looking at a glitch in The Matrix (Rubberduck's resolver has similar "nope" issues with MSForms controls): there isn't any obvious way to get VBA to bind a dynamic control object to its MSForms.Control events.
With the help of the ConnectToConnectionPoint API you can catch the Event (Every Event, also Enter and Exit) for every control.
Have a look here: Trigger Enter field behaviour through class for a control
For Exit it will be
Public Sub myExit(ByVal Cancel As MSForms.ReturnBoolean)
Attribute myExit.VB_UserMemId = -2147384829
'code
End Sub
When I protect my sheet and select the list from a combobox, another combobox shows up at a random place (marked by the red circle in the picture below).
I have not placed any comboboxes there, but it keeps showing, and I need to select an empty cell for that to disappear. Does anybody know how to fix this bug ?
this is my combo box code:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
'Update by Extendoffice: 2018/9/21
Dim xCombox As OLEObject
Dim xStr As String
Dim xWs As Worksheet
Dim xArr
Set xWs = Application.ActiveSheet
On Error Resume Next
Set xCombox = xWs.OLEObjects("TempCombo")
With xCombox
.ListFillRange = ""
.LinkedCell = ""
.Visible = False
End With
If Target.Validation.Type = 3 Then
Target.Validation.InCellDropdown = False
Cancel = True
xStr = Target.Validation.Formula1
xStr = Right(xStr, Len(xStr) - 1)
If xStr = "" Then Exit Sub
With xCombox
.Visible = True
.Left = Target.Left
.Top = Target.Top
.Width = Target.Width + 5
.Height = Target.Height + 5
.ListFillRange = xStr
If .ListFillRange = "" Then
xArr = Split(xStr, ",")
Me.TempCombo.List = xArr
End If
.LinkedCell = Target.Address
End With
xCombox.Activate
Me.TempCombo.DropDown
End If
End Sub
Private Sub TempCombo_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer)
Select Case KeyCode
Case 9
Application.ActiveCell.Offset(0, 1).Activate
Case 13
Application.ActiveCell.Offset(1, 0).Activate
End Select
End Sub