This is explained in the VBA Language Specification. The semantics of the assignment inside the With block is driven by whether or not the statement is a Set statement or a Let statement. In this context, it is a Let statement:
With x
.SomeThing = New Something
End With
Note that in the VBA grammar, the keyword Let is optional (obsolete):
let-statement = ["Let"] l-expression "=" expression
In a Set statement, the Set keyword is required:
set-statement = "Set" l-expression "=" expression
Inside of a With block, the l-expression is basically the UDT member, although the exact same behavior applies if x is used directly.
When evaluating a Let expression, the semantics are described in section 5.4.3.8:
Static Semantics.
This statement is invalid if any of the following is true:
- <expression> cannot be evaluated to a simple data value (section 5.6.2.2 ).
Following that to 5.6.2.2 (Evaluation to a simple data value), the following runtime semantics apply (applicable rule only):
Runtime semantics.
At runtime, the simple data value’s value and value type are
determined based on the classification of the expression, as follows:
Thus the runtime error 438 for SomeThing As Something.
With the Collection, the Let static semantics still apply, but it fails the static semantics of 5.6.2.2 (which gives the compile error). Again, the preceding inapplicable semantics are omitted:
Static semantics. The following types of expressions can be evaluated to produce a simple data value:
The default member of Collection is a function (.Item) that takes a single parameter Index. In this code, the parameter is not provided, so the argument list is incompatible:
With x
.SomeThing = New VBA.Collection
End With
Thus the Argument Not Optional compile error.