VBA Macro запускает разные макросы из открытой книги - PullRequest
0 голосов
/ 06 сентября 2018

У меня есть довольно простой кусок кода на листе ThisWorkbook в VBA. Как вы можете видеть, этот код заполняет комбинированный список именем сервера. Идея состоит в том, что пользователь выберет этот сервер после открытия рабочей книги, а затем активирует макрос на основе серверной переменной, чтобы заполнить второй комбинированный список списком баз данных.

Чтобы заполнить этот комбинированный список, макрос CB_Server_Change использует соединение ADODB для обращения к серверу и извлечения имен базы данных для выбора пользователем.

Однако при открытии этой книги она зависает и в конечном итоге отлаживается с невозможностью установить соединение с сервером. Что неудивительно, потому что при открытии книги у пользователя не было возможности выбрать какие-либо переменные.

При попытке отладки я обнаружил, что при переходе через .AddItem "M01-SQL-P09-DB2" для перехода к строке .ListIndex = 0 он просто переходит к макросу на рабочем листе (меню управления), где комбинированный список находится и пытается запустить макрос CB_Server_Change?

Я не могу понять, почему он не просто заполняет поле со списком, как запрошено, я вообще не ссылаюсь на лист меню управления или макрос CB_Server_Change в макросе ThisWorkbook Workbook_Open ().

    Private Sub Workbook_Open()

    With Application
        .Calculation = xlManual
        .EnableEvents = False
        .ScreenUpdating = False
    End With

        With Worksheets("Control Menu").CB_Server
            .Clear
            .AddItem "Select Server"
            .AddItem "M01-SQL-P09-DB2"
            .ListIndex = 0
        End With

    'Restore the settings.
    With Application
        .Calculation = xlAutomatic
        .EnableEvents = True
        .ScreenUpdating = True
    End With

End Sub

кто-нибудь сталкивался с этим раньше? Любая помощь будет высоко ценится.

Заранее спасибо

Ответы [ 2 ]

0 голосов
/ 06 сентября 2018

Я думаю, вы можете вызвать событие изменения при заполнении. Попробуйте добавить публичный var, называемый blnSetup или что-то в этом роде. Установите значение true при заполнении и false после, затем проверьте эту переменную в событии изменения.

blnSetup=True
With Worksheets("Control Menu").CB_Server
     .Clear
     .AddItem "Select Server"
     .AddItem "M01-SQL-P09-DB2"
     .ListIndex = 0
End With
blnSetup=false

затем в комбо-событии

if not blnSetup then
     ......
end if
0 голосов
/ 06 сентября 2018

Назначение ListIndex=0 запускает событие OnChanged, как если бы пользователь выбирал элемент. Мне удалось воспроизвести это в Excel 2013 с помощью:

  • Создание пустого XLSM
  • Добавление ActiveX ComboBox на лист1
  • Выбор Developer | View Code, который создал функцию ComboBox1_Change в Sheet1.
  • Добавление Debug.Print "Changed" к ComboBox1_Change
  • В ThisWorkbook, добавив подпункт:

    Private Sub Workbook_Open()
        Debug.Print "Opening"
        With Sheet1.ComboBox1
            .Clear
            .AddItem "foo"
            .AddItem "bar"
            .ListIndex = 0
        End With
        Debug.Print "done opening"
    End Sub
    
  • Сохранение, закрытие и повторное открытие. Результат (в Немедленном окне):

    Opening
    Changed
    done opening
    

Так что вы можете попробовать любую из двух вещей:

  1. Не задано ListIndex. Если я закомментирую эту строку, событие Change не сработает (я не получаю сообщение «Изменено» в окне «Немедленно»).

  2. Используйте идею @Nathan_Sav: вручную скажите код со списком Change, чтобы он ничего не делал.

Пример второй идеи:

В ThisWorkbook добавить переменную:

Option Explicit

Public Initialized As Boolean     ' <--- new

Private Sub Workbook_Open()
    Debug.Print "Opening"
    Initialized = False           ' <---
    With Sheet1.ComboBox1
        .Clear
        .AddItem "foo"
        .AddItem "bar"
        .ListIndex = 0
    End With
    Initialized = True            ' <---
    Debug.Print "done opening"
End Sub

В Sheet1 добавить:

Option Explicit

Private Sub ComboBox1_Change()
    If ThisWorkbook.Initialized Then  ' <--- test the variable
        Debug.Print "Changed"
    End If
End Sub

Таким образом, если вы все еще инициализируете (все еще в Workbook_Open), вы можете пропустить код, который вы не хотите запускать. Когда я открываю книгу с указанным выше кодом, я не получаю сообщение «Изменено» в окне «Немедленно», указывающее на то, что тест Initialized работает как положено.

...