关于生成文档序列号的问题

wangdaoyuan 2003-06-27 10:43:53
客户单位要求我们实现如下的功能:
每当新建一个文档并保存后,文档的某个域的值就要加一,即实现文档序列号的功能
编程思路是:创建一个专门存储序列号的文档,每当新建一个文档的时候都从这个文档中取回下一个号码作为文档序列号。因为用户可能在保存之前退出这个新建文档,所以必须等到存储新建文档的时候对序列号文档加一。

以下为我从人民邮电出版社的《Notes编程疑难详解》中第75页找到的一段程序,有几个地方没有读懂,希望高手指点:

Option Public
Option Explicit
Const COUNTER_FOLDER_FROM_NAME$="(记数文档)"

Function SequentialNumber&(Byval CounterName$,Byval CounterToSave%)

On Error Goto SequentialNumberError

Dim CounterFieldName$
Dim session As New NotesSession
Dim db As NotesDatabase
Dim view As NotesView
Dim doc As NotesDocument
Dim docNext As NotesDocument
Dim CounterValue&
Dim FieldValue As Variant
Dim Ret%
Dim item As NotesItem
Dim FolderToBeCreated%
CounterFieldName$="MB"+CounterName$

Set db=session.CurrentDatabase
Set view=db.GetView(COUNTER_FOLDER_FROM_NAME$)

If view Is Nothing Then
FolderToBeCreated%=True
End If

Do
If Not FolderToBeCreated% Then
view.Refresh
Set doc=Nothing
Set doc=view.GetFirstDocument()
End If

If doc Is Nothing Or FolderToBeCreated% Then
Set doc=New NotesDocument(db)
doc.Form=COUNTER_FOLDER_FROM_NAME$
Call doc.Save(True,False)
doc.PutInFolder COUNTER_FOLDER_FROM_NAME$
If FolderToBeCreated% Then
Set view=db.GetView(COUNTER_FOLDER_FROM_NAME$)
FolderToBeCreated%=False
End If
Else
Set item=doc.GetFirstItem(CounterFieldName$)
If item Is Nothing Then
Call doc.ReplaceItemValue(CounterFieldName$,0)
Call doc.Save(False,False)
Else
FieldValue=doc.GetItemValue(CounterFieldName$)
If Not CounterToSave% Then
CounterValue&=FieldValue(0)+1
Exit Do
Else
Call doc.ReplaceItemValue(CounterFieldName$,FieldValue(0)+1)
Ret%=doc.Save(False,False)
If Ret% Then
CounterValue&=FieldValue(0)+1
Exit Do
End If
End If
End If
End If
Loop

Set doc=view.GetNextDocument(doc)
Do While Not doc Is Nothing
Set docNext=view.GetNextDocument(doc)
Call doc.Remove(True)
Set doc=docNext
Loop

SequentialNumber&=CounterValue&

SequentialNumberExit:
Exit Function

SequentialNumberError:
Msgbox "SequentialNumber",Err,Error$
SequentialNumber&=-1
Goto SequentialNumberExit

End Function



...全文
193 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
coralc 2003-07-02
  • 打赏
  • 举报
回复
你的改动主要是变为数字,如果你要使用数字域那就更简单了
oldbh:=@DbColumn("":"nocache";"";"noview";1);
newbhnumber:=@If(oldbh="";1;@Subset(oldbh;-1)+1);
@If(@IsNewDoc;newbhnumber;RegNo)

不过我记的在视图中排序,好象直接用数字是有问题的,也就是10会排在1后面2前面,所以最好还是用固定长度的文本好。
coralc 2003-07-01
  • 打赏
  • 举报
回复
很抱歉,上次答复你时未经过测试,因为我以前用过是带日期的序号,略有不同。真的不是为了骗你的分啊!

1、首先,视图名一定要和此处公式中一致,如noview
2、使用以下的公式:
oldbh:=@dbcolumn("":"nocache";"";"noview";1);
newbhnumber:=@if(oldbh="";1;@texttonumber(@subset(oldbh;-1))+1);
newbhstring:=@trim(@text(newbhnumber));
newbh:=@repeat("0";4-@length(newbhstring))+ newbhstring;
@if(@isnewdoc;newbh;bh)

