Excel VBA - переменная Scoping Const, доступная только текущему проекту

У меня есть Excel-надстройка для хранения UDF, а также личная рабочая тетрадь для хранения подпрограмм.

Внутри надстройки у меня есть модуль для констант, где у меня есть запись для идеальной газовой постоянной:

Global Const r = 8.314 'Same result using Global or Public

Эта "глобальная" константа может быть доступна из всех модулей в надстройке Excel и личной книге.

Моя проблема в том, что я хотел бы иметь возможность ограничить область действия этой переменной только модулями надстройки и никакими другими открытыми проектами. В противном случае мне нужно отслеживать во всех открытых проектах, какие переменные я объявляю глобальными. В конце концов, я стану как НАСА, запутав мои подразделения...

Спасибо всем за вашу помощь заранее.

2 ответа

Решение

Global является устаревшим ключевым словом; единственная разница между Global а также Public это то, что вы не можете использовать Global в модуле класса. предпочитать Public для согласованности.

Используйте малоизвестный Friend модификатор доступа, чтобы сделать член доступным везде внутри проекта, в котором он объявлен, но только внутри этого проекта.

Предостережение в том, что его можно использовать только в модуле класса и только для процедур - вы не можете сделать Friend Const,

Обходным путем может быть использование скрытого VB_PredeclaredId атрибут класса и установите его True - создать новый текстовый файл в Блокноте с таким содержанием:

VERSION 1.0 CLASS
BEGIN
  MultiUse = -1  'True
END
Attribute VB_Name = "StaticClass1"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = False
Option Explicit

Сохраните файл с .cls расширение, затем импортируйте его в свой проект.

Затем вы можете переименовать его в нечто более значимое и Friend Property Get член:

Friend Property Get R() As Single
    R = 8.314
End Property

И теперь вы можете использовать это значение, но только внутри проекта, который содержит этот класс. Из-за PredeclaredId атрибут, вам не нужно создавать New пример:

Debug.Print StaticClass1.R ' 8.314

К сожалению (?) VB_GlobalNamespace Атрибут не влияет на пользовательские классы VBA, поэтому квалифицирующий объект (предварительно объявленный экземпляр класса имеет то же имя, что и сам модуль класса - именно так UserForm1.Show может работать) требуется.

Предупреждение: может быть заманчиво сохранить состояние экземпляра (например, частные переменные уровня модуля) в экземпляре по умолчанию (особенно в формах), но его следует избегать, когда это возможно. Если вам нужно сохранить состояние, подумайте о работе с New экземпляр класса вместо. Экземпляры с состоянием по умолчанию более подвержены ошибкам, в частности потому, что временем жизни объекта управляет среда выполнения VBA, а не код пользователя. Если экземпляр по умолчанию перерабатывается / воссоздается, любое ранее сохраненное состояние сбрасывается до значений по умолчанию во время разработки.

Обратите внимание, что модули классов по умолчанию являются закрытыми, что уже делает их невидимыми для других ссылочных проектов. Вы можете изменить свойство Instancing класса, чтобы сделать его PublicNotCreatable, который изменит значение этого VB_Exposed приписывать True:

Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = True

Публичные классы могут быть доступны извне проекта, но не могут быть созданы напрямую с помощью New Ключевое слово (изменение значения VB_Creatable атрибут не действует в VBA). С открытым / открытым классом ссылочные проекты смогут вызывать Public члены, но не Friend из них:

Public Property Get UseMeAnywhere() As Long
    UseMeAnywhere = 42
End Property

Friend Property Get YouOnlySeeMeInThisProject() As Long
    YouOnlySeeMeInThisProject = 42
End Property

Исправлением будет добавление оператора Option Private в раздел объявлений модуля. Это ограничит область действия только проектом, в котором находится модуль, а не открытым проектом. Ссылка ниже из Документов Microsoft для того, чтобы сделать это специально.

Для получения дополнительной информации о масштабах и видимости см. Ссылку ниже из Документов Microsoft:

https://docs.microsoft.com/en-us/office/vba/language/concepts/getting-started/understanding-scope-and-visibility

https://docs.microsoft.com/en-us/office/vba/language/reference/user-interface-help/option-private-statement

edit 22.04.2009: Разберитесь с идентификатором переменной Public to Global, так как это не решило проблему.

Другие вопросы по тегам