将行添加到 Access 表时生成一个序号(每组)

Posted

技术标签:

【中文标题】将行添加到 Access 表时生成一个序号(每组)【英文标题】:Generate a sequential number (per group) when adding a row to an Access table 【发布时间】:2013-11-04 05:39:05 【问题描述】:

我有一个 MS Access (.accdb) 表,其中包含如下数据:

Location Number
-------- ------
ABC      1
DEF      1
DEF      2
GHI      1
ABC      2
ABC      3

每次我将数据附加到表时,我都希望该数字对于该位置是唯一的。 我正在通过 MS Excel VBA 访问此表 - 我想创建一个新记录(我在代码中指定位置)并创建一个唯一的序列号。 有没有办法设置表格,以便在添加记录时自动发生这种情况? 我是否应该编写一些描述的查询并确定每个位置的下一个编号,然后在创建记录时同时指定位置和编号?

我正在写信如下:

    Set rst = New ADODB.Recordset
    rst.CursorLocation = adUseServer
    rst.Open Source:="Articles", _
         ActiveConnection:=cnn, _
         CursorType:=adOpenDynamic, _
         LockType:=adLockOptimistic, _
         Options:=adCmdTable
    rst.AddNew
    rst("Location") = fLabel.Location 'fLabel is an object contained within a collection called manifest
    rst("Number") = 'Determine Unique number per location
    rst.Update

任何帮助将不胜感激。

编辑 - 添加了我正在努力解决的 VBA 代码,因为问题被搁置了

【问题讨论】:

Access 数据库是.mdb 文件,还是.accdb 文件? 嗨 - 数据库是一个 .accdb 文件 好的,很好。现在确定您的环境是否使用 Access 2010(或更高版本)。如果是,那么edit 您的问题与该信息并询问您是否可以使用Data Macro 实现您的目标。 (提示:你可以。)然后,如果你的问题被重新打开,我可以回答它。 嗨,戈德 - 非常感谢您的帮助。我在考虑长期,但如果我将来某个时候将其迁移到 SQL 服务器,数据宏将无法工作。理想情况下,我想在大部分代码所在的 Excel VBA 代码中处理这个问题。这只是一般应用程序的一小部分。 【参考方案1】:

我怀疑你正在寻找这样的东西:

Dim con As ADODB.Connection, cmd As ADODB.Command, rst As ADODB.Recordset
Dim newNum As Variant

Const fLabel_Location = "O'Hare"  ' test data

Set con = New ADODB.Connection
con.Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Users\Public\Database1.accdb;"

Set cmd = New ADODB.Command
cmd.ActiveConnection = con
cmd.CommandText = "SELECT MAX(Number) AS maxNum FROM Articles WHERE Location = ?"
cmd.CreateParameter "?", adVarWChar, adParamInput, 255
cmd.Parameters(0).Value = fLabel_Location
Set rst = cmd.Execute
newNum = IIf(IsNull(rst("maxNum").Value), 0, rst("maxNum").Value) + 1
rst.Close

rst.Open "Articles", con, adOpenDynamic, adLockOptimistic, adCmdTable
rst.AddNew
rst("Location").Value = fLabel_Location
rst("Number").Value = newNum
rst.Update
rst.Close
Set rst = Nothing
Set cmd = Nothing
con.Close
Set con = Nothing

但请注意,此代码不是多用户安全的。如果有多个用户同时运行此代码的可能性,那么您可能会得到重复的 [Number] 值。

(为了使代码对多用户安全,您需要在 ([Location], [Number]) 上创建一个唯一索引并添加一些错误捕获,以防 rst.Update 失败。)

编辑

对于 Access 2010 及更高版本,请考虑使用事件驱动的数据宏,并在我的other answer to this question 中显示。

【讨论】:

感谢上帝。我今天不在办公桌前,除了您的“CreateParameter 行和它下面的行外,我了解上述内容。我会试一试,如果解决了,我会在可以测试时标记它。谢谢:)【参考方案2】:

您需要在数据类型为AutoNumber 的表中添加一个新列。

office.microsoft.com: Fields that generate numbers automatically in Access

您可能还应该将此列设置为主键。

【讨论】:

嗨,丹尼,感谢您的回复。我不确定这是我所追求的解决方案。我需要的数字不是表唯一的,但我确实需要每个位置唯一的数字。如果我误读了您的答案或错过了一些功能,请赐教:) 啊,对不起,我刚刚重新阅读了你的问题 - 你是对的,这不是你想要的。【参考方案3】:

对于 Access 2010 及更高版本,这是一种更好的方法。它使用表的Before Change数据宏推导出下一个序号,并将其放入新记录的[Number]字段中:

这种方法的优点是:

无论如何添加新记录,都会应用序列号。 Excel VBA代码不用担心创建序列号;它“刚刚发生”。 由于此代码位于表级别,它应该对于多用户环境是安全的。

有关数据宏的详细信息,请参阅

Create a data macro

【讨论】:

以上是关于将行添加到 Access 表时生成一个序号(每组)的主要内容,如果未能解决你的问题,请参考以下文章

将行分组到一个新的 Pandas DataFrame 中,每组一行

将行从一个表复制到另一个表时如何解决数据截断错误,两个表具有相同的模式?

长文本(> 255 个字符)在 MS Access 2013 中导入和添加到现有表时被截断

将多个Excel文件导入一个Access表时如何添加文件名

由于带有 sequelize.js 的 UUID 外键,尝试将行插入表时出错

access 数据库 添加序号语句