实际情况
我有一个带有用户表单的主工作簿(Wb)-文件浏览器(屏幕截图1)和结果的Sheet2(屏幕截图2)
我有一个源工作簿,该工作簿中有大量数据(14000行),坦白说是一团糟。.根据我的计算,源工作簿中只有两列是相关的:第8列(“正确日期”)和第30列(数值)。 关于第8列的重要说明:只有每月第一行的行才与我相关。含义:01.01。,01.02。,01.03。,01.04。等等。每隔一行都应该忽略。
我使用Wb搜索源工作簿(wb.Source)以应用以下计算:
任务1 :如果满足某些条件,则计算平均价值
任务2 :如果满足以下条件,则对行进行计数:
应该每月应用一次。
然后将结果添加到我的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