Создать доступный для записи список со списком с помощью vba

Я хочу создать поле со списком в ячейке, которую щелкнул пользователь, и разрешить пользователю писать и/или выбирать (автозаполнение, подобное 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

Проблема в том, что созданные поля со списком позволяют пользователю только выбирать, а не записывать в

Вы не определяете lst?

SJR 28.05.2019 17:28

Я сделал, я просто не заставил это появиться здесь

Foxhunt 28.05.2019 17:33

1. Вопрос должен включать все, относящийся к проблеме. Определение lst, безусловно, будет уместным. 2. Чтобы ответить кому-то в комментариях, поставьте перед его именем символ @, иначе не будет уведомления о том, что вы отвечаете.

Cindy Meister 28.05.2019 17:36
Преобразование HTML-таблицы в профессиональный документ Excel
Преобразование HTML-таблицы в профессиональный документ Excel
Это самый простой способ создания Excel из HTML-таблицы.
Импорт excel в laravel в базу данных
Импорт excel в laravel в базу данных
Здравствуйте, дорогой читатель, в этой статье я расскажу практическим и быстрым способом, как импортировать файл Excel в вашу базу данных с помощью...
1
3
290
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 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

Это выглядит красиво. Есть ли способ мгновенно расширить раскрывающийся список?

Foxhunt 28.05.2019 19:00

Я добавил код выше. Хотя я не уверен, что это лучшее, что можно сделать. Отправка нажатий клавиш опасна. Протестируйте его, прежде чем распространять.

Sam 28.05.2019 19:24

@Phoenix вам нужно .SelectShape, которое вы только что добавили, непосредственно перед SendKeys.

Mathieu Guindon 28.05.2019 19:58

Я добавил то, что предложил @MathieuGuindon.

Sam 28.05.2019 20:00

Sendkeys отлично работает, но проверка данных, по-видимому, не может использоваться для одновременного написания и поиска предложений. Я попробую с ActiveX Combox.

Foxhunt 28.05.2019 20:17

Я также мог бы сделать функцию для закрытия раскрывающегося списка при попадании символа, добавить символ в ячейку, отфильтровать список и снова открыть раскрывающийся список. Это лучше, чем использование поля со списком ActiveX?

Foxhunt 28.05.2019 20:31
Ответ принят как подходящий

Элементы управления ActiveX легче настроить, чем элементы управления формы. MSForm.ComboBox элементы управления имеют свойство Style, которое, если установлено значение fmStyleDropDownCombo, делает область текстового поля редактируемой; когда выбран стиль fmStyleDropDownList, пользовательский ввод ограничен тем, что находится в раскрывающемся списке.

ComboBox1 properties

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

DV red circle around invalid data

Я попробовал поле со списком ActiveX, оно отлично работает: ActiveSheet.OLEObjects.Add(ClassType: = "Forms.ComboBox.1", _ Link:=False, DisplayAsIcon:=False, Left:=Target.Left, Top:=Target. Сверху, Ширина:=162, _ Высота:=16) . Но коробка не имеет фокуса, и я пишу в ячейке сзади. Есть ли что-то вроде Me.CB.SetFocus.

Foxhunt 28.05.2019 20:24

@Phoenix все элементы управления MSForms имеют метод Focus. Вам нужно захватить объект, возвращаемый ActiveSheet.OLEObjects.Add, в локальную переменную — это будет OLEObject; тогда у вас может быть локальная переменная ctrl As MSForm.ComboBox, которую вы можете установить в свойство Object OLEObject - и оттуда у вас должен быть доступ к методу Focus. Если нет, попробуйте объявить ctrl As MSForm.Control.

Mathieu Guindon 28.05.2019 20:47

Фокус не работает, но Ctrl.Activate выполняет свою работу.

Foxhunt 28.05.2019 20:58

Другие вопросы по теме