[[20260812122850]] 『全体に対する順位の出し方』(なな) ページの最後に飛ぶ

[ 初めての方へ | 一覧(最新更新順) |

| 全文検索 | 過去ログ ]

 

『全体に対する順位の出し方』(なな)

全体に対する順位を出す関数を教えてほしいです。
マラソンのランキングなので、時間、分、秒と三つ情報があります。時間が書かれている範囲はE4:E33で、分はF4:E33、秒はG4:G33です。順位を出すところはBの列です。
=RANK.EQ(E4*3600+F4*60+G4,E4:E33*3600+F4:F33*60+G4:G33,1)このような関数を作ってみたのですが、「この数式には問題があります」と出てしまいます。どこが問題なのか、またどうすればいいのか、教えていただきたいです。

< 使用 Excel:unknown、使用 OS:unknown >


「分」の範囲は、F4:E33ではなくF4:F33

B4:(B33までコピペ)
=IF(COUNTA(E4:G4)<3,"",SUMPRODUCT(($E$4:$E$33<>"")*($F$4:$F$33<>"")*($G$4:$G$33<>"")*(($E$4:$E$33*3600+$F$4:$F$33*60+$G$4:$G$33)<(E4*3600+F4*60+G4)))+1)

同じタイムの人は同じ順位でExcelのRANK.EQ関数と同じ考え方です。

(詠み人知らず) 2026/08/12(水) 12:44:53


詠み人知らず 様

ご丁寧に対応していただき、ありがとうございます。
無事に順位を出すことができました。本当にありがとうございます。
(なな) 2026/08/12(水) 12:55:17


別回答 / ユーザー定義関数

B4 : =MarathonRank($E$4:$E$33,$F$4:$F$33,$G$4:$G$33,E4,F4,G4)

Option Explicit

Public Function MarathonRank( _

    ByVal HourRange As Range, _
    ByVal MinuteRange As Range, _
    ByVal SecondRange As Range, _
    ByVal TargetHour As Variant, _
    ByVal TargetMinute As Variant, _
    ByVal TargetSecond As Variant) As Variant

    Dim i As Long
    Dim rank As Long
    Dim targetTime As Double
    Dim otherTime As Double

    '範囲の行数が一致しているか確認
    If HourRange.CountLarge <> MinuteRange.CountLarge _
       Or HourRange.CountLarge <> SecondRange.CountLarge Then

        MarathonRank = CVErr(xlErrValue)
        Exit Function
    End If

    '対象者のタイムが未入力または数値でない場合
    If Not IsValidNumber(TargetHour) _
       Or Not IsValidNumber(TargetMinute) _
       Or Not IsValidNumber(TargetSecond) Then

        MarathonRank = ""
        Exit Function
    End If

    '対象者のタイムを秒に変換
    targetTime = CDbl(TargetHour) * 3600 _
               + CDbl(TargetMinute) * 60 _
               + CDbl(TargetSecond)

    '最初は1位
    rank = 1

    '対象者より速い人の人数を数える
    For i = 1 To HourRange.Count

        If IsValidNumber(HourRange.Cells(i, 1).Value) _
           And IsValidNumber(MinuteRange.Cells(i, 1).Value) _
           And IsValidNumber(SecondRange.Cells(i, 1).Value) Then

            otherTime = CDbl(HourRange.Cells(i, 1).Value) * 3600 _
                      + CDbl(MinuteRange.Cells(i, 1).Value) * 60 _
                      + CDbl(SecondRange.Cells(i, 1).Value)

            If otherTime < targetTime Then
                rank = rank + 1
            End If
        End If
    Next i

    MarathonRank = rank

End Function

Private Function IsValidNumber(ByVal Value As Variant) As Boolean

    If IsError(Value) Then Exit Function
    If IsEmpty(Value) Then Exit Function

    If VarType(Value) = vbString Then
        If Trim$(Value) = "" Then Exit Function
    End If

    IsValidNumber = IsNumeric(Value)

End Function

(詠み人知らず) 2026/08/12(水) 13:13:22


 質問にあたってはExcelのバージョンを書かれたほうがいいですよ。

 メモを残します。

 ヘルプによると、
 RANK.EQ関数の第二引数は、
 「数値の範囲の配列またはその範囲への参照を指定します。」とあるので
 計算式ではだめなのでしょう。

 H列に  E4*3600+F4*60+G4 の数値を入れておき、
 =RANK.EQ(H4,H$4:H$33,1)
 として下にコピーします。

 もしMicrosoft365という前提ですと(正確にはExcel2021以降ですか)、
 =LET(
    a,E4:E33*3600+F4:F33*60+G4:G33,
    RANK.EQ(a,a,1)
 )
 としたくなるけれど、これもNG。
 やはり範囲由来のもの(範囲の配列か、範囲そのもの)を
 第二引数に持ってこないとだめですね。

 H列に秒単位換算値を作成し、
 I4に RANK.EQ(H4:H33,H4:H33,1)
 とすれば、下にコピーすることなく、30個の順序数値が得られます。

(xyz) 2026/08/12(水) 13:49:50


コメント返信:

[ 一覧(最新更新順) ]


YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki. Modified by kazu.