newInstanceOfMe.targetWksht = targetWksht
Этот оператор создает уровень ошибки качество кода результат проверки для Требуемое значение проверка в Rubberduck (открытыйисточник надстройки VBIDE, которым я управляю). Инспекция объясняет ситуацию следующим образом:
Объект используется там, где требуется значение
Компилятор VBA не выдает ошибку, если объект используется вместо, которое требует тип значения и объявленный тип объекта, не имеет подходящего члена по умолчанию. Почти при любых обстоятельствах это приводит к ошибке времени выполнения 91 «Объект или С переменной блока не установлено» или 438 «Объект не поддерживает это свойство или метод» в зависимости от того, имеет ли объект значение «Ничего» или нет,который сложнее обнаружить и указывает на ошибку.
В VBA существует два типа присвоений: присвоение значения (Let
) и справочное присвоение (Set
). Ключевое слово Let
является избыточным / необязательным / устаревшим для присвоений значений:
Dim foo As Long
foo = 2 + 2
Let foo = 2 + 2 '<~ exactly equivalent to the above
Поэтому, если ключевое слово Set
не присутствует, VBA пытается выполнить присвоение значений. Если у объекта есть член по умолчанию , это может сработать - спецификации VBA определяют, как механизмы let-coercion делают это. Вот как вы можете присвоить Range
значению:
Sheet1.Range("A1") = 42
Это неявно присвоение Range.Value
через неявный вызов члена для Range.[_Default]
, скрытое свойствокласс Range
.
Если бы правая часть присваивания была также объектом, то с обеих сторон оператора происходило бы принудительное приведение:
Sheet1.Range("A1") = Sheet1.Range("B1") '<~ implicit default member calls galore!
Sheet1.Range("A1").Value = Sheet1.Range("B1").Value
Номы не смотрим Range
здесь, мы смотрим на UserForm
, а UserForm
не имеет члена по умолчанию, поэтому принудительное приведение не может произойти ... но компилятор победил 'Это можно проверить, поэтому код все равно запускается ... и взорвется во время выполнения.
Итак, мы смотрим на присваивание Let
с обеими сторонами, содержащими ссылку на объект, длятип класса, который не определяет член по умолчанию.
Something.SomeObject = someOtherObject
Но VBA не волнует, что нет члена по умолчанию - потому что нет ключевого слова Set
, он старается изо всех силто, что вы сказали ему сделать, и привести эти объекты к значениям ... и не получится, очевидно.
ЕслиSomething.SomeObject
(левая сторона) равно Nothing
, тогда попытка let-coercion попытается вызвать несуществующий элемент по умолчанию - но поскольку ссылка на объект Nothing
, вызов недопустим, и возникает ошибка 91.
Если Something.SomeObject
уже содержит действительную ссылку на объект, то попытка let-coercion продвинется на один шаг дальше и завершится неудачно с ошибкой 438, потому что нет элемента по умолчанию для вызова.
Если Something.SomeObject
имеет элемент по умолчанию (а ссылка не Nothing
), тогда присвоение значения выполнено успешно, ошибка не возникает ... но ссылка на объект не была назначена, и это может бытьнебольшая ошибка!
Добавление ключевого слова Set
делает назначение справочным назначением , и теперь все работает нормально.