【问题标题】:(Excel VBA) Finding Values Based on Multiple Criteria(Excel VBA) 基于多个条件查找值
【发布时间】:2016-09-24 10:49:56
【问题描述】:

我有一个包含两列的表。它们分别代表日期和相应的值。我想要做的是获取每个月的平均值并创建另一个包含月平均值和年份的表。我用“for”编写了一个简单的代码,它工作得很好,但需要一段时间,因为大约有 40000 行。我很好奇是否还有其他方法可以在更短的时间内完成。谢谢。

TABLE
...
09.07.1908  63.5
10.07.1908  59.7
11.07.1908  49
12.07.1908  44.7
.......
.......
12.05.2003  32.45
13.05.2003  38.33
.......



 OUTPUT
        JANUARY FEBRUARY MARCH ...  
 1908    12.53    23.45  45.87 ...
 1909    45.23    14.43  23.54 ...
 .................................
 .................................
 2014    23.65    56.87  12.43 ...




Dim i, j, index1, index2 As Integer
Dim mean, sum As Double

index1 = 0 
index2 = 1
For i = 1908 To 2014
  For j = 1 To 12
    For k = 3 To 39000
      If Month(Sheet1.Cells(k, 1).Value) = j And Year(Sheet1.Cells(k,1).Value) = i Then
      sum = sum + Sheet1.Cells(k, 2).Value
      index1 = index1 + 1
      End If
    Next
  mean = sum / index1
  Sheet5.Cells(index2 + 2, j + 1).Value = sum / index1
  sum = 0
  index1 = 0
  Next
index2 = index2 + 1
Next

【问题讨论】:

  • 如果您的代码有效并且您只想寻找最佳优化,请将其发布到Code Review

标签: excel vba find


【解决方案1】:

使用数组读取数据要快一些,但一次写入所有数据可以轻松地将大型数据集上的代码速度提高 100 倍。处理 39000 行 x 2 列并写入 1 行 x 13 列(标题行)并写入 106 行 x 13 列耗时:0.125 秒。

Sub Refactor()
    Dim Start: Start = Timer
    Dim arData, arSums(1908 To 2014, 0 To 12), arCounts(1908 To 2014, 1 To 12)
    Dim m As Long, x As Long, y As Long

    With Sheet1
        arData = .Range("A3", .Range("B" & Rows.Count).End(xlUp)).Value2
    End With

    For x = 1 To UBound(arData, 1)
        m = Month(arData(x, 1))
        y = Year(arData(x, 1))

        arSums(y, m) = arSums(y, m) + arData(x, 2)
        arCounts(y, m) = arCounts(y, m) + 1
    Next

    For x = LBound(arSums, 1) To UBound(arSums, 1)
        arSums(x, 0) = x

        For y = 1 To 12
            If Not IsEmpty(arCounts(x, y)) Then arSums(x, y) = arSums(x, y) / arCounts(x, y)
        Next
    Next

    Sheet5.Range("A1").Resize(1, 13) = Array("Year", "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec")
    Sheet5.Range("A2").Resize(106, 13).Value = arSums
    Debug.Print Timer - Start
End Sub

【讨论】:

  • 感谢您提供的重要信息。这确实是一个“显着”的区别:)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-06-08
  • 2023-02-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多