Основной проблемой является имя модуля, Constants
- оно вводит в заблуждение, поскольку ни общедоступная / глобальная переменная , ни общедоступное свойство только для получения не являются константы .
Боковой узел, константы, которые нельзя назначать неконстантным выражениям, не являются ограничением, специфичным для VBA.
Свойства являются совершенно допустимыми в стандартных модулях, и public getТолько свойства - это прекрасный способ показать значение, доступное только для чтения, которое необходимо построить во время выполнения.
публичные переменные очищаются при возникновении ошибки или остановке кода
Предполагается, что "когда происходит ошибка" включает нажатие Конец и эффективное завершение контекста выполнения, что справедливо для всего , выставленного где угодно, будь тоглобальная переменная, открытое свойство, объект или все, что существует в памяти во время выполнения ... и это просто обычные вещи - значение просто доступно по требованию в любое время.
Опять же, для этого не нужно иметь модуль класса, это вполне допустимо в стандартном модуле:
Option Explicit
Public Property Get MyString() As String
MyString = "\R;;" & Chr(163)
End Property
Если воссоздание строки каждый раз при обращении к объекту getter - проблема, то вынужен способ сохранить свое значение в вспомогательном поле - но тогда это вспомогательное поле (будь то в классе или в стандартном модуле) имеет значение только в том случае, если существует контекст выполнения, то есть у него точно такая же проблема, что и у глобальной переменной: выполнение остановлено, оно ушло.
Одним из решений может быть использование класса с атрибутом VB_PredeclaredId
, установленным в True
(по умолчанию False
).
VERSION 1.0 CLASS
BEGIN
MultiUse = -1 'True
END
Attribute VB_Name = "Class1"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = True
Option Explicit
Private internalString As String
Private Sub Class_Initialize()
internalString = "\R;;" & Chr(163)
End Sub
Public Property Get MyString() As String
MyString = internalString
End Property
И теперь VBA будет автоматически создавать экземпляр Class1
всякий раз, когда на него ссылаются, , как только на него ссылаются , и этот экземпляр остается "живым" до тех пор, пока оператор End
не будет явно выполнен или контекст выполненияв противном случае прекращается.Точно так же, как, скажем, класс UserForm
, вы получаете доступ к этому экземпляру по умолчанию , используя имя класса в качестве идентификатора:
Debug.Print Class1.MyString
Если экземпляр по умолчанию существовал при ссылке на Class1
internalString
возвращается.Если этого не произошло, то выполняется Class_Initialize
, а затем возвращается internalString
.