为什么此CountIf函数返回“ 0”?

时间:2020-05-13 22:10:51

标签: excel vba countif

实际情况

我有一个带有用户表单的主工作簿(Wb)-文件浏览器(屏幕截图1)和结果的Sheet2(屏幕截图2)

我有一个源工作簿,该工作簿中有大量数据(14000行),坦白说是一团糟。.根据我的计算,源工作簿中只有两列是相关的:第8列(“正确日期”)和第30列(数值)。 关于第8列的重要说明:只有每月第一行的行才与我相关。含义:01.01。,01.02。,01.03。,01.04。等等。每隔一行都应该忽略。

我使用Wb搜索源工作簿(wb.Source)以应用以下计算:

任务1 :如果满足某些条件,则计算平均价值

任务2 :如果满足以下条件,则对行进行计数:

  • 如果ws.Source中的行的第8列中的日期=“ 01.01”,而第30列中的数值为<50,则计数并在Wb的工作表2中的单元格B8中输入结果
  • 如果ws.Source中的行的第8列中的日期为“ 01.01”,而第30列的日期为> 50和<100,则计数并在Wb的工作表2中的单元格B9中输入结果
  • 如果ws.Source中的行在第8列=“ 01.01”中有日期,并且第30列> 100,则计数并在Wb的第2页的单元格B10中输入结果

应该每月应用一次。

然后将结果添加到我的Wb Sheet2。

我的问题/疑问

1。关于任务2:我的CountIf函数每个月的结果为“ 0”,我不知道为什么?请参阅我的Wb结果表(屏幕截图2)中的屏幕截图以及wb.Source的行示例(屏幕截图3)

2。关于任务1:到目前为止,计算仍然可以进行,但是我如何确保仅考虑每个月第一天的行而忽略其他所有内容?

3。是否有可能限制计算的范围,从一定的日期(倒计数)开始,仅计算过去的12个月。含义:要在用户表单中设置日期(月/年),并仅考虑过去12个月中的行进行计算?如果未设置日期,则“今天”应为起点。我认为必须从代码中删除Const = YEAR,因为肯定存在wb.Source包含不同年份的行的可能性。

我将不胜感激!

Private Sub CommandButton1_Click() ' select file    
    Dim fname As Variant
    With Me
        fname = Application.GetOpenFilename("Excel File(s) (*.xls*),*.xls*", , "Select FIle", , False)
        If fname <> "False" Then .TextBox1.Text = fname
    End With
End Sub

'calculate avarage
Private Sub CommandButton2_Click() ' update averages
    Const YEAR = 2019

    ' open source workbook
    Dim fname As String, wbSource As Workbook, wsSource As Worksheet
    fname = Me.TextBox1.Text

    If Len(fname) = 0 Then
        MsgBox "No file selected", vbCritical, "Error"
        Exit Sub
    End If

    Set wbSource = Workbooks.Open(fname, False, True) ' no link update, read only
    Set wsSource = wbSource.Sheets("Sheet1") ' change to suit

    Dim wb As Workbook, ws As Worksheet
    Set wb = ThisWorkbook
    Set ws = wb.Sheets("Sheet2") '

    ' scan down source workbook calc average
    Dim iRow As Long, lastRow As Long
    Dim sMth As String, iMth As Long
    Dim count(12) As Long, sum(12) As Long

    lastRow = wsSource.Cells(Rows.count, 1).End(xlUp).Row
    For iRow = 1 To lastRow
        If IsDate(wsSource.Cells(iRow, 8)) _
                And IsNumeric(wsSource.Cells(iRow, 30)) Then
            iMth = Month(wsSource.Cells(iRow, 8))   ' col H
            sum(iMth) = sum(iMth) + wsSource.Cells(iRow, 30) ' Col AD
            count(iMth) = count(iMth) + 1
        End If
    Next

    'calculate number of rows (CountIf)
    Dim x As Long
    Dim m As Variant

    For x = 1 To 12
        m = "01." & Format(x, "00")

        ws.Cells(8, 1 + x) = _
        Application.WorksheetFunction.CountIfs(wsSource.Columns(8), m & "*", _
        wsSource.Columns(30), "<=" & 50)

        ws.Cells(9, 1 + x) = _
        Application.WorksheetFunction.CountIfs(wsSource.Columns(8), m & "*", _
        wsSource.Columns(30), ">" & 50, wsSource.Columns(30), "<=" & 100)

        ws.Cells(10, 1 + x) = _
        Application.WorksheetFunction.CountIfs(wsSource.Columns(8), m & "*", _
        wsSource.Columns(30), ">" & 100)
    Next x

    ' close source worbook no save
    wbSource.Close False

    ' update Sheet 2 with averages
    With ws.Range("A3")
        For iMth = 1 To 12
            .Offset(0, iMth - 1) = MonthName(iMth) & " " & YEAR
            If count(iMth) > 0 Then
                .Offset(1, iMth - 1) = sum(iMth) / count(iMth)
                .Offset(1, iMth - 1).NumberFormat = "0.0"
            End If
        Next
    End With

    Dim msg As String
    msg = iRow - 1 & " rows scanned in " & TextBox1.Text
    MsgBox msg, vbInformation, "Sheet 2 updated"
End Sub

enter image description here

enter image description here

enter image description here

0 个答案:

没有答案