excel 在累计等于某个百分比的列中查找值

vlf7wbxs  于 2023-02-05  发布在  其他
关注(0)|答案(3)|浏览(202)

在Excel中,我有一个值列表(按随机顺序),我想找出哪些值占总值的75%;IidoEe.如果将最大值加在一起,我应该包括哪些值才能达到总数的75%(从最大到最小)。我想找到“截止值”,IidoEe.最小的数字包括在一组值中(组合起来的总和达到75%)。但是,我想这样做而不首先排序我的数据。
考虑下面的例子,在这里我们可以看到,截止点是在“公司6”,这对应于一个“截止值”750。
我所拥有的数据没有排序,因此我只想弄清楚“截止值”应该是什么,因为这样我就知道如果行中的金额大于该数字,则它是构成总数75%的值组的一部分。
答案可以是Excel或VBA;但我希望避免必须先对表进行排序,并且希望避免在每行中进行计算(因此最好是可以计算它的单个公式)。
| 行数|金额|百分比|运行总计|
| - ------|- ------|- ------|- ------|
| 公司1|一千|百分之十二点九|百分之十二点九|
| 二连|九五零|百分之十二点三|二十五点二|
| 三连|九百|百分之十一点六|三十六点八|
| 四连|八五零|百分之十一|四十七点七|
| 五连|八百|百分之十点三|58.1%|
| 六连|七百五十|九点七|六十七点七|
| 七连|七百|百分之九|七十六点八|
| 八连|六百五十|百分之八点四|八十五点二|
| 九连|六百|百分之七点七|百分之九十二点九|
| 十连|五百五十|百分之七点一|100.0%|
| 共计|七千七百五十人|||
| 占总数的75%|五千八百一十三人|||
编辑:我最初的想法是使用百分位数/四分位数函数,然而这并没有给我预期的结果。我一直试图使用percentrank,sort,sum和aggregate的组合-但不能想出如何将它们组合起来,以获得我需要的结果。
在本例中,我希望包括公司1到6,因为这些公司总计为5250,因此要包括的最小数字为750。如果添加公司7,则会超过5813(即75%)。

xienkqul

xienkqul1#

VBA气泡排序-不更改工作表。

Option Explicit

Sub calc75()

    Const PCENT = 0.75

    Dim rng, ar, ix, x As Long, z As Long, cutoff As Double
    Dim n As Long, i As Long, a As Long, b As Long
    Dim t As Double, msg As String, prev As Long, bFlag As Boolean
   
    ' company and amount
    Set rng = Sheet1.Range("A2:B11")
    ar = rng.Value2
    n = UBound(ar)
   
    ' calc cutoff
    ReDim ix(1 To n)
    For i = 1 To n
       ix(i) = i
       cutoff = cutoff + ar(i, 2) * PCENT
    Next

    ' bubble sort
    For a = 1 To n - 1
        For b = a + 1 To n
            ' compare col B
            If ar(ix(b), 2) > ar(ix(a), 2) Then
                z = ix(a)
                ix(a) = ix(b)
                ix(b) = z
            End If
        Next
    Next
   
    ' result
    x = 1
    For i = 1 To n
        t = t + ar(ix(i), 2)
        If t  > cutoff And Not bFlag Then
           msg = msg & vbLf & String(30, "-")
           bFlag = True
           If i > 1 Then x = i - 1
        End If
        
        msg = msg & vbLf & i & ") " & ar(ix(i), 1) _
             & Format(ar(ix(i), 2), "  0") _
             & Format(t, "  0")
   Next
   
   MsgBox msg, vbInformation, ar(x, 1) & " Cutoff=" & cutoff

End Sub
fsi0uk1n

fsi0uk1n2#

所以,按照我的建议简单地设置它。
您可以添加或更改约束条件,因为您希望得到您需要的结果-我选择二进制开始,但您可以限制为整数和1,2或3,例如。

我包括了我使用的roundup()以及sumproduct。
我使用二进制,因为它给出了一个明确的指示,选择,整数值也将做同样的事情。

pgvzfuti

pgvzfuti3#

运行总计的最小值...

=LET(Data,B2:B11,Ratio,0.75,
    Sorted,SORT(Data,,-1),MaxSum,SUM(Sorted)*Ratio,
    Scanned,SCAN(0,Sorted,LAMBDA(a,b,IF((a+b)<=MaxSum,a+b,0))),
    srIndex,XMATCH(0,Scanned)-1,
Result,INDEX(Sorted,srIndex),Result)

G2:  =SORT(B2:B11,,-1)
H2:  =SUM(B2:B11)*0.75
I2:  =SCAN(0,G2#,LAMBDA(a,b,IF((a+b)<$H$2,a+b,0)))
J2:  =XMATCH(0,I2#)
K2:  =INDEX(G2#,XMATCH(0,I2#)-1)
  • 出现的问题是,Amount列中可能存在重复项,而无法确定哪个结果是正确的。
  • 如果公司名称是唯一的,则准确的方法是返回公司名称。
=LET(rData,A2:A11,lData,B2:B11,Ratio,0.75,
    Data,HSTACK(rData,lData),Sorted,SORT(Data,2,-1),
    lSorted,TAKE(Sorted,,-1),MaxSum,SUM(lSorted)*Ratio,
    Scanned,SCAN(0,lSorted,LAMBDA(a,b,IF((a+b)<=MaxSum,a+b,0))),
    rSorted,TAKE(Sorted,,1),rIndex,XMATCH(0,Scanned)-1,
Result,INDEX(rSorted,rIndex),Result)
  • 请注意,您可以使用公式LAMBDA版本的以下部分定义名称,例如GetCutOffCompany
=LAMBDA(rData,lData,Ratio,LET(
    Data,HSTACK(rData,lData),Sorted,SORT(Data,2,-1),
    lSorted,TAKE(Sorted,,-1),MaxSum,SUM(lSorted)*Ratio,
    Scanned,SCAN(0,lSorted,LAMBDA(a,b,IF((a+b)<=MaxSum,a+b,0))),
    rSorted,TAKE(Sorted,,1),rIndex,XMATCH(0,Scanned)-1,
Result,INDEX(rSorted,rIndex),Result))
  • 然后,您可以在工作簿中的任何位置使用该名称,就像使用任何其他Excel函数一样,例如:
=GetCutOffCompany(A2:A11,B2:B11,0.75)

相关问题