Свойство Worksheet.Columns запрашивает у меня RowIndex? - PullRequest
2 голосов
/ 25 сентября 2019

Если я напишу это в редакторе VBA:

Dim ws As Worksheet: set ws = ActiveSheet
ws.Columns(

IntelliSense покажет мне, казалось бы, не связанную подсказку:

_Default ( [RowIndex] , [ColumnIndex])

Свойство Worksheet.Columns принимает только номер индекса (столбца), насколько я вижу в документации .

Так почему меня спрашивают о RowIndex?Почему это относится к _Default (и что это такое)?

1 Ответ

3 голосов
/ 25 сентября 2019

Свойство Worksheet.Columns принимает только номер индекса (столбца), насколько я вижу в документации.

Нигде в документации не сказано, что свойство Columnsпринимает параметр, и, действительно, было бы неправильно упоминать это, потому что он не имеет:

Worksheet.Columns definition in Object Browser

Как Worksheet.Rows, Worksheet.Columns дает Range объект.Поэтому, когда вы «параметризируете» его, на самом деле происходит следующее:

Set foo = ws.Columns.[_Default](value)

Любой аргумент, который вы предоставляете, интерпретируется как аргумент неявного вызова члена по умолчанию для объекта Range, который был возвращен при вызове Columns.

Возможно, вы где-то читали, что членом Range по умолчанию является Value - и это не так.Элементом по умолчанию Range является скрытое свойство с именем [_Default] (квадратные скобки требуются в VBA, если вы хотите вызывать его явно, поскольку никакой допустимый идентификатор VBA не может начинаться с подчеркивания), которое принимает два необязательных параметра:

Range._Default hidden property in Object Browser

Когда вы читаете ("get") это свойство по умолчанию без предоставления каких-либо аргументов, это свойство по умолчанию возвращает вам Range.Value (то есть одинЗначение Variant для отдельной ячейки или массив 2D Variant для нескольких ячеек).Когда вы назначаете этому свойству по умолчанию, вы присваиваете Range.Value.

Но когда при чтении ("get") этого свойства по умолчанию предоставляются какие-либо аргументы, вы получаетевызов очень стандартного Range.Item свойства индексатора:

Range.Item definition in the object browser

Итак, что делает Columns, это просто берет ваш входной диапазон и выдает объект Range, разложенный втаким образом, что к нему можно получить доступ с помощью аргумента RowIndex - мы можем доказать это с помощью именованных аргументов, которые показывают, что этот код недопустим:

?Sheet1.Range("A1:C1").Columns.Item(ColumnIndex:=2).Address
>> "wrong number of arguments"

Как и этот эквивалентный код:

?Sheet1.Range("A1:C1").Columns(ColumnIndex:=2).Address
>> "error 1004"

Обратите внимание, что свойство _Default дает Variant, поэтому вышеуказанный вызов члена .Address может быть разрешен только во время выполнения (и вы не получите никакого intellisense для него, и компиляторне дрогнуть при любой опечатке, даже с указанным Option Explicit - вы получите ошибку 438 во время выполнения, хотя).

Лучше всего придерживаться безопасной земли с ранней привязкой и извлекать возвращеннуюссылка на объект в локальной переменной:

Dim foo As Range
Set foo = ws.Columns(1)

Debug.Print foo.Address '<~ early-bound w/intellisense & compile-time validation

TL; DR: вам предлагается ввести аргумент RowIndex, потому что вы совершаете вызов (хотя неявный один) в скрытое свойство _Default, которое принимает RowIndex аргумент.

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