Я пытаюсь выполнить функцию CountIfs, где выполняются два критерия. Первая строка — «Утверждено», а вторая — Дата утверждения в отчетном месяце. CountIfs работает, когда существует только первый критерий, но когда я добавляю второй, я получаю ошибку несоответствия типа, и я не знаю, почему.
Код:
' Declarations
Dim sRoutine As String 'Routine’s Name
Dim lngStatus As Long
Dim lngLastRow As Long
Dim intRptMnth As Integer
Dim intRptYr As Integer
Dim lngAppvDate As Long
' Initialize Variables
lngLastRow = FindLastRow(strPSR_File, strCCL, 1)
lngStatus = Worksheets(strCCL).Range(FindLoc(strPSR_File, strCCL,"status")).Column
lngAppvDate = Worksheets(strCCL).Range(FindLoc(strPSR_File, strCCL,"Approved Date")).Column
intRptMnth = CInt(CalcRptMnthNum)
intRptYr = CalcRptYr
' Procedure
With Worksheets(strCCL)
CalcPCR_MTD_Cnt = Application.WorksheetFunction.CountIfs( _
Worksheets(strCCL).Range(Cells(2, lngStatus), Cells(lngLastRow,
lngStatus)), _
"=Approved", _
'********ERRORS HERE*****
Month(Worksheets(strCCL).Range("n2:n3")), _
intRptMnth)
'************************
End With
@ JNevil Обновлена строка до "Worksheets(strCCL).Range(.Cells(2, lngStatus), .Cells(lngLastRow, lngStatus))" - по-прежнему получается тот же результат
Также добавьте объявление ваших переменных вверху. Dim lngStatus as Long (если они еще не установлены). Гарантия того, что в этой переменной (и других подобных) есть числовое значение, а не диапазон.
@ JNevil Я отредактировал фрагмент кода, чтобы показать свои объявления, извините, мне нужно было добавить это раньше
Worksheets(strCCL).Range("n2:n3") возвращает двумерный массив 1x2. Month() ожидает один Date.
@GSerg Я думал, что это может быть проблемой. У вас есть рекомендация о том, как я могу сравнить даты в этом диапазоне с указанным значением? ИДК, как еще я мог сделать то, что я пытаюсь. Кстати, я новичок в VBA, поэтому, вероятно, есть лучший способ сделать это.
Создайте вариантный массив значений и выполните цикл, используя переменную в качестве счетчика.
@ScottCraner Есть ли способ сделать это в CountIfs? Или вы рекомендуете мне воссоздать функциональность CountIfs с помощью пользовательской функции?
Забавно, что функция задокументировано неправильно. Документация предполагает наличие одного диапазона и 29 параметров, которые являются фильтрами для этого диапазона. На самом деле есть пары параметров (один диапазон, один фильтр, снова), как и для листовая версия.
@GSerg Я тоже это заметил, когда пытался решить проблему
Вы можете заключить даты в скобки, если они меньше или равны концу месяца intRptMnth и больше или равны 1 того же месяца в countifs. Но еще одну вещь я заметил. Countifs требует, чтобы диапазоны были одинакового размера. Ваш первый диапазон является переменным, а второй установлен. Они должны быть одинакового размера.
@ScottCraner Спасибо за рекомендацию. Это сработало. Я обновлю код, чтобы показать правильную функцию
@Chris, если у вас все заработало, поместите новый код в качестве ответа и самостоятельно ответьте на вопрос. Не указывайте рабочий код в вопросе.
@ScottCraner Я пытался, но это не позволило мне ответить на вопрос. Я попробую снова.
Спасибо всем за помощь
Вероятно, вам следует отменить последние два редактирования, чтобы вернуть его к жизнеспособному вопросу. Сейчас код в вопросе работает. Он должен показать нерабочий код.
@ScottCraner Я откатил код к оригиналу, чтобы показать ошибку. Спасибо за помощь


Исправленный код:
' Declarations
Dim sRoutine As String 'Routine’s Name
Dim lngStatus As Long
Dim lngLastRow As Long
Dim intRptMnth As Integer
Dim intRptYr As Integer
Dim lngAppvDate As Long
' Initialize Variables
lngLastRow = FindLastRow(strPSR_File, strCCL, 1)
lngStatus = Worksheets(strCCL).Range(FindLoc(strPSR_File, strCCL, "status")).Column
lngAppvDate = Worksheets(strCCL).Range(FindLoc(strPSR_File, strCCL, "Approved Date")).Column
intRptMnth = CInt(CalcRptMnthNum)
intRptYr = CalcRptYr
' Procedure
With Worksheets(strCCL)
CalcPCR_MTD_Cnt = Application.WorksheetFunction.CountIfs( _
Worksheets(strCCL).Range(.Cells(2, lngStatus), .Cells(lngLastRow, lngStatus)), _
"=Approved", _
Worksheets(strCCL).Range(.Cells(2, lngAppvDate), .Cells(lngLastRow, lngAppvDate)), _
"> = " & DateSerial(intRptYr, intRptMnth, 1), _
Worksheets(strCCL).Range(.Cells(2, lngAppvDate), .Cells(lngLastRow, lngAppvDate)), _
"<" & DateSerial(Year(Date), Month(Date), 1) _
)
End With
Просто чтобы показать вариант метода массива:
Dim sRoutine As String 'Routine’s Name
Dim lngStatus As Long
Dim lngLastRow As Long
Dim intRptMnth As Integer
Dim intRptYr As Integer
Dim lngAppvDate As Long
' Initialize Variables
lngLastRow = FindLastRow(strPSR_File, strCCL, 1)
lngStatus = Worksheets(strCCL).Range(FindLoc(strPSR_File, strCCL, "status")).Column
lngAppvDate = Worksheets(strCCL).Range(FindLoc(strPSR_File, strCCL, "Approved Date")).Column
intRptMnth = CInt(CalcRptMnthNum)
intRptYr = CalcRptYr
' Procedure
With Worksheets(strCCL)
Dim apprv As Variant
apprv = .Range(.Cells(2, lngStatus), .Cells(lngLastRow, lngStatus)).Value
Dim dte As Variant
dte = .Range(.Cells(2, lngAppvDate), .Cells(lngLastRow, lngAppvDate)).Value
CalcPCR_MTD_Cnt = 0
Dim i As Long
For i = LBound(apprv, 1) To UBound(apprv, 1)
If apprv(i, 1) = "Approved" And Month(dte(i, 1)) = intRptMnth And Year(dte(i, 1)) = intRptYr Then CalcPCR_MTD_Cnt = CalcPCR_MTD_Cnt + 1
Next i
End With
Спасибо за ответ на вариант массива. Я не проверял это, чтобы убедиться, что это работает, но я ценю, что вы показали методологию.
Поставьте точку/точку
.передCellsв этой формуле и повторите.