Я пытаюсь понять, как использовать такие вещи, как .count, с диапазоном, который я сохранил как переменную в VBA.
Я сделал следующую функцию, которая работает
Function test2() As Variant
test2 = Sheet12.Range("B1:B19").Count
End Function
Возвращается значение 19, поскольку в этом диапазоне 19 строк.
Когда я делаю следующее, он просто возвращает «#VALUE!» несмотря на то, что это то же самое, кроме того, как хранится диапазон
Function test2() As Variant
Dim Grada As Variant
Grada = Sheet12.Range("B1:B19")
test2 = Grada.Count
End Function
Может ли VBA использовать такие операторы, как .count, для диапазонов, если они были сохранены таким образом, или что мне не хватает?
Grada
— это Variant
, а не Object
, поэтому без использования ключевого слова Set
будет рассматриваться как значение. Другая тонкая проблема здесь — использование методов/свойств по умолчанию.
Sheet12.Range("B1:B19")
имеет скрытый элемент по умолчанию, который возвращает значения, поэтому во втором коде вы вернули массив (причем двумерный массив) из Variant
, который отражает содержимое этих 19 ячеек. Массив не является Object
, поэтому не имеет методов. Здесь важно отметить, что использование скрытого элемента по умолчанию означает, что вы не возвращаете Range
, как предполагали.
Set Grada = Sheet12.Range("B1:B19")
возможно, дал желаемый результат, но такое позднее связывание означает, что вы не можете использовать IntelliText/AutoComplete, чтобы помочь вам определить, какие методы и свойства доступны.
Другой вариант — понять, что генерируется двумерный массив, и обобщить, что можно выбрать любой блок ячеек:
Function test2() As Variant
Dim Grada As Variant
Grada = Sheet12.Range("B1:B19").Value2 'I have added this last bit to make the default member explicit
test2 = (UBound(Grada,1) - LBound(Grada,1) + 1) * (UBound(Grada,2) - LBound(Grada,2) + 1)
End Function
Я оставляю это как упражнение для ФП (причем простое упражнение), чтобы определить, почему эта формула работает. Использование UBound
и LBound
устраняет любые капризы в массивах с отсчетом от 0 или 1 - это то, что я теперь делаю по привычке, чтобы мой код по своей сути был безопаснее, если я копирую биты куда-то еще.
Нет, Grada
быть Variant
— это не то, что определяет тип назначения и использование или отсутствие использования свойств по умолчанию. Это наличие Set
.
@GSerg- Спасибо, исправлено для полноты, учитывая ответ Балаза.
@IzakNash: Понимание массивов (как считать и каковы границы) является важным фундаментальным навыком, но выходит за рамки этого вопроса и ответа. В Интернете есть множество руководств и статей, которые объяснят это с примерами.
Когда вы определяете переменную как Variant, она может одинаково хранить значения или объекты. Но VBA должен знать, каков тип назначенного элемента. Если это значение, то имени переменной достаточно в левой части выражения. Если элемент, который вы хотите сохранить, является объектом любого типа, необходимо использовать объявление Set
.
С помощью этого мода вы можете использовать переменную Grada с объектом в ней.
Function test2() As Variant
Dim Grada As Variant
Set Grada = Sheet12.Range("B1:B19")
test2 = Grada.Count
End Function
Я понимаю по кусочкам то, что вы здесь говорите. Попытка понять ваш код с некоторым успехом. '(UBound(Grada,1) Это должно дать мне 19, поскольку это верхняя граница моего массива - LBound(Grada,1) + 1) Это должно быть 2? поскольку нижняя граница равна 1 (UBound(Grada,2). Понятия не имею, что здесь происходит, поскольку массив имеет только одну запись?? Не могу найти никаких объяснений того, на что ссылается вторая переменная, с моим текущим уровнем понимания VBA - LBound(Grada,2) + 1)', а почему они вычитаются друг из друга, а затем умножаются, я совершенно запутался.