VBA:流畅的数据

时间:2017-10-29 00:59:45

标签: excel vba excel-vba

我在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是“间隔”。

现在,如果有更好的方法可以做到这一点,我全都在船上!!!!

2 个答案:

答案 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
  1. 这有用吗?
  2. 它能做你想做的吗?
  3. 对于在移动设备上写的不良缩进感到抱歉。

    或者,非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")