VBA: использование открытого свойства Get вместо Const (для не-Unicode символов) - PullRequest
0 голосов
/ 15 января 2019

У меня есть код VBA, в котором мне нужно определить постоянную строку, содержащую символы не-Unicode (£). Кто-то может знать, что VBA Editor не поддерживает не-Unicode и использует настройки Windows «System Locale» в региональных и языковых настройках для разбора / сопоставления этих символов. На компьютере, на котором я разрабатываю код, установлена ​​английская языковая система, но некоторые пользователи имеют эту настройку, как и другие языки, например, Китайский, который переводит строковую константу в знак вопроса (£ ->?).

Теперь £ = chr (163), однако вы не можете использовать chr как часть определения константы в VBA. Так что пока это разрешено :

public const mystring = "reference constant string with £"

это запрещено в VBA "

public const mystring = "reference constant string with " & chr(163).

Одним из способов является определение mystring как публичной / глобальной переменной:

Constants.bas

public mystring as string

и затем установите открытую переменную в начале выполнения кода или открытия Excel.

ThisWorkbook

Private Sub Workbook_Open()
    mystring = "reference constant string with " & chr(163).
End Sub

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

**. ЦБС

Public Property Get mystring () As String
    mystring = "\R;;" & Chr(163)
End Property

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

1 Ответ

0 голосов
/ 15 января 2019

Основной проблемой является имя модуля, 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

Если экземпляр по умолчанию существовал при ссылке на Class1internalString возвращается.Если этого не произошло, то выполняется Class_Initialize, а затем возвращается internalString.

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