------------------------------.
番号 名前 ランキング 連番←追加項目
3 佐藤 1 1
1 佐藤 1 2
5 佐藤 2 3
4 鈴木 2 4
2 鈴木 2 5
------------------------------
要は、当該のId(=番号)が何番目に出現しているのか?
3--->1番目
1--->2番目
ならば、次のようなクエリを作成すれば目的は達成できます。
SELECT
T1.ID,
T1.名前,
T1.ランキング,
IdFound("SELECT ID FROM T1 ORDER BY [ランキング], 名前",[ID]) AS 連番
FROM T1
ORDER BY T1.名前, T1.ランキング;
さて、問題は IdFound() が提供されていないこと。
そこで、自作します。
Public Function IdFound(ByVal strSQL As String, ByVal Id As Integer) As Integer
Dim N As Integer
Dim M As Integer
Dim rst As ADODB.Recordset
Set rst = New ADODB.Recordset
With rst
.Open strSQL, _
CurrentProject.Connection, _
adOpenStatic, _
adLockReadOnly
If Not .BOF Then
M = .RecordCount
.MoveFirst
For N = 1 To M
If .Fields(0).Value = Id Then
Exit For
End If
.MoveNext
Next N
End If
End With
IdFound = N
End Function
祈、成功!
「番号」に重複がない長整数である事を前提にすると
一番簡単なのは、
テーブル「T_A」にフィールド「連番」(長整数)を設けて
VBA で「連番」を設定する事だと思います。
Public Sub Samp1()
Dim rs As DAO.Recordset
Dim sSql As String
sSql = "SELECT 連番 FROM T_A ORDER BY 名前, ランキング, 番号 DESC;"
Set rs = CurrentDb.OpenRecordset(sSql)
While (Not rs.EOF)
rs.Edit
rs(0) = rs.AbsolutePosition + 1
rs.Update
rs.MoveNext
Wend
rs.Close
Set rs = Nothing
End Sub
※ 上記 DAO の AbsolutePosition は、0 スタートの連番になるので
これを利用して単純に設定するものです。
(ADO に書き換える場合は、1 スタートなので + 1 は不要になります)
注意するのは、どの順番で得ておくか、だけです。
( ORDER BY 名前, ランキング, 番号 DESC )
フィールド「連番」を設けずにクエリだけで・・・とした場合、
1レコード毎に OpenRecordset すると、それだけでも遅くなると思うので
この「番号」の「連番」は何・・・
1度求めたものを Dictionary に格納しておいて、その中の情報を返す様にしてみます。
Dim dic As Object
Public Function myNoInit() As Boolean
Dim rs As DAO.Recordset
Dim sSql As String
If (dic Is Nothing) Then
Set dic = CreateObject("Scripting.Dictionary")
End If
dic.RemoveAll
sSql = "SELECT 番号 FROM T_A ORDER BY 名前, ランキング, 番号 DESC;"
Set rs = CurrentDb.OpenRecordset(sSql)
While (Not rs.EOF)
dic(rs(0).Value) = rs.AbsolutePosition + 1
rs.MoveNext
Wend
rs.Close
Set rs = Nothing
myNoInit = True
End Function
Public Function myNo(vNum As Variant) As Long
If (IsNull(vNum)) Then Exit Function
If (dic Is Nothing) Then Call myNoInit
myNo = dic(vNum)
End Function
上記を標準モジュールに記述しておいて、クエリでは以下のように
SELECT 番号, 名前, ランキング, myNo(番号) AS 連番
FROM T_A
WHERE myNoInit()
ORDER BY 名前, ランキング, 番号 DESC;
※ 不都合あれば修正してください。
お詫びと訂正:
× IdFound("SELECT ID FROM T1 ORDER BY [ランキング], 名前",[ID])
〇 IdFound("SELECT ID FROM T1 ORDER BY 名前, [ランキング],",[ID])
当然に、[ID]が出現する位置を確認する為の SQL文とクエリの並び(ORDER BY XXX, XXX)は同じでなければなりません。先の回答では、それが一致していませんでした。当然に、名前→ランキングの順で並べないと正しく連番は付与されません。ちょっと、単純なミスがありましたので訂正しておきます。
PS、IdFound()→InRecord()
なお、関数名ですが Instr()に近い働きですので InRecord()と命名すべきだったかも知れません。