EXCEL VBA:按年份排序,找到简单的平均值,最大值和最小值十年

时间:2012-10-23 17:29:35

标签: vba sorting excel-vba filter filtering

好吧,这样的场景:我有三个目前正在使用的专栏。 A列是我的唯一ID,B列是我的YEAR,C列是我的价值观。我在excel工作,并且有大约350,000行可以解决问题/目标:

我正在努力寻找能够筛选多年的正确代码,并为我提供VALUE C列的AVERAGE,MAX和MIN值十年。

同样,我有数十万行代码可供使用,我想从1940年代到2010年分类十年;每十年它会给我AVERAGE,MAX和MIN值。

我只是一名业余程序员,因此我知道如何通过在漫长而乏味的时间段内创建多种类型来逐个过滤十年。但是,我想知道是否有人知道可以一举完成所有代码,从而节省了程序不止一次筛选我的350,000行代码的过程。

我将非常感谢任何能教我这一点的人,祝你好运,感谢你!

编辑::(如何显示平均值,最大值和最小值))::

“啊,我为没有澄清而道歉。我只是假设我会在他们'神奇地'出现后我会照顾它,哈哈。不管怎样,我将展示我在一张简单的桌子上整理出来的十年信息在一个新的工作表中,AVERAGE,MAX,MIN将成为三行标题,而几十年将成为该表的列标题。“

2 个答案:

答案 0 :(得分:2)

我同意Scott的观点,在大多数情况下,公式是比VBA更好的选择。但是你要求一些特定的东西,包括对数据进行排序,在单独的选项卡上显示结果,所以我假设在这种情况下你可以使用宏带来的额外开销。

您遗漏了一些有关数据的详细信息(数据类型,特定单元格位置等)...因此,请参阅代码中的注释,您可能需要自定义。

我试图尽可能地逐字逐句地提出你的问题......例如,我个人可能更倾向于将结果放在一张桌子上,而不是放在一起,但这并不是我接近答案的方式。

Sub SummarizeDecade()

Const YearColumn As Integer = 2  'assumes the first year is in cell B2
Const FirstDataRow As Integer = 2 'assumes the first year is in cell B2

Dim wb As Excel.Workbook, ws As Excel.Worksheet, wsNew As Excel.Worksheet
Dim rowStart As Long, rowEnd As Long, colPaste As Long
Dim decade As Integer
Dim avg As Double, mini As Double, maxi As Double 'you didn't specify data type, Double is most accommodating

   Set wb = ThisWorkbook
   Set ws = wb.ActiveSheet  'assumes you run the macro while the data sheet is the current sheet; would prefer to use a sheet name

   'setup new worksheet for summary results, as requested
   wb.Worksheets.Add
   Set wsNew = wb.Worksheets(1)
   wsNew.Name = "Results"
   wsNew.Cells(1, 1).Value = "Decade"
   wsNew.Cells(2, 1).Value = "Average"
   wsNew.Cells(3, 1).Value = "Minimum"
   wsNew.Cells(4, 1).Value = "Maximum"
   colPaste = 2

   ws.Activate
   ws.Cells(FirstDataRow, YearColumn).Sort ws.Cells(FirstDataRow, YearColumn), xlAscending, , , , , , xlYes 'sorts the data by year, as requested

   rowStart = FirstDataRow
   rowEnd = rowStart

   Do Until Len(ws.Cells(rowEnd, 3).Value) = 0 'be sure your data does not include strings with spaces, zeroes, etc.  Must be blank/null/empty.
      decade = Int(ws.Cells(rowStart, YearColumn) / 10) * 10

      Do Until Int(ws.Cells(rowEnd, YearColumn) / 10) * 10 <> decade
         rowEnd = rowEnd + 1
      Loop

      'calculate the average, max, and min
      avg = Application.WorksheetFunction.Average(ws.Range(ws.Cells(rowStart, 3), ws.Cells(rowEnd - 1, 3)))
      mini = Application.WorksheetFunction.min(ws.Range(ws.Cells(rowStart, 3), ws.Cells(rowEnd - 1, 3)))
      maxi = Application.WorksheetFunction.max(ws.Range(ws.Cells(rowStart, 3), ws.Cells(rowEnd - 1, 3)))

      'write the summaries on the new worksheet tab
      wsNew.Cells(1, colPaste).Value = decade
      wsNew.Cells(2, colPaste).Value = avg
      wsNew.Cells(3, colPaste).Value = mini
      wsNew.Cells(4, colPaste).Value = maxi

      colPaste = colPaste + 1
      rowStart = rowEnd
   Loop


End Sub

答案 1 :(得分:0)

非VBA解决方案:

见下图。我冒昧地以简洁的格式设置数据以显示我的概念,但您可以轻松调整。相应地更改数据范围以及最大/最小公式。

请务必按Ctrl + Shift + Enter,因为这些公式是数组公式。

Non-VBA Solution