这次我是已经测过的了。
wangdaoyuan 2003-07-01
  • 打赏
  • 举报
回复
To coralc(草珊瑚) :
可是我是把bh换为真正的域名了,还是出错呀!!!
域:‘RegNo':Incorrect data type for operator or @Function:number expected!

不知道你这里有没有实现文档序列号的数据库例子,有的话,可否发送一个到我的邮箱里面呀?
你要多少分,只要我有,都可以给你的。


wangdaoyuan 2003-07-01
  • 打赏
  • 举报
回复
谢谢你了,为了表示感谢,我开了2个帖子,你要来接分呦!
http://expert.csdn.net/Expert/topic/1978/1978863.xml?temp=.302807
http://expert.csdn.net/Expert/topic/1978/1978853.xml?temp=.7281

这里还有一个帖子,你也去里面回复一下吧,我问的是与这个问题同样的问题,可是没有人给我解答的。
http://expert.csdn.net/Expert/topic/1963/1963733.xml?temp=.700268
wangdaoyuan 2003-07-01
  • 打赏
  • 举报
回复
我刚才又实验了一下你给的程序,确实好使,谢谢你了,coralc(草珊瑚) !
wangdaoyuan 2003-07-01
  • 打赏
  • 举报
回复
我刚才又用你的代码实验了一次,确实是好使的,谢谢你了,coralc(草珊瑚) !
ora9i 2003-07-01
  • 打赏
  • 举报
回复
关注
wangdaoyuan 2003-07-01
  • 打赏
  • 举报
回复
To coralc(草珊瑚) :
我把你的这段程序改了一点,不出现上面所说的对话框了,但是现在是第一次使用时编号域的值为1,从第二次开始编号值就都是0了,你能不能帮助我改一下程序呢?
我改动后的程序:
oldbh:=@DbColumn("":"nocache";"";"noview";1);
newbhnumber:=@If(oldbh="";1;@TextToNumber(@Subset(oldbh;-1))+1);
newbhstring:=@Trim(@Text(newbhnumber));
newbh:=@Repeat("0";4-@Length(newbhstring))+ newbhstring;
@If(@IsNewDoc;@TextToNumber(newbh);RegNo)
coralc 2003-07-01
  • 打赏
  • 举报
回复
不要客气,不用另外送分了,我们上来主要目的是互相学习共同进步嘛,这个分又不能当人民币用。
wangdaoyuan 2003-07-01
  • 打赏
  • 举报
回复
谢谢你了,我马上去试,如果好用我马上开几个帖子给分给你!
这阵子一直麻烦你了,在下在此深深谢过!
coralc 2003-06-29
  • 打赏
  • 举报
回复
你的这个编号域名是否为bh呢,我公式中只是举例,假设该域名为编号,如果不是要把bh换为真正的域名.
wangdaoyuan 2003-06-28
  • 打赏
  • 举报
回复
可是我把编号域的类型设为文本、计算也出现这样的对话框:
域:‘bh’:Incorrect data type for operator or @Function:number expected!

这到底是怎么回事呢?


coralc 2003-06-28
  • 打赏
  • 举报
回复
因为我上面的公式,生成的编号是文本型的,你只要把值的类型改为:文本,计算就好了.因为在实际应用中发现,用文本型的在视图中比较好处理,要用做数值时只要转换一下就可以了.
wangdaoyuan 2003-06-28
  • 打赏
  • 举报
回复
To coralc(草珊瑚) :
我按照你说的做了,我设定编号域的类型为:数值、计算
可是每次我新建文档时,总是会出现对话框:
域:‘bh’:Incorrect data type for operator or @Function:number expected!
我把编号域的类型设为文本、计算也是这个样子。
在没有给编号域加上你告诉代码之前,是不出现这样的对话框的。
而且,我发现如果公式的最后一行:@if(@isnewdoc;newbh;bh)
用其他公式代替就不会出现对话框。
这到底是怎么回事呢?我查阅上面所有用到的公式的帮助文件也没有搞明白,希望你能帮忙解决!
coralc 2003-06-27
  • 打赏
  • 举报
