我有一张表格,其中数据以下面的格式粘贴。我需要计算每个月有一个条目的次数,正如您从下面的示例中可以看到的那样,它可以在一个月内的许多天发生。
我能想到的唯一方法是将月份分开并对其进行小计并复制总数。
麻烦的是由于数据量的原因需要花费很长时间才能运行。
还有其他方法可以解决这个问题吗?我已粘贴下面的当前代码。 TIA
' Add Totals
Sheets("Data").Select
Columns("G:G").Select
Selection.NumberFormat = "mm"
Range("F4").Select
Selection.Subtotal GroupBy:=7, Function:=xlCount, TotalList:=Array(7), _
Replace:=True, PageBreaks:=False, SummaryBelowData:=True
ActiveSheet.Outline.ShowLevels RowLevels:=2
Range("G3:G4000").Select
Selection.SpecialCells(xlCellTypeVisible).Select
Selection.Copy
Sheets("Set Up Data").Select
Range("B2").Select
ActiveSheet.Paste
Application.CutCopyMode = False
Sheets("Data").Select
Range("D56").Select
Application.CutCopyMode = False
Selection.RemoveSubtotal
答案 0 :(得分:2)
将数据复制到变量数组会更快,并对其进行分析。
像这样的东西
Sub Demo()
Dim rData As Range
Dim vData As Variant
Dim i As Long
Dim Counts(1 To 12, 1 To 1) As Long
' Get range reference to source data
' assumes data is in column G, starting at row 4. Adjust as required
With Worksheets("Data")
Set rData = .Range(.Cells(4, 7), .Cells(.Rows.Count, 7).End(xlUp))
End With
' copy range data to variant array
vData = rData.Value
' count occurance of each month
For i = 1 To UBound(vData, 1)
' allow for possibility that dates are actually strings
Counts(Month(CDate(vData(i, 1))), 1) = Counts(Month(CDate(vData(i, 1))), 1) + 1
Next
' put count data back on sheet
' adjust target as required
Worksheets("Set Up Data").Cells(2, 2).Resize(UBound(Counts, 1), 1) = Counts
End Sub
答案 1 :(得分:0)
我还可以考虑其他两种方式,但两种方式都会在不同的表格中显示答案:
答案 2 :(得分:0)
有点hacky但应该比你拥有的更快。我假设您知道最短日期和最长日期。
首先添加一个连接月份和年份的新列。例如,2016年1月24日,列值将是2016年1月。循环遍历工作表以为每行添加此列。现在,您执行第二个循环,此时循环开始月和结束月之间的日期,并在循环中计算工作表的月 - 年字符串列中每个连接字符串的出现次数。因此,如果第一个月是2015年2月,则计算该列中2015年2月的出现次数,然后在下一次迭代中计算2015年3月的数量,依此类推。最后,您按月计算,并删除额外的列。
答案 3 :(得分:0)
你可以随时使用公式方法:
设置表后,我使用了COUNTIF()公式:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <signal.h>
#include <sys/wait.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <ncurses.h>
int main(void) {
int fd[2];
pid_t childpid;
char input = 'o';
pipe(fd);
if ((childpid = fork()) == -1) {
perror("fork");
exit(1);
}
if (childpid == 0) {
close(0);
dup(fd[0]);
execl("draw.out", "draw.out", NULL);
} else {
close(fd[0]);
initscr();
while (input != 'q') {
read(0, &input, 1);
if (input == 'a' || input == 's' || input == 'd' || input == 'w' || input == 'q') {
write(fd[1], &input, 1);
}
}
endwin();
exit(0);
}
return 0;
}
或者您可以使用SUMPRODUCT():
=COUNTIFS(G:G,"<"&DATE(K2,J2+1,1),G:G,">=" &DATE(K2,J2,1))
这只是一个FYI。
答案 4 :(得分:-1)
请您试试以下代码吗?我刚刚发布了你发布的一些内容。数据必须按加入日期排序才能生效。
Sub testSubtotal()
Sheets("Data").Select
Columns("G:G").Select
' Since you have two different years in the example I think it would be
' better to get subtotals for year and month together
Selection.NumberFormat = "yyyy-mm"
Range("F1").Select
Selection.Subtotal GroupBy:=7, Function:=xlCount, TotalList:=Array(7), _
Replace:=True, PageBreaks:=False, SummaryBelowData:=True
ActiveSheet.Outline.ShowLevels RowLevels:=2
' Selecting also column F you will get the description of the subtotal
' in the "Set Up Data" worksheet
Range("F1:G4000").Select
Selection.SpecialCells(xlCellTypeVisible).Copy
Sheets("Set Up Data").Select
' I have changed the destination cell to B1
' but I do not know how yor worksheet is formatted.
Range("B1").Select
ActiveSheet.Paste
Sheets("Data").Select
Cells.Select
Selection.RemoveSubtotal
End Sub
我只在一张数据很少的桌子上测试过它,但它看起来并不慢。我希望我能正确理解你的问题...