Libreoffice Calc:如何在不跳过排名的情况下对数字进行排名?

问题描述 投票:0回答:1

我有一个表格,其中一列包含积分/比赛,我想按第二列中的相对位置对球队进行排名,但 RANK 函数没有达到我的预期,而是将所有并列位置添加到给定排名的计数中到下一个等级。

这是我的表格,其中第一列有积分/游戏 (BX10:BX23)。

simple ranking table

在第二列中,我希望每支球队按照他们在列表中的相对位置进行排名,并且平局得分/比赛给予相同的排名。使用 =RANK($BX10, $BX$10:$BX$23) 可以正常工作,但是这会将前一个排名中的每个项目的下一个位置增加 1。

换句话说,前 5 支球队的得分/比赛都相同,因此所有球队都正确排名为 1。但是,下一个球队的排名为 6,而不是 2,依此类推。

我想让它简单地显示“这些球队并列第一;接下来的球队并列第二……”所以我想让“地点”栏从上到下显示:“1, 1, 1, 1, 1, 2, 3, 4, 4, 4, 5, 5, 5, 6”而不是 RANK 给出的“1, 1, 1, 1, 1, 6, 7, 8, 8, 8, 11, 11, 11, 14”。

有没有一种相当简单的方法来做到这一点?

libreoffice rank calc
1个回答
0
投票

当我发现我记不起我需要的内置函数或者公式太麻烦时,我会编写自己的用户定义函数来完成这项工作。 “想要做好,就自己做”

在本例中,代码如下:

Option Explicit 
Function placeInSeq(aData As Variant, Optional asAscending As Integer) As Variant
Dim aUniqueVal() As Variant 
Dim i As Long, j As Long 
    If IsMissing(asAscending) Then asAscending=0
    For i = LBound(aData) To UBound(aData)
        For j = LBound(aData,2) To UBound(aData,2)
            collectUnique(aData(i,j), aUniqueVal)
        Next j
    Next i
    For i = LBound(aData) To UBound(aData)
        For j = LBound(aData,2) To UBound(aData,2)
            aData(i,j) = getIndexOfUnique(aData(i,j), aUniqueVal)
            If asAscending Then
                aData(i,j) = aData(i,j) + 1
            Else 
                aData(i,j) = UBound(aUniqueVal) - aData(i,j) +1
            EndIf 
        Next j
    Next i
    placeInSeq = aData
End Function

Sub collectUnique(key As Variant, aData As Variant)
Dim l&, r&, m&, N&, i&
    l = LBound(aData)
    r = UBound(aData) + 1
    N = r
    While (l < r)
        m = l + Int((r - l) / 2)
        If aData(m) < key Then l = m + 1 Else r = m
    Wend
    If r = N Then
        ReDim Preserve aData(0 To N)
        aData(N) = key
    ElseIf aData(r)(0) = key Then
'       Nothing todo
    Else
        ReDim Preserve aData(0 To N)
        For i = N - 1 To r Step -1
            aData(i + 1) = aData(i)
        Next i
        aData(r) = key
    End If
End Sub

Function getIndexOfUnique(key As Variant, aData As Variant)
Dim l&, r&, m&, N&, i&
    l = LBound(aData)
    r = UBound(aData) + 1
    N = r
    While (l < r)
        m = l + Int((r - l) / 2)
        If aData(m) < key Then l = m + 1 Else r = m
    Wend
    If r = N Then
        getIndexOfUnique = -1
    ElseIf aData(r) = key Then
        getIndexOfUnique = r
    Else
        getIndexOfUnique = -1
    End If
End Function

函数

placeInSeq()
采用一个必需参数 - 来自一系列单元格的值数组,并返回相同大小的数组。第二个可选参数与
Type
函数中的
RANK()
参数具有相同的含义 - 如果为 0 或未指定,则值按降序排列,否则 - 按升序排列。

只需在

BY10
中输入 =PLACEINSEQ(BX10:BX23) 并使用 Ctrl+Shift+Enter 完成输入即可向 Calc 显示这是一个数组公式。

Result

是的,这不是一个理想的解决方案。但它有效并且结果符合预期。

© www.soinside.com 2019 - 2024. All rights reserved.