加权中值 – 数组的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的每个模块的顶部。 你将永远感谢我。

不需要数组公式:

以下是另外两个参数StoreRangestore

函数将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 

结果

在这里输入图像描述