想使用delphi自动生成“年后两位+月份+四位编号”的流水号
现新增第一条记录的时候能生成
第二条的时候流水号的最后一位就没了
大家帮忙看看我的代码错在哪里
procedure TForm1.FormCreate(Sender: TObject);
var
i:Real;
newid:string;
begin
with ADOQuery1 do
begin
Close;
SQL.Clear;
SQL.Add(' select * from JYBB where id like '+''''+FormatDateTime('YYMM',Now())+'%'+'''');
Open;
if ADOQuery1.IsEmpty then
newid:=formatdatetime('YYMM',Now())+'0001'
else
begin
Close;
SQL.Clear;
SQL.Add('select max(id)+1 as i from JYBB where left(id,4)='''+FormatDateTime('YYMM',Now())+'''') ;
Open;
newid:=FormatDateTime('YYMM',Now())+ FormatFloat('000',i);
end;
Edit3.Text:=newid;
end;
end;
现新增第一条记录的时候能生成
第二条的时候流水号的最后一位就没了
大家帮忙看看我的代码错在哪里
procedure TForm1.FormCreate(Sender: TObject);
var
i:Real;
newid:string;
begin
with ADOQuery1 do
begin
Close;
SQL.Clear;
SQL.Add(' select * from JYBB where id like '+''''+FormatDateTime('YYMM',Now())+'%'+'''');
Open;
if ADOQuery1.IsEmpty then
newid:=formatdatetime('YYMM',Now())+'0001'
else
begin
Close;
SQL.Clear;
SQL.Add('select max(id)+1 as i from JYBB where left(id,4)='''+FormatDateTime('YYMM',Now())+'''') ;
Open;
newid:=FormatDateTime('YYMM',Now())+ FormatFloat('000',i);
end;
Edit3.Text:=newid;
end;
end;
也会不行的如果i是09100001,那么这个结果将会是9100001,再加上YYMM,最后是09109100001newid:=FormatDateTime('YYMM',Date)+ Copy(ADOQuery1.FieldValues['i'],5,4);
改为
SQL.Add(' select max(id)+1 as i from JYBB where id like '+''''+FormatDateTime('YYMM',Now())+'%'+'''');
感觉你产生的流水号与实现语音无关,就是用的数据库的操作实现的我不写DELPHI,刚没事来看看
declare @id int
declare @ym varchar(20)
select @ym=getdate()转为yyyymmdd格式后的3-6位
select @id=isnull(max(right(id,4)),0) from tb where id like @ym+'%'
set @id=@id+1
insert tb (id) values (@ym+right('0000'+@id,4))
select @id --返回新的id给客户端,以便补充其他字段
你FORMAT字符串有问题,自己写个填充函数比如
/*============================
piLength --填充后的字符串长度
psString --被填充的字符串
psFillString --用该字符进行填充
返回值: 填充后的字符串
MagicYang 2009-10-24
=============================*/
function FillLeftString(piLength: integer;psString,psFillString: String): string;
var
iTmp: integer;
sTmp: string;
begin
result := '';
if Length(psString) >=piLength then
Exit;
for i:=0 to piLength-Length(psString) do
sTmp := psFillString+sTmp;
result := sTmp;
end;
并且,如果有并发处理,这样合成的顺序好不能保证是唯一的。
建议你再创建一个表,这个表就两个字段,一个是记录 yymm 的,一个是记录当前顺序号最大值的,例如
0910 0003
0909 0039
......
上面表示09年10月份当前最大编号是3,09年9月份当前最大编号是39,当然,如果你仅仅处理当前数据(没有对历史数据的新增问题),那么只要一条记录就足够了,就记录当前年月的最大号。
然后你的程序中单独写一个函数用来获得指定年月的最大值,这个函数传入要查找的年和月,返回这个年月的最大值+1,在函数内部,采用select for update的方式打开表(写锁定的方式打开表),或者值之后,再+1,然后提交给数据库并关闭表(释放锁)。
这样能保证你的序列号是唯一的,并且能保证你的号码是正确的。
这样设计后,你在打开数据表的时候,仅仅使用 select * from JYBB where id > #39 + FormatDateTime('yymm', now()) + '0000' + #39就可以了,这样打开表,如果你在id上建立了索引,是非常快的。也省去了你再次用max的方式打开表。
比如,你获得最大值的函数是getMaxNum(),则,需要最大号的时候,调用下就可以了newid := getMaxNum(FormatDateTime('yymm', now()));(当然了,上面的调用方式也意味着你的getMaxNum函数里面要把传入的年和月接到最大编号上返回,呵呵)
var
i,tnum:integer;
t,t1,t2,t3:string;
Year,Month,Day:WORD;
begin
if messagedlg('确认添加新记录吗?',mtconfirmation,[mbYes,mbNo],0)=mrYes then
begin
DecodeDate(Now,Year,Month,Day);
t1:=inttostr(month);
tnum:=month;
with adoquery1 do begin
close;
sql.Clear;
sql.Add('select * from T_dropdownexp order by no asc');
open;
for i:=0 to 26 do begin //新增标题
stringgrid1.Cells[i,0]:=adoquery1.Fields[i].FieldName;
end;
end;
if tnum<10 then begin //判断月份是否为个位数,加0补齐两位数
t1:='0'+t1;
end;
t2:=inttostr(year);
if adoquery1.IsEmpty then
stringgrid1.Cells[0,1]:=t2+t1+'0001' //如记录为空,记录从1开始
else
with adoquery1 do begin
close;
sql.Clear;
sql.Add('select * from T_dropdownexp order by no asc');
open;
adoquery1.Last;
t:=adoquery1.Fields[0].AsVariant;
t3:=copy(t,5,2); //在NO中取两位数为月份
if t1<>t3 then //判断月份,相同则累计,不同则重新计
stringgrid1.Cells[0,1]:=t2+t1+'0001'
else
stringgrid1.Cells[0,1]:=inttostr(strtoint(t)+1);
end;
stringgrid1.Cells[1,1]:=edit2.text; //新增输入内容
stringgrid1.Cells[2,1]:=edit3.text;
stringgrid1.Cells[3,1]:=edit4.text;
stringgrid1.Cells[4,1]:=edit5.text;
stringgrid1.Cells[5,1]:=edit6.text;
stringgrid1.Cells[6,1]:=edit7.text;
stringgrid1.Cells[7,1]:=edit8.text;
stringgrid1.Cells[8,1]:=edit9.text;
stringgrid1.Cells[9,1]:=edit10.text;
stringgrid1.Cells[10,1]:=edit11.text;
stringgrid1.Cells[11,1]:=edit12.text;
stringgrid1.Cells[12,1]:=edit13.text;
stringgrid1.Cells[13,1]:=edit14.text;
stringgrid1.Cells[14,1]:=edit15.text;
stringgrid1.Cells[15,1]:=edit16.Text;
stringgrid1.Cells[16,1]:=memo4.Text;
stringgrid1.Cells[17,1]:=edit22.Text;
stringgrid1.Cells[18,1]:=memo5.Text;
stringgrid1.Cells[19,1]:=edit23.Text;
stringgrid1.Cells[20,1]:=memo6.Text;
stringgrid1.Cells[21,1]:=combobox1.Text;
stringgrid1.Cells[22,1]:=combobox2.Text;
stringgrid1.Cells[23,1]:=combobox3.Text;
end;
end;
我以前接觸過的是把目前的流水號(就後面五位,不包括年月日)保存在數據庫的一個表裏面,這個表裏面存放了所有表(需要有流水號)的流水號情況。
每次要產生流水號的時候就從這個表裏面來取,用SQL函數來調用,這樣速度也快,而且也不太容易會出現同號的情況