Вызов определенной пользователем функции в Sub VBA - PullRequest
2 голосов
/ 07 марта 2019

Я новичок в VBA. В настоящее время я пытаюсь применить цикл к пользовательской функции. Определенная функция выглядит следующим образом.

  Function CountColor(InRange As range, ColorIndex As Long, _
    Optional OfText As Boolean = False) As Long
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' CountColor
' This function counts the cells in InRange whose ColorIndex
' is equal to the ColorIndex parameter. The ColorIndex of the
' Font is tested if OfText is True, or the Interior property
' if OfText is omitted or False. If ColorIndex is not a valid
' ColorIndex (1 -> 56, xlColorIndexNone, xlColorIndexAutomatic)
' 0 is returned. If ColorIndex is 0, then xlColorIndexNone is
' used if OfText is Fasle or xlColorIndexAutomatic if OfText
' is True. This allows the caller to use a value of 0 to indicate
' no color for either the Interior or the Font.
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Dim R As range
Dim N As Long
Dim CI As Long

If ColorIndex = 0 Then
    If OfText = False Then
        CI = xlColorIndexNone
    Else
        CI = xlColorIndexAutomatic
    End If
Else
    CI = ColorIndex
End If


Application.Volatile True
Select Case ColorIndex
    Case 0, xlColorIndexNone, xlColorIndexAutomatic
        ' OK
    Case Else
        If IsValidColorIndex(ColorIndex) = False Then
            CountColor = 0
            Exit Function
        End If
End Select

For Each R In InRange.Cells
    If OfText = True Then
        If R.Font.ColorIndex = CI Then
            N = N + 1
        End If
    Else
        If R.Interior.ColorIndex = CI Then
            N = N + 1
        End If
    End If
Next R

CountColor = N


End Function

Я пытаюсь использовать эту функцию CountColor в Sub. Но он выдает ошибку времени выполнения 424.

Sub Summary()    
    LastColumn = Cells(1, Columns.Count).End(xlToLeft).Column
    LastRow = Cells(Rows.Count, 1).End(xlUp).Row

        For i = 2 To LastRow
        TOTALFAILS = CountColor((range(Cells(i, 4), Cells(i, LastColumn))), 38)
        Cells(i, LastColumn + 8) = TOTALFAILS

        Next i
End Sub

Не могли бы вы помочь мне выяснить, что я делаю не так? Любая помощь будет высоко оценена. Спасибо

Ответы [ 2 ]

1 голос
/ 07 марта 2019

Ваша CountColor функция ожидает ссылку на объект Range для первого параметра, но это не то, что вы ей даете:

TOTALFAILS = CountColor((range(Cells(i, 4), Cells(i, LastColumn))), 38)

Первый аргумент является результатом этого выражения:

(range(Cells(i, 4), Cells(i, LastColumn)))

Когда вы помещаете аргумент в скобки, вы передаете результат вычисления выражения, переданного ByVal (независимо от того, подпись функции указывает ByRef или нет).

Так почему тогда "объект требуется"? Разве выражение не оценивается как Range объект?

В классе Range есть скрытый член по умолчанию , который можно открыть в Обозревателе объектов (F2):

Members of 'Range'

Обратите внимание на скрытый / затененный _Default член.

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

Members of 'Collection'

Элемент по умолчанию может быть вызван неявно. Вот как вы можете сделать myCollection("someKey") для извлечения предмета, и это полностью эквивалентно myCollection.Item("someKey").

Элемент Range.[_Default] немного отличается тем, что его реализация будет "перенаправлять" к различным элементам, в зависимости от контекста: при вызове без параметров возвращается Range.Value - для диапазона из одной ячейки, это ячейка значение. Для диапазона из нескольких ячеек это двумерный вариантный массив, содержащий все значения.

Таким образом, когда вы передаете (someRange) в качестве аргумента, вы неявно передаете (someRange.[_Default]), , потому что класс имеет член по умолчанию, без параметров (ну, два параметра являются необязательными, поэтому вызов без параметров является допустимым).

Другими словами, вы передаете массив 2D-вариантов в CountColor, а не Range ссылку на объект.

И именно поэтому VBA выдает ошибку времени выполнения 424 «Требуется объект» - потому что для вызова требуется объект, но объект не был предоставлен.

Как уже ответил Витята , удаление лишних скобок исправит это, потому что без лишних скобок вы больше не заставляете ByVal вычислять Range объект / выражение.

1 голос
/ 07 марта 2019

Существует один "(" больше, чем нужно при вызове функции, поэтому она не получает правильные параметры. Попробуйте это:

CountColor(Range(Cells(i, 4), Cells(i, LastColumn)), 38)

Чтобы убедиться, что вы передаете ожидаемый параметр, нажмите Ctrl + I , находясь на линии. VBEditor поможет:

enter image description here

Как правило, при работе с объектами Range() и Cells() обязательно обращайтесь к их рабочим листам и рабочим книгам , чтобы избежать ошибок 1004 . В случае примера это должно быть так:

With ThisWorkbook.Worksheets(1)
    For i = 2 To LastRow
        TOTALFAILS = CountColor(.Range(.Cells(i, 4), .Cells(i, LastColumn)), 38)
        .Cells(i, LastColumn + 8) = TOTALFAILS
    Next i
End With
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...