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