代码之家  ›  专栏  ›  技术社区  ›  this

为什么某些类型缺少“Set”是运行时错误而不是编译错误?

vba
  •  3
  • this  · 技术社区  · 7 年前

    给定以下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.集合 ?

    2 回复  |  直到 7 年前
        1
  •  3
  •   Comintern    7 年前

    这在VBA语言规范中有解释。内部赋值的语义 With 块由语句是否为 Set 语句或 Let 声明。在这种情况下,它是一个 声明:

    With x
        .SomeThing = New Something
    End With
    

    注意,在VBA语法中,关键字 可选(过时):

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

    设置 声明 设置 关键字是必需的:

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

    内部 布洛克,那个 l-expression 基本上是UDT成员,但是如果 x 直接使用。

    当评估 表达式,语义如中所述 section 5.4.3.8

    静态语义。

    如果以下任一项为真,则此语句无效:

    • <表达式>不能是 5.6.2.2 )

    在那之后 5.6.2.2 (Evaluation to a simple data value) ,以下运行时语义适用(仅适用于规则):

    运行时语义。

    在运行时,简单的数据值value和value type是

    • 如果表达式值类型是特定类:

      • 如果源对象具有公共默认属性Get或public 默认函数,此默认成员参数列表为 与包含0个参数的参数列表兼容,简单 数据值值是将此默认成员计算为 一个简单的数据值。

      • 否则,如果源对象没有公共默认值 不支持此属性或方法)。

    因此,的运行时错误438 SomeThing As Something .

    Collection ,的 静态语义仍然适用,但它不能满足 静止的

    静态语义。

    • 分类为值表达式的表达式可以根据以下规则计算为简单数据值:

      • 如果表达式的类型是特定的,则声明该类的类型:

      • 如果此类具有公共默认属性Get或function,并且此默认成员参数列表与参数兼容 包含0个参数的列表,简单数据值计算重新启动为 如果此默认成员是表达式。

    收藏 .Item )只需要一个参数 Index . 在此代码中,未提供参数,因此参数列表不兼容:

    With x
        .SomeThing = New VBA.Collection
    End With
    

    因此 Argument Not Optional 编译错误。

        2
  •  1
  •   this    7 年前

    在打印问题时,我突然想到 VBA.Collection .Something = New VBA.Collection 作为一个 分配 默认成员。。。除了 Item Argument not optional 如果使用 Set

    相反,VBA类模块可能根本没有默认成员,因此没有索引属性+默认成员来触发编译时错误。然而,这也意味着在运行时才会发现错误的语法。