设为首页收藏本站Access中国

Office中国论坛/Access中国论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

12下一页
返回列表 发新帖
查看: 4888|回复: 11
打印 上一主题 下一主题

[模块/函数] 【源码示例】高效无重复自动编码解决方案

[复制链接]
跳转到指定楼层
1#
发表于 2011-1-28 14:45:25 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
一般自动编号功能,是先取得表中的已有最大号,然后在此基础上加1,如果每次生成编号都要从表中去取得最大编号,也就意味着每次生成编号都需要查询表中所有的记录,如果表中数据量很大,如有十万条以上,那么性能就很差了。(当然数据库引擎会有优化,但再优化总归是有限的)。并且这种方法在多用户同时录入时,存在生成重复编号的问题。

    本示例采用的方式为:调用GetNewID函数时,从编码表(USysSN)中读取指定编号字段对应的编号记录,如果记录为空,则先从原表中读取最大编号写入到该记录中;如果记录不为空,则读取该记录中的编号,并加1生成新编号,同时将编码表中的编号更新为新生成的编号。这样每次生成编号时只需要查询编码表中的很少的记录即可,并且由于生成的编号和原表无关,还可以防止多用户同时录入时生成重复编号的问题。

    假设某个表中有10万条记录,那么直接读取表生成新编号的方式需要查询10万条记录,而使用编码表的方式则每次只需要查询编码表中的几十条记录。


  1. '============================================================================================================================
  2. '-函数名称:    GetNewID
  3. '-功能描述:    高效率的文本型自动编号函数,除了第一次调用,以后每次生成编号时不需要再访问编号字段所在的表,因此效率非常高,
  4. '               表中数据量越大,效果越明显。并且在多用户环境下,也不会出现多个用户基于一个表同时录入时,会出现的编号重复问
  5. '               题。适用于各种单据的编号及流水码等,具体请参考使用示例。
  6. '-输入参数:    TableName       必需的,表名称或查询名称。
  7. '               FieldName       必需的,自动编号字段名。
  8. '               Digit           必需的,不包含前缀的序号位数。
  9. '               Prefixal        可选的,编号前缀字符串,除了单据类型的描述字符,还可以把其它信息要素如部门ID等加入到此参数中。
  10. '               DateFormat      可选的,编号中的日期部分格式,具体使用请参考Format函数中关于日期的数的部分说明。
  11. '-其它说明:    必需要有一个编号维护表配合使用,表名称:USysSN 字段:TableName|FieldName|LastID ,3个字段均为文本型,大小60。
  12. '-使用注意:
  13. '-返回参数:    返回生成的编号,出错时返回空字符串("")。
  14. '-兼 容 性:
  15. '-使用示例:    =GetNewID("Orders","OrderID",5,"XS","yymmdd")     返回示例:XS01042500004
  16. '               =GetNewID("Orders","OrderID",5,"XS","-yyyymmdd-") 返回示例:XS-20100425-00004
  17. '               =GetNewID("Orders","OrderID",5,"XS")              返回示例:XS00004
  18. '               =GetNewID("Orders","OrderID",5,"XS","-")          返回示例:XS-00004
  19. '               =GetNewID("Orders","OrderID",5)                   返回示例:00004
  20. '               =GetNewID("Orders","OrderID",5,"【售】")          返回示例:【售】00004
  21. '-相关调用:
  22. '-作    者:    红尘如烟
  23. '-创建日期:    2011-1-25
  24. '=============================================================================================================================
  25. Function GetNewID(TableName As String, FieldName As String, Digit As Integer, _
  26.                     Optional Prefixal As String, Optional DateFormat As String) As String
  27.     On Error GoTo Err_GetNewID
  28.     Dim strDate     As String
  29.     Dim strLastID   As String
  30.     Dim strSN       As String
  31.     Dim strWhere    As String
  32.    
  33.     If DateFormat <> "" Then strDate = Format$(Date, DateFormat)
  34.     strSN = String$(Digit, "0")
  35.     strWhere = "TableName='" & TableName & "' AND FieldName='" & FieldName & "'"
  36.     strLastID = Nz(DLookup("LastID", "USysSN", strWhere))
  37.    
  38.     If strLastID = "" Then
  39.         strLastID = Nz(DMax(FieldName, TableName), strSN)
  40.         CurrentDb.Execute "DELETE FROM USysSN WHERE " & strWhere
  41.         CurrentDb.Execute "INSERT INTO USysSN(TableName,FieldName) " & _
  42.                           "VALUES('" & TableName & "','" & FieldName & "')"
  43.     End If
  44.    
  45.     strLastID = Prefixal & strDate & Format$(Val(Right$(strLastID, Digit)) + 1, strSN)
  46.     CurrentDb.Execute "UPDATE USysSN SET LastID='" & strLastID & "' WHERE " & strWhere
  47.     GetNewID = strLastID
  48.    
  49. Exit_GetNewID:
  50.     Exit Function
  51.    
  52. Err_GetNewID:
  53.     GetNewID = ""
  54.     MsgBox Err.Description, vbCritical, "Error #" & Err
  55.     Resume Exit_GetNewID
  56. End Function
复制代码


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏3 分享分享 分享淘帖 订阅订阅

点击这里给我发消息

2#
发表于 2011-1-28 15:36:55 | 只看该作者
终于坐个沙发,思路不错!
3#
发表于 2011-1-28 21:36:25 | 只看该作者
学习了,谢谢...
4#
发表于 2011-1-28 22:57:36 | 只看该作者
一直都这样处理
5#
发表于 2011-1-29 08:36:17 | 只看该作者
下载学习,谢谢分享!
6#
发表于 2011-1-29 08:41:41 | 只看该作者
本帖最后由 ycxchen 于 2011-1-29 08:42 编辑

此函数是“高效率的文本型自动编号函数”,请问,数字型的不行?
7#
 楼主| 发表于 2011-1-29 11:10:02 | 只看该作者
andymark 发表于 2011-1-28 22:57
一直都这样处理

andymark说的不错,这个处理方法其实不是什么新鲜的东西,很多管理软件中都是这样处理的,只不过基本上都是基于SQL Server等数据库的,在Access中的应用,至少我在网上没看到过,所以做了这个示例给大家参考一下。
8#
 楼主| 发表于 2011-1-29 11:11:21 | 只看该作者
ycxchen 发表于 2011-1-29 08:41
此函数是“高效率的文本型自动编号函数”,请问,数字型的不行?

这里的函数只支持文本型的编号,不支持数字型,其实数字型的更好处理,另外一般来说如果是数字型的话,直接用“自动编号”数据类型的字段就行了,没什么必要再去自己写代码处理。

点击这里给我发消息

9#
发表于 2011-1-30 12:01:22 | 只看该作者
好贴。我也是使用这种方法。也是加了日期和前缀。不过,我还应用户需要加了个后缀。另外增加了一个顺序有多少位 及总长度多少位的控制。
看来,做到最后,大家都想到一块去了。
10#
发表于 2013-5-22 16:38:50 | 只看该作者
下载学习,谢谢分享!
您需要登录后才可以回帖 登录 | 注册

本版积分规则

QQ|站长邮箱|小黑屋|手机版|Office中国/Access中国 ( 粤ICP备10043721号-1 )  

GMT+8, 2024-5-20 07:51 , Processed in 0.079328 second(s), 35 queries .

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表