VBA Почему Application.Countif возвращает массив или ошибку 424

Я хотел бы посчитать количество подходящих элементов в массиве. Я пытался использовать Application.Countif

MyCount = Application.WorksheetFunction.CountIf(Myrange, val)

но это возвращает массив, полный ошибок, а не простой счет. Я также пытался использовать Application.WorksheetFunction.Countif но это вызывает 424 error,

В настоящее время я тестирую на листе с кратким списком имен в ячейках A1:A20, но в конечном итоге я планирую использовать этот код с очень большим CSV-файлом и хочу загрузить информацию в массив перед использованием CountIf (вместо использования диапазона).

Sub TestCount()
    Dim MyCount
    Dim Myrange As Variant
    Dim val As String
    val = "Addison"
    Myrange = ActiveSheet.Range("A1").CurrentRegion.Value
    MyCount = Application.WorksheetFunction.CountIf(Myrange, val)
    MsgBox (MyCount)
End Sub

Кто-нибудь может подсказать, что я сделал не так?

4 ответа

Решение

У вас есть несколько проблем.

Использование CountIf

Во-первых, если я правильно понимаю, вы намеренно пытаетесь использовать Application.WorksheetFunction.CountIf оператор на массив. Это только вызовет проблемы, так как CountIf (как подсказывает утверждение) - это "функция листа", а не "функция массива VBA".

То же самое создало решение, которое использует CountIf правильно, установив диапазон в листе, на котором CountIf Заявление выполняет свою работу. Если все, что вам нужно, это способ подсчитать значение в этом диапазоне, это путь.

Создание массива из диапазона

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

  1. Вы правы в том, что для создания массива путем присвоения диапазона переменной необходим вариант, но вы забыли круглые скобки, которые являются важной частью обозначения массива.

    Итак, вместо Dim Myrange As Variant ты должен использовать Dim Myrange () As Variant

  2. Установив MyRange как массив, теперь вы можете назначить значения массива, сказав MyRange = Range("x") где х - это область захвата. Вам не нужно (или хотите) использовать .Value за это. VBA автоматически сделает это за вас.

    Итак, в вашем случае вы хотите использовать CurrentRegion за Range("A1") что сделано так: MyRange = Range("A1").CurrentRegion, Вы также можете использовать строго определенный диапазон, например: MyRange = Range("A1:A12") или же MyRange = Range("C7:F14"),

    Примечание: я остановился на ActiveSheet потому что это не работает при назначении диапазонов для массивов. Предполагается, что вы используете активный лист, а текущая область предназначена для ячейки, указанной в Range("x") заявление.

Подсчет значений в массиве

В-третьих, как только вы создадите массив, вы не сможете использовать Countif (как указано выше). Вам нужно будет создать метод подсчета этого значения в массиве. Есть несколько соображений при этом.

  1. Поскольку массив, созданный из диапазона, будет двухмерным и может иметь более одного столбца, не следует использовать только один столбец. Вы захотите создать переменную, которая будет содержать количество строк и количество столбцов, чтобы вы могли просматривать весь массив. Что-то вроде этого:

    Dim Row As Long Dim Col As Long

  2. Вы захотите определить пределы своих циклов, используя UBound размеров массива. Что-то вроде этого:

    Dim RowNumber As Integer RowNumber = UBound(MyRange, 1) Dim ColNumber As Integer ColNumber = UBound(MyRange, 2)

Код для использования массива, чтобы найти ваш счет

Я думаю, что следующий код будет делать то, что вы хотите, используя массив, созданный так, как вы пытались:

Sub TestCount()

    Dim MyCount As Long
        MyCount = 0
    Dim MyRange() As Variant
        MyRange = Range("A1").CurrentRegion
    Dim val As String
        val = "Addison"
    Dim Row As Long
    Dim Col As Long
    Dim RowNumber As Long
        RowNumber = UBound(MyRange, 1)
    Dim ColNumber As Long
        ColNumber = UBound(MyRange, 2)

    For Col = 1 To ColNumber
        For Row = 1 To RowNumber
            If MyRange(Row, Col) = val Then MyCount = MyCount + 1
        Next Row
    Next Col

    msgbox MyCount

End Sub

Только потому, что эта лошадь уже недостаточно разбита... есть 1 вкладыш

Sub Button3_Click()
    MsgBox Application.WorksheetFunction.CountIf(Range("A1:a20"), "Addison")
End Sub

Попробуй это:

  Sub TestCount()
      Dim MyCount
      Dim Myrange As Range
      Dim val As String
      val = "Addison"
      Set Myrange = ActiveSheet.Range("A1:a20")
      MyCount = Application.WorksheetFunction.CountIf(Myrange, val)
      MsgBox (MyCount)
  End Sub

1) определить "Myrange" как ДИАПАЗОН, а не вариант.

2) используйте ключевое слово "set", чтобы назначить диапазон Myrange

3) укажите желаемый диапазон: "a1:a20", а не просто "a1"

Да, вы не объявили свой диапазон как тип диапазона, поэтому вы не установили диапазон.

Sub Macro1()
Dim val as String
Dim r As Range
Set r = Range("a1:a20")
val = "Addison"
MsgBox Application.WorksheetFunction.CountIf(r, val)
End Sub

или же

Sub CritSrh_Column()
Dim cell As Variant
Dim counter As Integer
For Each cell In Range("A1:A20")
'could use ("A:A") to search the whole column #not recommended#
'for dynamic rows, use end.xl('direction')
    If cell.Value = "Addison" Then
        counter = counter + 1
    End If
Next
MsgBox counter
End Sub
Другие вопросы по тегам