I take a rather unorthodox approach for calculating Ranks based on a specific Field.
- In the Table whose Field you wish to Rank, create a Field named [Rank] {LONG}.
- Call a Function and pass to this Function three Arguments: Table Name, Name of Field to Rank, and the Name of the Primary Key.
- Within this Function a Recordset is created with the Field to Rank in Descending Order as the Primary Sort, then sorted by the Primary Key Ascending as the Secondary Sort. NULLs are not Ranked.
- The Rank Field created earlier is now populated with incremental and sequential Ranks.
- The Secondary Sort (PK) assures that Ties are not ranked equally, the Record(s) entered earlier will win the Tie(s).
- All Data, along with Ranking Values, are now contained in the Table allowing for great flexibility.
- I'll post the Function Definition and Call below, but download the Attachment to see what is really going on.
- Processing Time was approximately .250 seconds to Rank 2,154 Records.
- Function Definition:
- Public Function fAssignRank(strTableName As String, strFieldToRank As String, strPrimaryKey As String)
-
Dim MyDB As DAO.Database
-
Dim rst As DAO.Recordset
-
Dim strSQL As String
-
Dim lngCtr As Long
-
-
strSQL = "SELECT * FROM [" & strTableName & "] WHERE [" & strFieldToRank & _
-
"] IS NOT NULL ORDER BY [" & strFieldToRank & _
-
"] DESC, [" & strPrimaryKey & "]"
-
-
Set MyDB = CurrentDb
-
Set rst = MyDB.OpenRecordset(strSQL, dbOpenDynaset)
-
-
With rst
-
Do While Not .EOF
-
lngCtr = lngCtr + 1
-
.Edit
-
![Rank] = lngCtr
-
.Update
-
.MoveNext
-
Loop
-
End With
-
-
rst.Close
-
Set rst = Nothing
-
End Function
- Function Call:
- Call fAssignRank("Order Details", "UnitPrice", "OrderID")
P.S. - For the sake of brevity and simplicity, I've have not included any Validation or Error Checking Code.