Почему отсутствует `Set` для определенных типов ошибки времени выполнения, а не ошибки компиляции? - PullRequest
0 голосов
/ 30 августа 2018

Учитывая следующий код VBA, предполагая, что Something является просто модулем класса VBA ....

Public Type Foo
    SomeThing As Something
End Type

Public Sub TestFoo()
    Dim x As Foo
    With x
        'Correct way to do it
        Set .someThing = New Something
    End With

    With x
        'This is wrong but realized only as a RTE 
        '438: Object doesn't support this property or method
        .SomeThing = New Something
    End With
End Sub

Напротив, если вы измените тип на что-то вроде VBA.Collection, как показано ниже:

Public Type Foo
    SomeThing As VBA.Collection
End Type

Public Sub TestFoo()
    Dim x As Foo

    With x
        .SomeThing = New VBA.Collection
    End With
End Sub

Теперь это ошибка компиляции, с Argument Not Optional. Это, очевидно, неправильно, но почему это ошибка времени компиляции только с VBA.Collection?

Ответы [ 2 ]

0 голосов
/ 30 августа 2018

Это объясняется в спецификации языка VBA. Семантика присваивания внутри блока With определяется тем, является ли оператор оператором Set или оператором Let. В этом контексте это Let оператор:

With x
    .SomeThing = New Something
End With

Обратите внимание, что в грамматике VBA ключевое слово Let является необязательным (устарело):

let-statement = ["Let"] l-expression "=" expression

В операторе Set требуется ключевое слово Set:

set-statement = "Set" l-expression "=" expression

Внутри блока With l-expression в основном является элементом UDT, хотя точно такое же поведение применяется, если x используется напрямую.

При оценке выражения Let семантика описана в разделе 5.4.3.8 :

Статическая семантика.

Это утверждение недопустимо, если выполняется любое из следующих условий:

  • не может быть оценено как простое значение данных (раздел 5.6.2.2 ) .

После этого к 5.6.2.2 (Оценка для простого значения данных) применяется следующая семантика времени выполнения (только применимое правило):

Семантика времени выполнения.

Во время выполнения значение простого типа данных и тип значения определяется на основании классификации выражения следующим образом:

  • Если типом значения выражения является определенный класс:

    • Если исходный объект имеет общедоступное свойство Get по умолчанию или общедоступное функция по умолчанию, и список параметров этого члена по умолчанию совместим со списком аргументов, содержащим 0 параметров, простой Значение значения данных является результатом оценки этого элемента по умолчанию как простое значение данных.

    • В противном случае, если исходный объект не имеет общедоступного значения по умолчанию Свойство Get или общедоступная функция по умолчанию, ошибка времени выполнения 438 (Объект не поддерживается это свойство или метод).

Таким образом, ошибка времени выполнения 438 для SomeThing As Something.

При Collection статическая семантика Let по-прежнему применяется, но она не соответствует семантике static из 5.6.2.2 (которая дает ошибку компиляции). Опять же, предыдущая неприменимая семантика опущена:

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

  • Выражение, классифицированное как выражение значения, может оцениваться как простое значение данных на основе следующих правил:

    • Если объявленный тип выражения является конкретным классом:

    • Если у этого класса есть общедоступное свойство или функция по умолчанию, и список параметров этого члена по умолчанию совместим с аргументом список, содержащий 0 параметров, простая оценка значений данных перезапускается как если этот элемент по умолчанию был выражением.

Элементом по умолчанию Collection является функция (.Item), которая принимает один параметр Index. В этом коде параметр не указан, поэтому список аргументов несовместим:

With x
    .SomeThing = New VBA.Collection
End With

Таким образом Argument Not Optional ошибка компиляции.

0 голосов
/ 30 августа 2018

При наборе вопроса меня поразило, что VBA.Collection имеет члена по умолчанию. Таким образом, компилятор интерпретировал .Something = New VBA.Collection как присвоение члену по умолчанию ... за исключением того, что Item является индексированным свойством. Это объясняет, почему мы получаем Argument not optional, что было бы довольно странной ошибкой для оператора Set.

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

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