回复
可以做到啊,更简单了呢,视图直接以编号排序即可,公式修改为:
oldbh:=@dbcolumn("":"nocache";"";"noview";1);
newbhnumber:=@if(@iserror(oldbh);1;@texttonumber(@subset(oldbh;-1))+1);
newbhstring:=@trim(@text(newbhnumber));
newbh:=@repeat("0";4-@length(newbhstring)) & newbhstring;
@if(@isnewdoc;newbh;bh)
firesyang 2003-06-27
  • 打赏
  • 举报
回复
同coralc(草珊瑚)相比,其实你的要求更简单了,只要视图按编号排序就可以了,如果用代理,可以在文档的保存事件中调用,然后查到该视图的第一条文档,取得编号,在加1,就可以。如果怕编号产生冲突,可以这样解决,在代理中首先取得当前编号,然后在一个指定视图中新建一条检测文档,记录当前编号和当前用户名称,保存。建立一个空循环,800,完毕后检查指定视图,第一条文档是否自己刚才创建的文档如果是,证明当前没有其他人正在编号,本文档顺利保存。如果第一条不是自己创建的,则重新取一次编号,重复刚才的几步,知道正常创建为止。最后,在服务器端做一个代理,在凌晨3点,删除指定视图中的检测文档。此种方法可能会降低系统速度,但可以将编号冲突的可能降到很低。当然对于发生异常死机等情况,可能会出现跳号的问题。
wangdaoyuan 2003-06-27
  • 打赏
  • 举报
回复
谢谢coralc(草珊瑚)了,但客户要求的是四位编号,而且与时间没有关系,只是要求从1开始,每次新建并保存一个文档后,编号域要自动加一,用你上面告诉的方法可以做到吗?
coralc 2003-06-27
  • 打赏
  • 举报
回复
其实比较简单的,可以用公式实现。
建立一个视图noview,以该文档的编号域bh排序,如果编号前还有其他限制项如年月,20020301这样的,就建两个列,第一个列是前六位排序,第二列才是后两位编号排序。
然后将编号域设为计算,公式为:
year:=@text(@year(@created));
month:=@if(@month(@created)<10;"0"+@trim(@text(@month(@created)));@trim(@text(@month(@created))));
oldbh:=@dblookup("":"nocache";"";"noview";year&month;2);
newbhnumber:=@if(@iserror(oldbh);1;@texttonumber(@subset(oldbh;-1))+1);
newbh:=@if(newbhnumber<10;"0"+@trim(@text(newbhnumber));@trim(@text(newbhnumber)));
@if(@isnewdoc;newbh;bh)

公式的好处就是如果用户将最后一个文档删除了,如果用的是生成编号文档,不太可能同时删除编号文档,则再新建文档时就会出现跳号,公式则不会。
不过这样有一个问题就是,可能在新建时看到的编号和保存后的编号不同,因为最终编号是保存时生成的。另外如果两个用户在同一秒保存文档,可能编号重复。不过如果用代理程序新建编号文档也有一样的问题。
wangdaoyuan 2003-06-27
  • 打赏
  • 举报
回复
书中写到:
函数的调用方式为:
SequentialNumber&(CounterName$,CounterToSave%)
此函数支持多个序列的序列号,CounterName$参数为要使用的序列号名称。CounterToSave%参数为True时,函数取回下一个序列号,并将该号码加一;当CounterToSave%参数为False时,函数只取回下一个序列号。

我的问题是:
1.函数调用时CounterName$参数应该以什么作为输入参数?
2.上面程序中的语句中的"MB"是何用意?
CounterFieldName$="MB"+CounterName$

535

社区成员

发帖
与我相关
我的任务
社区描述
企业开发 Exchange Server
社区管理员
  • 消息协作社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