Могу ли я использовать позднюю привязку, чтобы проверить существование библиотеки перед ее использованием через раннюю привязку? - PullRequest
3 голосов
/ 18 января 2012

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

Однако, чтобы использовать раннее связывание, мне нужно добавить ссылку на соответствующую библиотеку (например, «Среда выполнения сценариев Microsoft»). Это нормально для подобных «стандартных» библиотек, но иногда я хочу использовать библиотеку, которая может присутствовать или не присутствовать на компьютере пользователя.

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

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

If o Is Nothing Then
    MsgBox "nope"
End If

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

Есть ли способ обойти эту ловушку-22?

Ответы [ 2 ]

6 голосов
/ 19 января 2012

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

Все эти процедуры будут использовать прокси-класс одинаково, поэтому вам не нужно будет пересматривать эти процедуры для переключения между ранним и поздним связыванием. И 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. описано. Однако у меня сложилось впечатление, что это более обременительно в вашей ситуации, поэтому, возможно, вы готовы вкладывать больше усилий, чем я, во что-то вроде этого.

3 голосов
/ 18 января 2012

Не совсем.

Тем не менее, один из способов, с которым я столкнулся при разработке, - это две отдельные строки объявления. Я комментирую один или другой в зависимости от того, занимаюсь ли я разработкой или выпускаю в производство. Вы можете оставить все остальное в покое (включая строку 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
...