Я хочу создать поле со списком в ячейке, которую щелкнул пользователь, и разрешить пользователю писать и/или выбирать (автозаполнение, подобное Google), установить его в ячейку и закрыть поле со списком.
У меня есть этот код, который создает поле:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim lst
If Not Intersect([4:7], Target) Is Nothing And Target.Count = 1 Then
Me.DropDowns.Delete
With Worksheets("Listing")
lst = "'" & .Name & "'!" & _
.Range(.Range("a1"), _
.Cells(.Rows.Count, 1).End(xlUp)).Address()
End With
With Me.Shapes.AddFormControl(xlDropDown, Left:=Target.Left, _
Top:=Target.Top, Width:=60, Height:=15)
.Name = "CB"
.OnAction = "CB_Change"
.ControlFormat.ListFillRange = lst
End With
End If
End Sub
Проблема в том, что созданные поля со списком позволяют пользователю только выбирать, а не записывать в
Я сделал, я просто не заставил это появиться здесь
1. Вопрос должен включать все, относящийся к проблеме. Определение lst, безусловно, будет уместным. 2. Чтобы ответить кому-то в комментариях, поставьте перед его именем символ @, иначе не будет уведомления о том, что вы отвечаете.


Если возможно, используйте вместо этого проверку данных. Это создаст доступную для записи комбинацию на основе значений в ячейках J3:J5.
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Not Intersect([4:7], Target) Is Nothing And Target.Count = 1 Then
With Target.Validation
.Delete
.Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, Operator:=xlBetween, Formula1: = "=$J$3:$J$5"
.IgnoreBlank = True
.InCellDropdown = True
.InputTitle = ""
.ErrorTitle = ""
.InputMessage = ""
.ErrorMessage = ""
.ShowInput = True
.ShowError = False
End With
' This will expand the list
Target.Select
SendKeys "%{DOWN}"
End If
End Sub
Это выглядит красиво. Есть ли способ мгновенно расширить раскрывающийся список?
Я добавил код выше. Хотя я не уверен, что это лучшее, что можно сделать. Отправка нажатий клавиш опасна. Протестируйте его, прежде чем распространять.
@Phoenix вам нужно .SelectShape, которое вы только что добавили, непосредственно перед SendKeys.
Я добавил то, что предложил @MathieuGuindon.
Sendkeys отлично работает, но проверка данных, по-видимому, не может использоваться для одновременного написания и поиска предложений. Я попробую с ActiveX Combox.
Я также мог бы сделать функцию для закрытия раскрывающегося списка при попадании символа, добавить символ в ячейку, отфильтровать список и снова открыть раскрывающийся список. Это лучше, чем использование поля со списком ActiveX?
Элементы управления ActiveX легче настроить, чем элементы управления формы. MSForm.ComboBox элементы управления имеют свойство Style, которое, если установлено значение fmStyleDropDownCombo, делает область текстового поля редактируемой; когда выбран стиль fmStyleDropDownList, пользовательский ввод ограничен тем, что находится в раскрывающемся списке.

... с учетом сказанного, Проверка данных, вероятно, является лучшим вариантом (менее подверженным ошибкам, лучше интегрированным с рабочим листом / Excel, без зависимости MSForm), если вы можете жить с «обводить неверные данные», делая красные круги вокруг «недопустимых данных» который разрешено вводить, но не в выпадающем списке:

Я попробовал поле со списком ActiveX, оно отлично работает: ActiveSheet.OLEObjects.Add(ClassType: = "Forms.ComboBox.1", _ Link:=False, DisplayAsIcon:=False, Left:=Target.Left, Top:=Target. Сверху, Ширина:=162, _ Высота:=16) . Но коробка не имеет фокуса, и я пишу в ячейке сзади. Есть ли что-то вроде Me.CB.SetFocus.
@Phoenix все элементы управления MSForms имеют метод Focus. Вам нужно захватить объект, возвращаемый ActiveSheet.OLEObjects.Add, в локальную переменную — это будет OLEObject; тогда у вас может быть локальная переменная ctrl As MSForm.ComboBox, которую вы можете установить в свойство Object OLEObject - и оттуда у вас должен быть доступ к методу Focus. Если нет, попробуйте объявить ctrl As MSForm.Control.
Фокус не работает, но Ctrl.Activate выполняет свою работу.
Вы не определяете
lst?