Вкладка в список или комбинированный список на листе - PullRequest
0 голосов
/ 02 мая 2020

У меня есть массив, загруженный адресами ячеек, которые передаются в подпрограмму, которая обрабатывает порядок табуляции на листе. Я хочу иметь возможность поместить имя элемента управления, то есть «MyListBox» в этот массив, и моя функция обрабатывает его. Однако я не могу получить разрешение в методе .activate. Если я неявно назову элемент управления, он будет работать, но мне нужно, чтобы он «развернул / расширил макрос» до фактического имени элемента управления, чтобы я мог сказать Array (x) .Activate.

Вот код, который я возился безрезультатно. Я пробовал с и без декларации MSFORM. Я попытался объединить команду "ActiveSheet". & arr (x) и многое другое. Я почти уверен, что, возможно, упускаю что-то простое, но не могу найти это.

Sub TabIntercept()

Dim arr, a, x, nxt, sel
Dim cMyListBox As MSForms.ListBox

If TypeName(Selection) <> "Range" Then Exit Sub 'Exit if (eg) a shape is selected

Set sel = Selection.Cells(1) 'if multiple cells selected use the first...

arr = GetTabOrder(ActiveSheet.Name) 'this function loads the tab order from a table

If UBound(arr) = -1 Then
    Application.OnKey "{TAB}"
    Exit Sub
End If


For x = LBound(arr) To UBound(arr)

    If Left(arr(x), 3) = "lst" Or Left(arr(x), 3) = "cmb" Then 'Look for a control - they all start with lst/cmb

        Set cMyListBox = Sheets("Resources & Process").arr(x) 'HERE IS THE ISSUE
        arr(x).Activate
    End If

    If sel.Address() = sel.Parent.Range(arr(x)).Address() Then
        'loops back to start if at end...
        nxt = IIf(x = UBound(arr), LBound(arr), x + 1)
        sel.Parent.Range(arr(nxt)).Select
        Exit For
    End If
Next x

End Sub

1 Ответ

0 голосов
/ 02 мая 2020
Set cMyListBox = Sheets("Resources & Process").arr(x) 'HERE IS THE ISSUE

Сначала объявите переменную Worksheet для этого листа; свойство Workbook.Sheets возвращает Object, поэтому все эти вызовы членов неявно связаны с поздним связыванием, и вы кодируете с завязанными глазами без помощи компилятора.

Dim sheet As Worksheet
Set sheet = ActiveWorkbook.Worksheets("Resources & Process")

Обратите внимание на квалификатор ActiveWorkbook: если вы используйте вместо этого указанный c Workbook объект, используйте его. Но всегда учитывайте квалификацию вызовов Workbook, иначе вы неявно ссылаетесь на то, чем является ActiveWorkbook, и в конечном итоге это не будет ожидаемая книга.

Теперь, sheet.arr(x) isn ' не будет работать, так как IntelliSense теперь показывает вам, когда вы набираете этот . оператор точки: объект Worksheet должен будет предоставить индексированное свойство с именем arr, чтобы это работало.

Что вы хотите сделать, это получить OLEObject с именем независимо от значения arr(x).

Вы получаете OLE-объекты из свойства Worksheet.OLEObjects :

Dim oleControl As OLEObject
Set oleControl = sheet.OLEObjects(arr(x))

Если это удастся, вы нашли свой элемент управления MSForms - но он обернут в объект OLE, и теперь нам просто нужно развернуть его:

Set cMyListBox = oleControl.Object

Если это не удалось элемент управления MSForms несовместим с объявленным типом cMyListBox. Но теперь вы получаете IntelliSense и проверку во время компиляции для вызовов участников против него: если вы наберете cMyListBox., и есть Activate член, то вызов должен быть действительным во время выполнения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...