一昨日は、「空手の形の試合の得点から、ワークシート関数を用いて順位付けする計算式」を作成した。
infoment.hatenablog.com
今日は、マクロで順位を求めてみる。
まず、計算方法をおさらいする。
- 主審1名と副審4名が採点する。
- 一人の持ち点は7.0点。そこから0.1点単位で、加点または減点する。
- 5名のうち、最高点と最低点を除く3名の合計点の大小で勝敗を決める。
- 上記に於いて同点の場合、合計点に最低点を加えて比較する。
- それでも勝敗が決まらない場合、最高点を加えて比較する。
対象となる表は、こちらだ。事前に、テーブルとして書式設定済み。
表の各行が、各選手の成績となっている。そこで、成績計算用のクラスモジュールを作成することにした。
クラスモジュール(KarateRankClass)
Option Explicit ' 選手の各情報を受け取る配列。 Public myRecord As Variant ' 一回目の順位。 Public Rank_1st As Long ' 二回目の順位。一回目の順位で同じ順位の人が居る場合のみ有効。 Public Rank_2nd As Long ' 三回目の順位。二回目の順位で同じ順位の人が居る場合のみ有効。 Public Rank_3nd As Long
選手名前
Property Get PlayerName() As String PlayerName = myRecord(1, 1) End Property
その選手の最高点。配列内には選手の名前(文字列)も含まれているが、数字以外は無視してくれるらしい。
Property Get MaxPoint() As Double MaxPoint = WorksheetFunction.Max(myRecord) End Property
その選手の最低点。
Property Get MinPoint() As Double MinPoint = WorksheetFunction.Min(myRecord) End Property
5人の審判の採点合計。
Property Get Total_3rd() As Double With WorksheetFunction Total_3rd = .Round(.Sum(myRecord), 2) End With End Property
最高点を除く4人の審判の採点合計。
Property Get Total_2nd() As Double With WorksheetFunction Total_2nd = .Round(Total_3rd - MaxPoint, 2) End With End Property
最高点と最低点を除く、3人の審判の採点合計。
Property Get Total_1st() As Double With WorksheetFunction Total_1st = .Round(Total_2nd - MinPoint, 2) End With End Property
次いで、テーブルの採点からランク付け用配列を作成する。
標準モジュール
Sub GetRank() Dim PointTable As ListObject Set PointTable = ActiveSheet.ListObjects("採点表") ' 順位のセルをリセット。 PointTable.ListColumns("順位").DataBodyRange = "" ' 各選手の成績を配列化。 Dim Player() As KarateRankClass ReDim Player(1 To PointTable.DataBodyRange.Rows.Count) ' 最高点と最低点を除く合計点格納用配列。 Dim TotalSeq_1st() As Variant ' 最高点を除く合計点格納用配列。 Dim TotalSeq_2nd() As Variant ' 合計点格納用配列。 Dim Totalseq_3rd() As Variant ReDim TotalSeq_1st(1 To UBound(Player)) ReDim TotalSeq_2nd(1 To UBound(Player)) ReDim Totalseq_3rd(1 To UBound(Player)) ' 各選手のレコードから、各情報を取得。 Dim i As Long For i = 1 To UBound(Player) Set Player(i) = New KarateRankClass Player(i).myRecord = PointTable.DataBodyRange.Rows(i) TotalSeq_1st(i) = Player(i).Total_1st TotalSeq_2nd(i) = Player(i).Total_2nd Totalseq_3rd(i) = Player(i).Total_3rd Next
各選手の各合計点を、順位付け用の各配列に格納した。後は、RANK関数で順位を出すだけだ。
そして、この時気が付いた。RANK関数の第二引数の型は、Range型だってことに。
こいつは、うっかりだった。RANK関数が、そのままでは使えない。何か別の方法を考えないと。
次回に続きます。
参考まで。