Глобальные переменные с поздним связыванием? - PullRequest
0 голосов
/ 15 мая 2018

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

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

Мой код, как показано ниже:

On Error Resume Next
strGUID = "{420B2830-E718-11CF-893D-00A0C9054228}"
ThisWorkbook.VBProject.References.AddFromGuid GUID:=strGUID, Major:=1, Minor:=0

Dim Dic1 As Object
Set Dic1 = CreateObject("Scripting.Dictionary")
Dim Dic2 As Object
Set Dic2 = CreateObject("Scripting.Dictionary")

Что если я хочу объявить объект глобального словаря с поздним связыванием? Похоже, VBA не позволит мне размещать какой-либо код вне подпрограмм (кроме объявлений).

Как я могу объявить объект глобального словаря, не требуя от конечного пользователя настройки ссылки на библиотеку самому? Должен ли я надеть следующее?

Dim Dic1 As Object
Dim Dic2 As Object

Sub Prog1()
    On Error Resume Next
    strGUID = "{420B2830-E718-11CF-893D-00A0C9054228}"
    ThisWorkbook.VBProject.References.AddFromGuid GUID:=strGUID, Major:=1, Minor:=0

    Set Dic1 = CreateObject("Scripting.Dictionary")
    Set Dic2 = CreateObject("Scripting.Dictionary")
End Sub

Ответы [ 2 ]

0 голосов
/ 15 мая 2018

Глобальные переменные действительно не нужны и их следует избегать.Однако, если вы решили использовать их по своим собственным причинам, вы можете поместить их в событие Workbook_Open:

Option Explicit

Dim Dic1 As Object
Dim Dic2 As Object

Private Sub Workbook_Open()

    Set Dic1 = CreateObject("Scripting.Dictionary")
    Set Dic2 = CreateObject("Scripting.Dictionary")

End Sub

Таким образом, он будет создавать объект при каждом открытии книги.

0 голосов
/ 15 мая 2018

Как и сам код VBA, ссылки на проекты волшебным образом не исчезают, когда ваш пользователь открывает рабочую книгу хоста.Они сохраняются вместе с кодом в главном документе.

Итак, предпосылка вашего вопроса неверна: пользователям никогда не нужно подправлять ссылки на проекты.

Также библиотека типов Scripting Runtimeстандартная проблема и была поставлена ​​точно такая же версия на каждой машине Windows, построенной в этом столетии (даже до этого), что означает, что если ваш код не должен работать на Mac, нет необходимости в позднем связывании библиотеки времени выполнения сценариев.

И если ваш код должен быть запущен на Mac, библиотека все равно не будет выполнять позднюю привязку, потому что не будет найдена на хост-машине, поэтому поздняя привязка среды выполнения сценариев служит только для глупых опечатоки представить другие легко устраняемые ошибки, которые IntelliSense помогает предотвратить.


ThisWorkbook.VBProject.References.AddFromGuid GUID:=strGUID, Major:=1, Minor:=0

Это устраняет всю цель позднего связывания: это использование библиотеки расширяемости VBIDE (которая требует пониженного макросанастройки безопасности), чтобы программно добавить ссылку, которую вы можете легко добавить во время разработки через* Меню Инструменты VBE.

Код с поздней привязкой вообще не нуждается в ссылке.Не во время компиляции, не во время выполнения.

Добавьте ссылку, сохраните, затем объявите ваши объекты As Scripting.Dictionary и воспользуйтесь преимуществами раннего кода.

Set Dic1 = New Scripting.Dictionary

Это все, что вам нужно.


Что если я хочу объявить объект глобального словаря с поздним связыванием?Похоже, VBA не позволит мне размещать какой-либо код вне подпрограмм (кроме объявлений).

Позднее связывание ничем не отличается от раннего связывания в этом аспекте.Разница между only между кодом с поздним и ранним связыванием является предложением As объявления:

Private foo As Object ' no compile-time type knowledge: late-bound
Private bar As Dictionary ' compile-time type knowledge: early-bound

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

При этом в реестре выполняется поиск ProgID для поиска библиотеки и тип:

Set foo = CreateObject("Scripting.Dictionary")

Используются ссылки на проект:

Set foo = New Scripting.Dictionary

Оба верны, и оба будут работать против ранних или поздних объявлений.За исключением того, что если у вас уже есть ссылка на библиотеку типов, на самом деле нет необходимости нажимать на реестр, чтобы найти эту библиотеку - просто New it up!

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