Почему тип возвращаемого значения функции Worksheet.Cells изменяется в зависимости от переменной присваивания? - PullRequest
0 голосов
/ 04 августа 2020

У меня есть следующий код макроса.

Sub display_name()
    Dim strName As String
    Dim nameCell As Range
        
    strName = ActiveSheet.Cells(1, 1) 'String
    Set nameCell = ActiveSheet.Cells(1, 1) 'Range Object
    
    MsgBox "Content: " & strName & ", " & nameCell.Value
End Sub

Значение MsgBox:

Содержимое: Hello world, Hello world

В первом case ActiveSheet.Cells метод возвращает строку, а во второй строке тот же метод возвращает объект Range.

Согласно документации vba, Worksheet.Cells возвращает объект диапазона. Я исхожу из опыта Java и считаю такое поведение неуместным.

У меня есть следующие вопросы:

  1. Почему возвращается тип Worksheet.Cells зависит от типа переменной, которой он назначен?
  2. Почему VBA допускает такое поведение?

1 Ответ

2 голосов
/ 04 августа 2020

Когда вы используете выражение Set в VBA, вы назначаете объектную ссылку объектной переменной. На большинстве языков у вас нет этой Set -команды, вместо этого вы назначаете ссылку с помощью = или :=, но в VBA вы должны использовать Set.

Если вы опускаете Set и попытайтесь назначить объект переменной, вы получите ошибку времени выполнения 438. За одним исключением:

VBA имеет концепцию Элемент по умолчанию . Каждый класс может иметь член по умолчанию (не у всех классов он есть!). VBA будет неявно ссылаться на член по умолчанию, если вы используете объект без указания члена, и вы не ссылаетесь на ссылку этого объекта (например, используя Set или передавая объект в качестве параметра, когда объект ожидается).

Этот элемент по умолчанию пригодится в нескольких случаях. Возьмем, к примеру, Collection, где вы можете получить доступ к его членам через индекс, как если бы это был простой массив. Таким образом, вы пишете MyCollection(1) для доступа к первому члену - на самом деле вы вызываете функцию Item, которая является членом коллекции по умолчанию.

Этот член по умолчанию , однако , также может привести к путанице. Если вы передаете объект в качестве параметра подпрограмме и параметр определен как тип Variant, передаст ли VBA ссылку на объект или значение члена по умолчанию?

Если вы хотите знать член класса по умолчанию, go в обозревателе объектов [F2] и найдите член с синим значком. Этот ответ объясняет его использование, включая то, как показывать скрытые элементы.

По сути, член Range по умолчанию ... сложен. Однако, если диапазон содержит только одну ячейку, это значение этой ячейки (насколько я знаю, это член Value2). Вы обнаружите, что чаще всего доступ к значению ячейки осуществляется с использованием члена по умолчанию - как вы это делали в своем примере кода. Но я бы посоветовал писать явно strName = ActiveSheet.Cells(1, 1).Value - не оставляет места для недоразумений.

Если вас интересует более подробная информация, прочтите эту статью Rubberduck . И вот интересный вопрос по SO о реальном члене по умолчанию для Range. И если вы все еще не достаточно запутались, прочтите это .

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