我在excel中创建了一种方法,我可以通过“移动平均”来平滑数据,只需更改单元格的值(间隔)并在图形中实时查看更改,而不必单击每次数据分析 - 移动平均值等。问题是我发现的方式显着减慢了Excel,因为它似乎每次在同一张表中的任何其他内容“计算”移动平均值(或其他东西)。当我在同一个文件中有大量数据时情况会变得最糟。 这是我目前正在这样做的方式: 我在E3中复制下面的公式,然后在C中拖拽相同数量的占用行。
=IF(COUNT($C$3:C3)>IntAve, AVERAGE(INDIRECT("C"&(ROW()-IntAve+1)):INDIRECT("C"&ROW())),"N/A")
其中C列包含我要平滑的数据,“IntAve”是包含要平均的单元格数或在移动平均窗口中调用的“间隔”的单元格。
如果可能,我希望用VBA创建一个宏,它将读取C中所有占用的行,读取单元格“IntAve”中的值,最后执行与上面相同的计算,但只需粘贴E列中的值,因此表格无需计算。
当我录制一个执行数据分析 - 移动平均线路的宏时,这就是我所看到的
Application.Run "ATPVBAEN.XLAM!Moveavg", ActiveSheet.Range("$B$1:$B$74662") _
, ActiveSheet.Range("$D:$D"), 45, False, False, False
但我不确定如何利用上面的宏来做我想要的。 顺便说一句45是“间隔”。
现在,如果有更好的方法可以做到这一点,我全都在船上!!!!
答案 0 :(得分:0)
如果我理解正确的话:
Option explicit
Sub MovingAverages()
With activesheet
Dim MovingAveragePeriod as long
MovingAveragePeriod = .range("IntAve").value2
Dim LastRowInColumnC as long
LastRowInColumnC = .cells(.rows.count,"C").end(xlup).row
Dim ColumnC as range
' I assume values begin from cell C1'
Set ColumnC = .range("C1:C" & LastRowInColumnC)
With .range("E1:E" & (lastrowincolumnc - movingaverageperiod +1))
'IF YOU HAVE VALUES LOWER DOWN IN COLUMN E below the averages that you do not want to clear, comment/get rid of this line below.'
.entirecolumn.clearcontents
.formula = "=average(C1:C" & movingaverageperiod & ")" ' check the last formula in column E to make sure it has copied down correctly and refers to the correct cells in column C'
.calculate ' I think this will only calculate the newly added averages.'
.value2 = .value2 ' hopefully this replaces formulas with values'
End With
End Sub
对于在移动设备上写的不良缩进感到抱歉。
或者,非VBA方法可以使用工作表函数:OFFSET()
答案 1 :(得分:0)
正如您所发现的,INDIRECT函数是易失性的,这意味着它会在每次细胞更改时重新计算,不仅是函数范围内的细胞,而且还有任何位置。
除非您需要评估一串TEXT,否则应该避免使用INDIRECT。当您的输入是数字时,您可以使用INDEX函数,因为它不是易失性的:
=IF(COUNT($C$3:$C3)>intAve, AVERAGE(INDEX($C:$C, ROW()-intAve+1):INDEX($C:$C, ROW())), "N/A")