单号自动增加 ( 积分: 10 )

  • 主题发起人 主题发起人 admin2008
  • 开始时间 开始时间
A

admin2008

Unregistered / Unconfirmed
GUEST, unregistred user!
就是入库单号是自动增加的 如 a20071010001 当再打开窗口时窗口中的edit1.text:=a20071010002,当然当表中的单号字段是空值的话 就是a20071010001
怎么实现呢 我写了一点不会写了
with adoquery2 do
begin
close;
sql.Clear ;
sql.Text:='select max(IN_ID) from INHEAD where substring(in_id,1,9)=:num';
adoquery1.Parameters.ParamByName('num').Value:=dw_name+FormatDateTime('yyyymmdd',date());
open;
edit1.Text:=
end;
 
我按照我的思路把你的代码改了一下,不过我没有进行调试,希望对你能有所帮助.
with adoquery2 do
begin
close;
sql.Clear ;
sql.Text:='select max(IN_ID) as maxbh from INHEAD where substring(in_id,1,9)=:num';
adoquery1.Parameters.ParamByName('num').Value:=dw_name+FormatDateTime('yyyymmdd',date());
open;
end;
if adoquery1.fieldbyname('maxbh').asstring='' then edit1.Text:=dw_name+FormatDateTime('yyyymmdd',date())+'001'
else
edit1.Text:=dw_name+inttostr(strtoint(copy(maxbh,2,11))+1);
 
单机的话这样子可以,要是网络如c/s就不行了
 
我是这样处理的,用一个表来保存当前值,不过会又多出一个问题,在删除后哪么将出现跳号。
 
我这是网络版的呀(c/s)555a 那样怎么处里呢
 
在CS环境下,可以使用类似操作系统的PV操作,把提取最大号码的一段代码(即临界区)封锁住,即在某一个时间内,只允许一台机器运行这段代码.你可以在表中加入一个标志字段,只有它为某个值时才允许进入临界区,进入和退出临界区记住要修改它的值.
我的程序也是CS方式的,不过只有一台机器需要产生号码,所以我就懒的写这么多代码了.
 
CS的也是一样,设计一个叫计数器的表,我们是这样叫的,记数名,前缀,是否加日期,长度,值比如你的这个就可以记录成今天是20071011
名称A1 前缀A 日期加 长度12 值1
第一次A1生成A20071011001.生成后,更改值为累加成2
第二次A1生成A20071011002.生成后,更改值为累加成3
第三次A1生成A20071011003.生成后,更改值为累加成4
你也可以设置其它生成条件。
 
先max(单号),然后把单号分离成字母和数字,数字+1,然后在合并,就这样
 
就是在新增时将原来的最大值+1,单机版不用再判断了。
若是在C/S下,保存时就需要再重复判断一下即可。
最后写个通用的函数,我以前也有写过。
 
我觉得有两种方法可以实现。
1、打开窗口时,显示a20071010001,这时,已经将a20071010001这条记录插入到表INHEAD里面。其他客户端再进入是MAX(IN_ID)+1,就是下一个流水号了。我们系统就是使用这种的。
2、第二种呢,就是像hfqxfx说的那样。建一个专门记录流水号的表。
但这两种方法都会造成跳号问题。如果是C/S的话,我们也没有办法避免跳号这个问题。如果有什么好方法,大家讨论下吧~
 
设计数据库的 时候,设计一个表单号的表,把单号分割成多个字段,分别存储单号表中,使用的时候再合成提取
 
with adoquery2 do
begin
close;
sql.Clear ;
sql.Text:='select max(IN_ID) as maxbh from INHEAD where substring(in_id,1,9)=:num';
adoquery2.Parameters.ParamByName('num').Value:=dw_name+FormatDateTime('yyyymmdd',date());
open;
end;
for i:=0 to adoquery2.recordcount -1 do
begin
if adoquery2.fieldbyname('maxbh').asstring='' then
edit1.Text:=dw_name+FormatDateTime('yyyymmdd',date())+'001'
else
edit1.Text:=dw_name+inttostr(strtoint(copy('maxbh',2,11))+1);
end;
这段代码当编号为空时 保存就可以 编号是 a20071012001 当我再打开窗口时编号应为a20071012002 但是这时就出错了 提示 字段maxbh不是一个整型的,
因为表中的字段IN_ID是nvarchar(20)的
 
自动生成单号的方法....
//单号长度,起始字符,字段名,加入天数
function TDM.CreateNO(FieldLength: Integer; NO, TableName,
FieldName: string; IsDay: boolean): string;
var
bh,Len:integer;
y,m,d:word;
y1,m1,d1,str:string;
begin
Result:='';
try
DecodeDate(Date,y,m,d);
NO:=Trim(NO);
Len:=Length(NO);
m1:=IntToStr(m);
d1:=IntToStr(d);
y1:=Copy(IntToStr(y),3,2);
if m<10 then m1:='0'+m1;
if d<10 then d1:='0'+d1;
with TmpData do
begin
Close;
CommandText:='select Top 1 '+FieldName+' from '+TableName
+' where SUBSTRING('+FieldName+',1,'+IntToStr(Len)+')=:str1 and '
+' SUBSTRING('+FieldName+','+IntToStr(Len+1)+',2)=:y and '
+' SUBSTRING('+FieldName+','+IntToStr(Len+3)+',2)=:m ';
if IsDay then
begin
CommandText:=CommandText+' and SUBSTRING('+FieldName+','+IntToStr(Len+5)+',2)=:d ';
Parameters.ParamByName('d').Value:=d1;
end;
CommandText:=CommandText+' order by '+FieldName+' DESC';
Parameters.ParamByName('str1').Value:=NO;
Parameters.ParamByName('y').Value:=y1;
Parameters.ParamByName('m').Value:=m1;
open;
if IsDay then
str:=NO+y1+m1+d1+StringOfChar('0',FieldLength-Len-7)+'1'
else
str:=NO+y1+m1+StringOfChar('0',FieldLength-Len-5)+'1';
if Not IsEmpty then
begin
if IsDay then
begin
bh:=strtoint(Copy(trim(Fields[0].AsString),Len+7,FieldLength-len-6))+1;
str:=StringOfChar('0',FieldLength-Len-6-Length(IntToStr(bh)))+IntToStr(bh);
Str:=NO+y1+m1+d1+str;
end
else
begin
bh:=strtoint(Copy(trim(Fields[0].AsString),Len+5,FieldLength-len-4))+1;
str:=StringOfChar('0',FieldLength-Len-4-Length(IntToStr(bh)))+IntToStr(bh);
Str:=NO+y1+m1+str;
end;
end;
Result:=str;
end;
except
Result:='';
end;
end;
 
来自:跳狗的墙墙, 时间:2007-10-13 15:31:39, ID:3842227
我的方法我用了 当数据库的单号字段是空的话 就显示 为 a20071013001
数据保存了 可是当我下次再打开时edit1的内容还是a20071013001 这时就不能保存数据了 单号不能重复
我的调用是 edit1.Text:=CreateNO(10,'a','inhead','in_id',true);
它不能自加1
 
最好在存储过程中实现,我看 金蝶K3软件就是这样
 
建立一个流水号的表,里面存储最后一个使用的流水号
如果是单用户版本,如果是单用户,不会产生并发冲突,按照规则生成流水号即可
如果是多用户版本,需要考虑并发冲突,
如果使用3层技术,可以在中间层使用操作系统的同步原语解决
如果是c/s结构,可以考虑在使用事务+表级锁定解决
 
后退
顶部