我有一个以name, age, city
为列的员工表。我想在运行时显示一个列,从1开始我的行号。我在Access中使用SQL。
答案 0 :(得分:1)
从您的查询中调用以下函数。
Public Function GetNextNum(str As String) As Long
num = num + 1
GetNextNum = num
End Function
需要注意的是,您必须至少有一个参数(即使您不需要一个参数),否则该函数只会被调用一次并为所有行返回1.
在运行查询之前,将全局变量num
设置为0.
答案 1 :(得分:1)
你只需要一个功能来获得一个非常快速,甚至可以组合的"行计数器,有或没有自动重置计数器。
有关典型用法,请参阅内嵌评论:
Public Function RowCounter( _
ByVal strKey As String, _
ByVal booReset As Boolean, _
Optional ByVal strGroupKey As String) _
As Long
' Builds consecutive RowIDs in select, append or create query
' with the possibility of automatic reset.
' Optionally a grouping key can be passed to reset the row count
' for every group key.
'
' Usage (typical select query):
' SELECT RowCounter(CStr([ID]),False) AS RowID, *
' FROM tblSomeTable
' WHERE (RowCounter(CStr([ID]),False) <> RowCounter("",True));
'
' Usage (with group key):
' SELECT RowCounter(CStr([ID]),False,CStr[GroupID])) AS RowID, *
' FROM tblSomeTable
' WHERE (RowCounter(CStr([ID]),False) <> RowCounter("",True));
'
' The Where statement resets the counter when the query is run
' and is needed for browsing a select query.
'
' Usage (typical append query, manual reset):
' 1. Reset counter manually:
' Call RowCounter(vbNullString, False)
' 2. Run query:
' INSERT INTO tblTemp ( RowID )
' SELECT RowCounter(CStr([ID]),False) AS RowID, *
' FROM tblSomeTable;
'
' Usage (typical append query, automatic reset):
' INSERT INTO tblTemp ( RowID )
' SELECT RowCounter(CStr([ID]),False) AS RowID, *
' FROM tblSomeTable
' WHERE (RowCounter("",True)=0);
'
' 2002-04-13. Cactus Data ApS. CPH
' 2002-09-09. Str() sometimes fails. Replaced with CStr().
' 2005-10-21. Str(col.Count + 1) reduced to col.Count + 1.
' 2008-02-27. Optional group parameter added.
' 2010-08-04. Corrected that group key missed first row in group.
Static col As New Collection
Static strGroup As String
On Error GoTo Err_RowCounter
If booReset = True Then
Set col = Nothing
ElseIf strGroup <> strGroupKey Then
Set col = Nothing
strGroup = strGroupKey
col.Add 1, strKey
Else
col.Add col.Count + 1, strKey
End If
RowCounter = col(strKey)
Exit_RowCounter:
Exit Function
Err_RowCounter:
Select Case Err
Case 457
' Key is present.
Resume Next
Case Else
' Some other error.
Resume Exit_RowCounter
End Select
End Function
答案 2 :(得分:0)
您有5种方法可供使用。
仅限报告 - 运行总和
如果您将此信息用于Access报告,则有一种简单的方法,不需要VBA或花哨的SQL。只需添加一个包含控件源集=1
的文本框,然后将Running Sum
设置为Over All
即可。
下面列出的其他方法适用于表格/数据表/记录集
相关子查询
您可以执行相关子查询。这个解决方案是完全独立的,但不是很通用。这将是类似的事情:
SELECT
(
SELECT COUNT(*)
FROM Employees AS x
WHERE x.EmployeeID <= e.EmployeeID
ORDER BY x.EmployeeID
) AS RowNumber,
e.EmployeeID
FROM Employees AS e;
请注意,由于相关子查询,性能会随着表中记录数量的增加而迅速降低。您可能必须自定义ORDER BY
子句以获得所需的号码分配,如果它不应该依赖于EmployeeID
而是其他东西(例如HireDate
)
VBA维持计数,仅向前记录集的功能
此方法可以更快地执行,但只能使用一次;当然不在表格/数据表中,因为在您浏览时会不断评估VBA功能。因此,这仅在以仅向前方式读取记录集时才适用。使用标准VBA模块:
Private Counter As Long
Public Function ResetRowNumber() As Boolean
Counter = 0
ResetRowNumber = (Counter = 0)
End Function
Public Function GetRowNumber(PrimaryKeyField As Variant) As Long
Counter = Counter + 1
GetRowNumber = Counter
End Function
然后在查询中使用:
SELECT
GetRowNumber([EmployeeID]) AS RowNumber,
EmployeeID
FROM Employees
WHERE ResetRowNumber();
请注意使用WHERE
隐式调用ResetRowNumber
函数的技巧。请注意,这只会在只有一个查询处于活动状态时才有效;拥有多个采用行号的查询会导致错误的结果。然而,实现非常简单,速度更快。
VBA保持计数并保留作业的功能
这比以前的方法更昂贵,但对于足够大的表,仍然比相关子查询解决方案便宜。这具有在表格/数据表中有用的优点,因为一旦给出了数字,就会再次给出它。同样,在标准VBA模块中:
Private NumberCollection As VBA.Collection
Public Function ResetRowNumber() As Boolean
NumberCollection = New VBA.Collection
ResetRowNumber = (NumberCollection.Count = 0)
End Function
Public Function GetRowNumber(PrimaryKeyField As Variant) As Variant
On Error Resume Next
Dim Result As Long
Result = NumberCollection(CStr(PrimaryKeyField))
If Err.Number Then
Result = 0
Err.Clear
End If
If Result Then
GetRowNumber = Result
Else
NumberCollection.Add NumberCollection.Count + 1, CStr(PrimaryKeyField)
GetRowNumber = NumberCollection.Count
End If
If Err.Number Then
GetRowNumber = "#Error " & Err.Description
End If
End Function
输入参数PrimaryKeyValue
引用非可空列(根据定义应该是主键列)非常重要。否则,我们无法知道如果已经将其发给记录,我们应该给出哪个号码。 SQL与以前的方法类似:
SELECT
GetRowNumber([EmployeeID]) AS RowNumber,
EmployeeID
FROM Employees
WHERE ResetRowNumber();
与之前的方法一样,这一次只适用于一个查询。如果您需要多个查询,那么您需要两倍的图层;一个集合,用于引用哪个查询集合,然后检查该查询的集合。这可能会有点毛茸茸。你可能也可以通过Scripting.Dictionary
获得更多的爆炸性,这是另一种选择。
另请注意,该函数现在返回Variant
,因为它可能会遇到意外错误。因为函数可以被调用多次,可能是几百甚至几千次,所以我们不能弹出一个消息框,所以我们可以模仿内置函数做什么并返回#Error
,这是与我们真正使用的基础类型Long
不兼容。
升级到SQL Server或其他RDBMS
Access是用于构建以数据为中心的应用程序的现象 RAD工具。但是,您不一定要使用其数据库引擎。您可以将数据迁移到免费RDBMS之一,使用ODBC链接并继续像以前一样使用Access应用程序,并获得SQL的强大功能,包括窗口函数ROW_NUMBER()
,这使得更容易实现比VBA。如果您正在考虑的不仅仅是获取行号,您可能需要考虑是否应将数据迁移到其他数据库引擎。
有关其他参考资料,请this may be helpful。