加权中值 – 数组的UDF?
我是一个被认可的newb,当涉及到在其他许多事情excel / code /等。 当我计算一个中间值(一个值为一列,一个值)时,我试图find一种方法来计算出现加权,并且发现了一个运行良好的较老的UDF。
现在我可能会变得有点贪婪,但是我正在尝试处理相当多的信息,最快的方法就是只有在第三列中的标签标识了值时,才能执行加权中介。
Occurr. Cost Store Name 1 9.99 Charlie 4 15 Charlie 5 8 Charlie 6 10 Romeo 9 12 Delta 2 15 Romeo 3 8 Romeo 4 9.99 Delta 6 15 Delta 1 8 Delta
我试过这个{= WeightedMedian(IF($ C $ 2:$ C $ 12 = $ D2,$ B $ 2:$ B $ 12),IF($ C $ 2:$ C $ 12 = $ D2,$ A $ 2:$ A $ 12) )}希望返回两个必要的数组来服务WeightedMedian的ValueRange和WeightRange。 不过,我只是得到#Value错误。 任何想法如何解决它? 下面列出了原始UDF。
*UDF* Function WeightedMedian(ValueRange As Range, WeightRange As Range) Dim MedianArray() On Error GoTo WrongRanges ArrayLength = Application.Sum(WeightRange) ReDim MedianArray(1 To ArrayLength) Counter = 0 ArrayCounter = 0 For Each ValueRangeCell In ValueRange LoopCounter = LoopCounter + 1 FirstArrayPos = ArrayCounter + 1 ArrayCounter = ArrayCounter + Application.Index(WeightRange, LoopCounter) For n = FirstArrayPos To ArrayCounter MedianArray(n) = ValueRangeCell.Value Next Next WeightedMedian = Application.Median(MedianArray) Exit Function WrongRanges: WeightedMedian = CVErr(2042) End Function
我刚刚改变你的function,以下面的数组公式:
{=WeightedMedian(IF($C$2:$C$12=$D2,$B$2:$B$12),IF($C$2:$C$12=$D2,$A$2:$A$12))}
正如评论提到{IF($C$2:$C$12=$D2,$B$2:$B$12)}
和数组上下文中的另一个IF
不会导致范围,但在数组中。 所以Function
必须处理它们而不是范围。
请注意,作为{IF($C$2:$C$12=$D2,$A$2:$A$12)}
结果的Weights
数组是一个二维数组。 作为{IF($C$2:$C$12=$D2,$B$2:$B$12)}
也是。 但是因为For Each
我们不需要注意。
UDF:
Function WeightedMedian(Values As Variant, Weights As Variant) As Variant Dim MedianArray() On Error GoTo WrongRanges ArrayLength = Application.Sum(Weights) ReDim MedianArray(1 To ArrayLength) Counter = 0 ArrayCounter = 0 For Each sValue In Values LoopCounter = LoopCounter + 1 FirstArrayPos = ArrayCounter + 1 ArrayCounter = ArrayCounter + Weights(LoopCounter, 1) For n = FirstArrayPos To ArrayCounter MedianArray(n) = sValue Next Next WeightedMedian = Application.Median(MedianArray) Exit Function WrongRanges: WeightedMedian = CVErr(2042) End Function
结果:
转到工具=>选项..并勾选“需要variables声明”自动添加Option Explicit
到您将来创build的每个模块的顶部。 你将永远感谢我。
不需要数组公式:
以下是另外两个参数StoreRange
和store
。
函数将input范围转换为循环的变体数组。
可能比@AxelRichter慢,但不需要CSEinput。
Function WeightedMedianArrays(ValueRange As Range, _ WeightRange As Range, _ StoreRange As Range, _ store As String) As Single 'Assumes all ranges start on same row and are same length Dim MedianArray() Dim Weights() As Variant Dim Vals() As Variant Dim Stores() As Variant Dim FirstArrayPos As Long Dim n As Long Dim x As Long Weights = WeightRange Vals = ValueRange Stores = StoreRange For x = 1 To UBound(Vals) If Stores(x, 1) = store Then ReDim Preserve MedianArray(1 To FirstArrayPos + Weights(x, 1)) For n = 1 To Weights(x, 1) MedianArray(FirstArrayPos + n) = Vals(x, 1) Next FirstArrayPos = FirstArrayPos + Weights(x, 1) End If Next WeightedMedianArrays = Application.Median(MedianArray) End Function
结果