Могу ли я использовать позднюю привязку для проверки наличия библиотеки перед ее использованием через раннее связывание?

Мне нравится использовать раннее связывание в моих проектах VBA, так как мне нравится автозаполнение имен методов и т.д. во время разработки. Мне также нравится уверенность в том, что компилятор предупредит меня, если я неправильно назвал имя метода.

Однако для использования раннего связывания мне нужно добавить ссылку на соответствующую библиотеку (например, "Microsoft Scripting Runtime" ). Это отлично подходит для "стандартных" библиотек, но иногда я хочу использовать библиотеку, которая может или не может присутствовать на пользовательской машине.

В идеале, я хочу отобразить полезное сообщение, если библиотека отсутствует (например, "xyz" не установлен на этом компьютере, и поэтому эта функция не может быть использована "). Если бы я использовал только последнее связывание, тогда я мог бы это сделать:

Dim o As Object
Set o = CreateObject("foo", "bar")

If o Is Nothing Then
    MsgBox "nope"
End If

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

Есть ли какой-либо путь вокруг этого catch-22?

Ответ 1

Не совсем.

Тем не менее, один из способов, которым я занимался этим в разработке, состоит в том, чтобы иметь две отдельные строки декларации. Я прокомментирую тот или иной вопрос в зависимости от того, выполняю ли я свою работу или выпускаю на производство. Вы можете оставить все остальное в одиночестве (включая строку CreateObject), а затем вам просто нужно запомнить, чтобы переключить прокомментированную строку и добавить/удалить ссылку.

Например:

Dim o As foo.bar   'Comment out for production'
'Dim o As Object    ''Comment out for dev work'
Set o = CreateObject("foo", "bar")

If o Is Nothing Then
    MsgBox "nope"
End If

Ответ 2

Вы можете создать модуль класса в качестве прокси для библиотеки объектов --- обернуть все методы, свойства и константы, необходимые для ваших других процедур.

Все эти процедуры будут использовать прокси-класс одинаково, поэтому вам не нужно будет пересматривать эти процедуры для переключения между ранним и поздним связыванием. И Intellisense покажет вам все, что вы выставляете с классом прокси.

Класс будет одной точкой управления для переключения между ранним и поздним привязкой. Вы упомянули Excel как один пример:

#Const DevStatus = "PROD"
#If DevStatus = "DEV" Then
    Private objApp As Excel.Application
    Private objBook As Excel.Workbook
    Private objSheet As Excel.Worksheet
#Else 'assume PROD
    Private objApp As Object
    Private objBook As Object
    Private objSheet As Object
#End If

Если есть вероятность, что Excel не может быть установлен на компьютерах любого пользователя, вы можете проверить его доступность во время инициализации класса.

Dim blnExcelAvailable As Boolean

Private Sub Class_Initialize()
    blnExcelAvailable = IsExcelAvailable()
End Sub

Private Function IsExcelAvailable() As Boolean
    Dim blnReturn As Boolean
    Dim objTest As Object

On Error GoTo ErrorHandler

    Set objTest = CreateObject("Excel.Application")
    blnReturn = True

ExitHere:
    On Error GoTo 0
    Set objTest = Nothing
    IsExcelAvailable = blnReturn
    Exit Function

ErrorHandler:
    blnReturn = False
    GoTo ExitHere
End Function

Затем ваши процедуры, которые используют прокси-класс, могут проверять свойство, чтобы увидеть, доступен ли Excel.

Public Property Get ExcelAvailable() As Boolean
    ExcelAvailable = blnExcelAvailable
End Property

Я думаю, что такой подход возможен, и он удовлетворяет вашим требованиям AFAICT. Однако я не уверен, разумно ли это. Вернемся к примеру Excel, вы можете сделать что-то подобное для управляемого подмножества своей объектной модели. Но если вам нужны все или большинство его методов, свойств и констант, класс прокси-сервера будет огромным делом.

Лично я бы не использовал этот подход. Это меньше работает для меня, чтобы управлять ранним/поздним связыванием как mwolfe02 и JP. описано. Однако мое впечатление, что это более обременительно в вашей ситуации, поэтому, возможно, вы готовы вкладывать больше усилий, чем я в чем-то подобном.