Свойство класса как аргумент ByRef не работает - PullRequest
1 голос
/ 02 июля 2019

Я использую функцию для изменения ряда строк, передавая их ByRef в качестве аргументов модифицирующей функции. Все строковые переменные вызывающей стороны изменяются, как и ожидалось, но один аргумент, который является свойством класса, не изменяется, это должно быть возможно? Основы класса: -

Private cRptRef As String

Public Property Get TestRefID() As String
    TestRefID = cRptRef
End Property

Public Property Let TestRefID(Test_Ref As String)
    cRptRef = Test_Ref
End Property

Функция для модификации строк имеет следующее объявление

Public Function GetTestFileNames(ByRef hdrFile As String, _
                                 ByRef calFile As String, _
                                 ByRef dataFile As String, _
                                 ByRef testRef As String _
                                 ) As Boolean

Вызов GetTestFilenames выглядит следующим образом:

If GetTestFileNames(HEADERpath, CALpath, RAWDATApath, _
                    ref) = False Then

Все строковые аргументы объявлены как глобальные строки и являются пустыми ("") перед вызовом. После вызова они обычно имеют содержимое типа "d: {путь к файлу {имя_файла.csv}. Таким образом, все эти операторы в функции заполняют целевые строки ОК.

hdrFile = Replace(userFile, "##", PT_Rpt.Info.FindNode(TEST_REF_HDRsuffix).data, , , vbTextCompare)
dataFile = Replace(userFile, "##", PT_Rpt.Info.FindNode(TEST_REF_DATAsuffix).data, , , vbTextCompare)
calFile = Replace(userFile, "##", PT_Rpt.Info.FindNode(TEST_REF_CALsuffix).data, , , vbTextCompare)

Но этот оператор не может присвоить что-либо своей целевой строке

testRef = Mid(userFile, InStrRev(userFile, Application.PathSeparator) + 1)
testRef = Left(testRef, InStrRev(testRef, "_") - 1)
Debug.Print "Class.TestRefID="; testRef

Оператор Debug.Print печатает ожидаемую строку, но внешняя ссылка не затрагивается. Это как-то связано с тем, что это собственность? Целевая строка Class.TestRefID вместо аргумента testRef. Если я заменяю свойство класса в списке аргументов на стандартную строковую переменную, а затем присваиваю это свойству свойству класса, тогда получаю ожидаемый результат, который кажется ненужной работой. Я что-то упускаю или это невозможно в VBA?

1 Ответ

4 голосов
/ 02 июля 2019

Выражение доступа к члену - это выражение , которое сначала должно быть оценено VBA, прежде чем его результат можно будет передать.

Если у меня есть Class1такой модуль:

Option Explicit
Public Foo As String

А затем процедура быстрого вызова:

Sub test()
    With New Class1
        bla .Foo
        Debug.Print .Foo
    End With
End Sub

Sub bla(ByRef bar As String)
    bar = "huh"
End Sub

Процедура test выведет пустую строку.

Причина этогопотому что когда вы передаете элемент параметру ByRef процедуры в VBA, вы не передаете ссылку элементу - вы передаете ссылку на значение, хранящееся вэтот член .

Таким образом, выражение доступа к члену оценивается, оценивается в "", поэтому "" передается ByRef в процедуру, которая присваивает его "huh", но вызывающая сторона не держит ссылку на значение "", поэтому она никогда не увидит назначенную строку "huh".

Если я заменимсвойство класса в списке аргументов со стандартной строковой переменной, а затем присвоить его классу proтогда я получаю ожидаемый результат, который кажется ненужной работой

Это не ненужная работа, это обязательный , иначе ничто не удерживает ссылку на результатвыражение члена.

Опять же, проблема real - это проблема проектирования, указанная Warcupine : функция не хочет byref-возвращать 4 значения, онахочет получить ссылку на этот объект и присвоить его свойства.

...