2

列の最後の、たとえば 20 個の数値の移動平均を計算したいと考えています。問題は、列の一部のセルが空である可能性があることです。それらは無視する必要があります。例:

 A
175
154

188
145
155

167
201

最後の 3 つの移動平均は (155+167+201)/3 になります。平均、オフセット、インデックスを使用してこれを実装しようとしましたが、方法がわかりません。私はマクロに少し慣れているので、そのような解決策はうまくいくでしょう:=MovingAverage(A1;3)

ヒントや解決策をありがとう!

4

4 に答える 4

7
{=SUM(($A$1:A9)*(ROW($A$1:A9)>LARGE((ROW($A$1:A9))*(NOT(ISBLANK($A$1:A9))),3+1)))/3}

これをcontrol+shift+enterで入力すると配列数式になります。これにより、最新の 3 つの値が検索されます。多かれ少なかれ必要な場合は、式の 2 つの「3」のインスタンスを必要に応じて変更します。

LARGE((ROW($A$1:A9))*(NOT(ISBLANK($A$1:A9))),3+1)

この部分は、値を持つすべてのセルの 4 番目に高い行番号を返します。例では 5 を返します。これは、行 6、8、および 9 が値を持つ 1 番目から 3 番目に高い行であるためです。

(ROW($A$1:A9)>LARGE((ROW($A$1:A9))*(NOT(ISBLANK($A$1:A9))),3+1))

この部分は、行番号が 4 番目に大きいかどうかに基づいて、9 つの TRUE または FALSE を返します。

($A$1:A9)*(ROW($A$1:A9)>LARGE((ROW($A$1:A9))*(NOT(ISBLANK($A$1:A9))),3+1))

これにより、A1:A9 の値が 9 つの TRUE または FALSE で乗算されます。TRUE は 1 に、FALSE は 0 に変換されます。これにより、SUM関数は次のようになります

=SUM({0;0;0;0;0;155;0;167;201})/3

155 を超えるすべての値が行数基準を満たしていないため、get にゼロが乗算されます。

于 2011-03-12T17:49:19.610 に答える
3

UDF を使用する場合、パラメータに処理したいデータ範囲がすべて含まれている場合にのみ、データを変更したときに正しく再計算されます。

以下は、列全体を処理し、いくつかのエラー処理を含む移動平均 UDF です。数式をセル
に入力することで呼び出すことができます。=MovingAverage(A:A,3)

Function MovingAverage(theRange As Range, LastN As Long) As Variant
    Dim vArr As Variant

    Dim j As Long
    Dim nFound As Long
    Dim dSum As Double

    On Error GoTo Fail
    MovingAverage = CVErr(xlErrNA)
    '
    ' handle entire column reference
    '
    vArr = Intersect(Application.Caller.Parent.UsedRange, theRange).Value2

    If IsArray(vArr) And LastN > 0 Then
        For j = UBound(vArr) To 1 Step -1
            ' skip empty/uncalculated
            If Not IsEmpty(vArr(j, 1)) Then
                ' look for valid numbers
                If IsNumeric(vArr(j, 1)) Then
                    If Len(Trim(CStr(vArr(j, 1)))) > 0 Then
                        nFound = nFound + 1
                        If nFound <= LastN Then
                            dSum = dSum + CDbl(vArr(j, 1))
                        Else
                            Exit For
                        End If
                    End If
                End If
            End If
        Next j

        If nFound >= LastN Then MovingAverage = dSum / LastN

    End If
    Exit Function
Fail:
    MovingAverage = CVErr(xlErrNA)
End Function
于 2011-03-13T17:37:33.470 に答える
1

VBA で短いスクリプトを作成しました。うまくいけば、それはあなたが望むことをします。はい、どうぞ:

Function MovingAverage(ByVal r As String, ByVal i As Integer) As Double
Dim rng As Range, counter As Long, j As Integer, tmp As Double
    Set rng = Range(r)
    counter = 360
    j = 0
    tmp = 0
    While j < i + 1 And counter > 0
        If Len(rng.Offset(j, 0)) > 0 Then
            tmp = tmp + rng.Offset(j, 0).Value
        End If
        j = j + 1
        counter = counter - 1
    Wend
    MovingAverage = CDbl(tmp / i)
End Function

1) 制限を 360 セルに設定しました。これは、スクリプトが 360 を超えるセルを検索しないことを意味します。変更したい場合は、counterの初期値を変更してください。

2) スクリプトは丸められていない平均を返します。最後の行を MovingAverage = Round(CDbl(tmp / i),2) に変更します

3) 使い方は思い通りなので、セルに=MovingAverage("a1";3)と入力するだけです。

どんなコメントでも大歓迎です。

于 2011-03-12T22:50:28.087 に答える
1

簡単な解決策: 数値がセル A2:A10 にあると仮定すると、B10 に次の式を入力します。

=IF(COUNT(A8:A10)=3,AVERAGE(A8:A10),IF(COUNT(A7:A10)=3,AVERAGE(A7:A10),"too many blanks"))

式を上にドラッグすると、移動平均が得られます

2 つの連続する空白の可能性がある場合は、別の入れ子にすることができます。それ以上の場合、このソリューションは複雑になりすぎます。

于 2011-03-12T17:32:04.000 に答える