计算 SMA 时处理空白单元格

Handling blank cells while calculating SMA

我试图跳过一个范围内的空白单元格,这样它就不会改变我的简单移动平均线。所以我尝试从一个范围开始,“copy/paste”一个名为 oRng 的新范围内的非空白值,这样我就可以使用新范围来计算我的 SMA。

我在这一行收到错误 5,提示“参数或过程调用不正确”

Set oRng = Application.Union(oRng, cell)

这是我的完整代码:

Function SMA(rng As Range, N As Integer)

    Dim oRng As Range
    Dim cell As Range

    On Error GoTo ErrHandler

    For Each cell In rng
        If not IsEmpty(cell) = True Then
            Set oRng = Application.Union(oRng, cell)
    Next cell

    SMA = Application.Average(oRng.Resize(N, 1))

ErrHandler:
    Debug.Print Err.Description
End Function

oRng.Resize(N, 1) 不适用于 non-continous 范围。您只能调整连续范围的大小。因此,在使用 Union.

oRng 中收集它们之前,您需要调整单元格的大小

同样在 Dim oRng As Range 之后变量 oRngNothing 并且你不能在 Union 中使用 Nothing 所以你需要先直接测试这个 Set oRng = cell.Resize(N, 1) 第一次然后使用 Union 其他:

Public Function SMA(ByVal rng As Range, ByVal N As Long) As Variant
    Dim oRng As Range

    On Error GoTo ErrHandler

    Dim cell As Range
    For Each cell In rng
        If Not IsEmpty(cell) Then
            If oRng Is Nothing Then
                Set oRng = cell.Resize(N, 1)
            Else
                Set oRng = Application.Union(oRng, cell.Resize(N, 1))
            End If
    Next cell

    SMA = Application.Average(oRng)

ErrHandler:
    Debug.Print Err.Description
End Function

平均 Non-Contiguous(UDF 与否)

  • 请注意,Average 如果错误值将失败。

Function SMA_Columns( _
    ByVal FirstRowRange As Range, _
    Optional ByVal RowsCount As Long = 1) _
As Double

    Dim urg As Range ' Combined (Union) Range
    Dim crg As Range ' Column Range

    For Each crg In FirstRowRange.Resize(RowsCount).Columns
        If Not IsEmpty(crg.Cells(1)) Then
            If urg Is Nothing Then Set urg = crg Else Set urg = Union(urg, crg)
        End If
    Next crg
    If urg Is Nothing Then Exit Function
    
    SMA_Columns = Application.Average(urg)

End Function

行数

Function SMA_Rows( _
    ByVal FirstColumnRange As Range, _
    Optional ByVal ColumnsCount As Long = 1) _
As Double

    Dim urg As Range ' Combined (Union) Range
    Dim rrg As Range ' Row Range

    For Each rrg In FirstColumnRange.Resize(, ColumnsCount).Rows
        If Not IsEmpty(rrg.Cells(1)) Then
            If urg Is Nothing Then Set urg = rrg Else Set urg = Union(urg, rrg)
        End If
    Next rrg
    If urg Is Nothing Then Exit Function
    
    SMA_Rows = Application.Average(urg)

End Function