在 excel VBA 中创建一个函数来计算一组循环数字中的平均点

Creating a function in excel VBA to calculate the average point in a circular set of numbers

在这方面还是相当业余,所以请保持温和。我正在尝试创建一个函数来给出一组数字的平均值。这组数字实际上是一个齿轮的齿。主牙始终是牙齿 1(可识别为油漆),损坏或停止记录在顺时针旋转的牙齿上,因此牙齿 7 和 23 处的损坏将位于距起始牙齿的第 7 和 23 颗牙齿处。现在,当您计算正常平均值时会出现异常情况,因为按照标准平均值,第 3、4 和 33 号齿的平均停机次数实际上是 1 而不是 14.33。我已经计算出平均值,我的意思是更接近一组循环数字的中位数。我为范围内的每个值加一,并使用 MOD 函数计算最大数和最小数之间的差值。一旦我确定了最短差异的第一个位置,这就是从新平均值中减去增量值的简单情况。它可能在 table...

中有更好的描述

如你所见,真正的平均数或中位数是第1颗牙,即平均数减去第一个差值最小的一组数字的增量。 我目前要进行这些计算的代码给出了 value# 错误,但我对自定义函数的经验非常少,我不知道从哪里开始纠正问题,将不胜感激,一个解决方案将太棒了。非常感谢。

Public Function AVGDISTCALC(rng As Range)
'Determines the average distance of a number of distances on a 37 tooth wheel.
Dim x As Integer
Dim i As Integer
Dim avg As Integer
Dim diff As Integer
Dim Arr() As Variant
Dim r As Long
Dim c As Long
Application.ScreenUpdating = False

    'Write the range to an array.
    Arr = rng
    'Cycle through each increment on the 37 tooth wheel.
    diff = 38
    For i = 1 To 37
    Arr = rng
        'For each increment calculate the min and max of the range.
        For r = 1 To UBound(Arr, 1)
            For c = 1 To UBound(Arr, 2)
                If (Arr(r, c) + i) Mod 37 = 0 Then
                    Arr(r, c) = 37
                Else
                    Arr(r, c) = (Arr(r, c) + i) Mod 37
                End If
            Next c
        Next r
        If WorksheetFunction.Max(Arr) - WorksheetFunction.Min(Arr) < diff Then
            diff = WorksheetFunction.Max(Arr) - WorksheetFunction.Min(Arr)
            avg = WorksheetFunction.Average(Arr)
            x = i
        End If
    Next i
    
    AVGDISTCALC = avg - x
    
End Function

感谢 BigBen 指导我们使用数组。为了计算一组循环数字的平均值,我使用了下面的代码。我希望这个例子能帮助其他有类似问题的人。如果您需要不同数量的齿轮,您应该适当地更改 MOD 值。

Public Function AVGDISTCALC(rng As Range)
'Determines the average distance of a number of distances on a 37 tooth wheel.
Dim x As Integer
Dim i As Integer
Dim avg As Integer
Dim diff As Integer
Dim Arr() As Variant
Dim r As Long
Dim c As Long
Application.ScreenUpdating = False

    'Write the range to an array.
    Arr = rng
    'Cycle through each increment on the 37 tooth wheel.
    diff = 38
    For i = 1 To 37
    Arr = rng
        'For each increment calculate the min and max of the range.
        For r = 1 To UBound(Arr, 1)
            For c = 1 To UBound(Arr, 2)
                If (Arr(r, c) + i) Mod 37 = 0 Then
                    Arr(r, c) = 37
                Else
                    Arr(r, c) = (Arr(r, c) + i) Mod 37
                End If
            Next c
        Next r
        If WorksheetFunction.Max(Arr) - WorksheetFunction.Min(Arr) < diff Then
            diff = WorksheetFunction.Max(Arr) - WorksheetFunction.Min(Arr)
            avg = WorksheetFunction.Average(Arr)
            x = i
        End If
    Next i
    
    Select Case avg - x
    Case 0
        AVGDISTCALC = 37
    Case Is > 0
        AVGDISTCALC = avg - x
    Case Is < 0
        AVGDISTCALC = (avg - x) + 37
    End Select
    
End Function

这个怎么样?似乎 return 与您的示例具有相同的值,但如果有更多的样本计算来测试会很有用...

Function AvgDistance(vals As Range, teeth) As Double
    Dim arr, i As Long, tot As Long, v
    arr = vals.Value
    tot = 0
    For i = 1 To UBound(arr, 1)
        v = arr(i, 1)
        tot = tot + IIf(v > (teeth / 2), v - teeth, v)
    Next i
    AvgDistance = tot / UBound(arr, 1)
End Function