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:
edit 22.04.2009: Разберитесь с идентификатором переменной Public to Global, так как это не решило проблему.