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
Заявление выполняет свою работу. Если все, что вам нужно, это способ подсчитать значение в этом диапазоне, это путь.
Создание массива из диапазона
Во-вторых, если вам действительно нужно вывести элементы из рабочего листа и в массив (например, если вы планируете работать с этими значениями так, чтобы не влиять на рабочий лист), вы должны знать, что у вас есть только частично решен вопрос о создании массива значений из диапазона выбора.
Вы правы в том, что для создания массива путем присвоения диапазона переменной необходим вариант, но вы забыли круглые скобки, которые являются важной частью обозначения массива.
Итак, вместоDim Myrange As Variant
ты должен использоватьDim Myrange () As Variant
Установив
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
(как указано выше). Вам нужно будет создать метод подсчета этого значения в массиве. Есть несколько соображений при этом.
Поскольку массив, созданный из диапазона, будет двухмерным и может иметь более одного столбца, не следует использовать только один столбец. Вы захотите создать переменную, которая будет содержать количество строк и количество столбцов, чтобы вы могли просматривать весь массив. Что-то вроде этого:
Dim Row As Long Dim Col As Long
Вы захотите определить пределы своих циклов, используя
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