UDF returns the same value everywhere

前端 未结 5 1904
闹比i
闹比i 2020-12-06 22:06

I am trying to code in moving average in vba but the following returns the same value everywhere.

Function trial1(a As Integer) As Variant
    Application.Vo         


        
5条回答
  •  悲哀的现实
    2020-12-06 22:57

    It's kind of strange to me for a UDF to calculate moving average given a number. If this UDF is to be used within the Worksheet, I believe you would put it next to existing data and if you want to change the size of the range for average amount, you update them manually?

    Assuming you can name a Range "MovingAverageSize" to store the size of the range to calculate the average, and the average amount on the right of the existing data, consider below:

    • Range C2 is named MovingAverageSize
    • Data stored from B3 and downwards
    • Moving Average result is stored 1 column on the right of the data
    • If the data is less than MovingAverageSize, the SUM function adjusts accordingly
    • Any calculation error occurs with result in zero
    • Every time MovingAverageSize changes value, it triggers a Sub to update the formulas (Codes are placed in the Worksheet object rather than normal Module)
    • Alternatively, you can change the code to place the MovingAverage to same column of the MovingAverageSize, so you can have a few different size comparing next to each other.

    Code in Worksheet Object:

    Option Explicit
    
    Private Sub Worksheet_Change(ByVal Target As Range)
        If Target.Count = 1 Then
            If Target.Address = ThisWorkbook.Names("MovingAverageSize").RefersToRange.Address Then UpdateMovingAverage Target
        End If
    End Sub
    
    Private Sub UpdateMovingAverage(ByRef Target As Range)
        Dim oRngData As Range, oRng As Range, lSize As Long, lStartRow As Long
        Debug.Print "UpdateMovingAverage(" & Target.Address & ")"
        If IsNumeric(Target) Then
            lSize = CLng(Target.Value)
            If lSize <= 0 Then
                MsgBox "Moving Average Window Size cannot be zero or less!", vbExclamation + vbOKOnly
            Else
                ' Top Data range is "B3"
                Set oRngData = Target.Parent.Cells(3, "B") ' <-- Change to match your top data cell
                lStartRow = oRngData.Row
                ' Set the Range to last row on the same column
                Set oRngData = Range(oRngData, Cells(Rows.Count, oRngData.Column).End(xlUp))
                Application.EnableEvents = False
                For Each oRng In oRngData
                    If (oRng.Row - lSize) < lStartRow Then
                        oRng.Offset(0, 1).FormulaR1C1 = "=iferror(sum(R[" & lStartRow - oRng.Row & "]C[-1]:RC[-1])/MovingAverageSize,0)"
                    Else
                        oRng.Offset(0, 1).FormulaR1C1 = "=iferror(sum(R[" & 1 - lSize & "]C[-1]:RC[-1])/MovingAverageSize,0)"
                    End If
                Next
                Application.EnableEvents = True
                Set oRngData = Nothing
            End If
        End If
    End Sub
    

    Sample data and screenshots

提交回复
热议问题