Ваша CountColor
функция ожидает ссылку на объект Range
для первого параметра, но это не то, что вы ей даете:
TOTALFAILS = CountColor((range(Cells(i, 4), Cells(i, LastColumn))), 38)
Первый аргумент является результатом этого выражения:
(range(Cells(i, 4), Cells(i, LastColumn)))
Когда вы помещаете аргумент в скобки, вы передаете результат вычисления выражения, переданного ByVal
(независимо от того, подпись функции указывает ByRef
или нет).
Так почему тогда "объект требуется"? Разве выражение не оценивается как Range
объект?
В классе Range
есть скрытый член по умолчанию , который можно открыть в Обозревателе объектов (F2):

Обратите внимание на скрытый / затененный _Default
член.
Если вы знакомы с классом Collection
, вам может быть известно, что его член Item
является членом этого класса по умолчанию:

Элемент по умолчанию может быть вызван неявно. Вот как вы можете сделать myCollection("someKey")
для извлечения предмета, и это полностью эквивалентно myCollection.Item("someKey")
.
Элемент Range.[_Default]
немного отличается тем, что его реализация будет "перенаправлять" к различным элементам, в зависимости от контекста: при вызове без параметров возвращается Range.Value
- для диапазона из одной ячейки, это ячейка значение. Для диапазона из нескольких ячеек это двумерный вариантный массив, содержащий все значения.
Таким образом, когда вы передаете (someRange)
в качестве аргумента, вы неявно передаете (someRange.[_Default])
, , потому что класс имеет член по умолчанию, без параметров (ну, два параметра являются необязательными, поэтому вызов без параметров является допустимым).
Другими словами, вы передаете массив 2D-вариантов в CountColor
, а не Range
ссылку на объект.
И именно поэтому VBA выдает ошибку времени выполнения 424 «Требуется объект» - потому что для вызова требуется объект, но объект не был предоставлен.
Как уже ответил Витята , удаление лишних скобок исправит это, потому что без лишних скобок вы больше не заставляете ByVal
вычислять Range
объект / выражение.