如何实现 单号:20021004001, 20021004002 ,20021005001这样的数据.(50分)

  • 主题发起人 主题发起人 李锦江
  • 开始时间 开始时间
对不起,cxz9的答案不是最完美的!

他的答案用在单机上可以,不会出现麻烦。但用在网上就不行了,会出现跳号。
因为有时候一个号码产生了以后,有可能会放弃它。
当然,一般来说,跳号的现象客户是能接受的,只有在特殊情况下要考虑,下面是我的做法,
未经测试,请包涵:

1.建一个流水号表 lsh(id int, xh int),其中字段id是自增的;给一个初始数据(1,1)。
2.建一个存储过程:
create procedure get_lsh
@st int, --用来标记取号的状态,0表示取一个号码,其它数表示还一个号码
@hm char(11) output --用来存放号码,如果失败,则其值为'error'
as
declare @@tmp int,
@@i int

if @st = 0
begin
select @@i = id, @@tmp = xh from lsh where id = min(id)
if @@i = 1 then
update lsh set xh = xh + 1 where id = 1
else delete from lsh where id = @@i
set @hm = cast(year(getdate()) as char(4)) + cast(month(getdate()) as char(2))
+ cast(day(getdate()) as char(2))
@@i = 4 - len(ltrim(rtrim(cast(@@tmp as char)))
if @@i < 0 set @hm = 'error'
while @@i > 0
begin
set @hm = @hm + '0'
set @@i = @@i - 1
end
if @hm <> 'error' set @hm = @hm + ltrim(rtrim(cast(@@tmp as char))
end
else begin
if cast(@hm as int) = 0 set @hm = 'error'
else begin
set @tmp = cast(substring(@htm, 9, 4) as int)
if @tmp = 0 set @hm = 'error'
if @hm <> 'error'
begin
insert into lsh(xh) values(@tmp)
set @hm = '0'
end
end
end

当然,这样做也不能完全避免跳号,只是可以少跳许多。
 
我写的不过尾值是由EDIT得到,你可以自己改改,很简单的
function getid:string;
var
s,m:string;
begin
m:=form1.Edit1.Text;
while length(m)<>3 do
begin
if length(m)>3 then m:=copy(m,length(m)-3,3);
if length(m)<3 then m:='0'+m;
end;
s:=formatdatetime('yyyymmdd',date);
result:=s+m;
end;
 
如果在单机上实现流水号的生成,不必采用数据库既可以行。——采用INI文件方式。
下面是BCB的实现:


AnsiString getFlowID(int ID, bool bIn)
{
/**
* 产生流水号函数:要求输入当前ID(编号)和是否是入
* 首先将会在系统目录下产生ISMFLOW.INI文件
* 如果以前的流水号的ID与现在地不同,将会返回味空,失败的流水号
* 如果时间与当天相同,则依据序号直接增加,不同将会产生新的一天FLOWID
***/
AnsiString FlowFile = "//ISMFLOW.INI";
char SysDir[256];
memset(SysDir, 0, sizeof(SysDir));
GetSystemDirectory(SysDir, 256);
FlowFile = SysDir + FlowFile;
if (!FileExists(FlowFile)){
AnsiString strID = IntToHex(ISMID, 2);
strID = strID + "1900010112010100" + "000000";
TStringList *strList = new TStringList;
strList->Add("[FLOWID]");
strList->Add("IN=" + strID + "00");
strList->Add("OUT=" + strID + "11");
strList->SaveToFile(FlowFile);
strList->Clear();
delete strList;
strList = NULL;
}
TIniFile *iniFile;
iniFile = new TIniFile(FlowFile);
AnsiString flowID;
if (bIn){
flowID = iniFile->ReadString("FLOWID", "IN", "");
}else{
flowID = iniFile->ReadString("FLOWID", "OUT", "");
}

AnsiString tmpStr = "0x" + flowID.SubString(1,2);
if (tmpStr.ToInt() != ID) return "";
AnsiString strGetDate = flowID.SubString(3, 16);
AnsiString strIndex;
if (isToday(strGetDate, Now())){
strIndex = StrToInt(flowID.SubString(19, 6));
}else{
strIndex = "000000";
}
strIndex = getIndex(strIndex.ToInt(), true);
AnsiString strReturnID;
if (bIn){
strReturnID = IntToHex(ID,2)
+ FmtDT(Now())
+ strIndex
+ "00";
iniFile->WriteString("FLOWID", "IN", strReturnID);
}else{
strReturnID = IntToHex(ID,2)
+ FmtDT(Now())
+ strIndex
+ "11";
iniFile->WriteString("FLOWID", "OUT", strReturnID);
}
delete iniFile;
iniFile = NULL;
return strReturnID;
}

AnsiString FmtDT(TDateTime dt)
{
/**
* 将时间转换为标准的字符格式。
* 时间格式为:时间格式为YYYYMMDDHHNNSSXX
YYYY:年
MM :月
DD :日
HH :时
NN :分
SS :秒
XX :毫秒
***/
AnsiString tmpDT1 = FormatDateTime("YYYYMMDDHHNNSS", dt);
AnsiString tmpDT2 = FormatDateTime("ZZZ", dt);
return tmpDT1 + tmpDT2.SubString(1,2);
}
 
/*产生进货编号
Samples->dbo.NewVoucher_No(getdate()) */
CREATE FUNCTION NewVoucher_No(@dDate datetime)
RETURNS char(12)
Begin
Declare @id varchar(12)
Declare @chrNum char(12)
Declare @chrToday char(10)
Declare @chrExpress char(8)
Declare @intNum integer

Set @chrToday = Convert(char(10),@dDate,20)
/*年月日*/
Set @chrExpress = SubString(@chrToday,1,4)+SubString(@chrToday,6,2)+SubString(@chrToday,9,2)
Set @chrExpress = Cast(@chrExpress As char(8))
/* 找出目前最大的编号 */
Select @chrNum=isNull(Max(Voucher_No),'') From Stock Where Voucher_No Like @chrExpress+'%'

--Select Top 1 @chrNum = Voucher_No From Stock Where Voucher_No Like @chrExpress+'%' Order By Voucher_No Desc
--If @@RowCount = 0 /* 如果是第一笔记录 */
If (@chrNum='')
Return @chrExpress+'0001'
Set @intNum = Cast(Right(@chrNum, 4) As int) + 1
Set @id = Cast(@intNum As varchar)
Return @chrExpress + Replicate('0', 4-Len(@id)) + @id
End
或者
CREATE proc getminmaxno @na char(3) as
declare @tno char(12);
declare @td char(9);
declare @pp char(10);
declare @num int;
set @pp=convert(char(10),getdate(),20);
set @td=@na+substring(@pp,3,2)+substring(@pp,6,2)+substring(@pp,9,2)
set @td=cast(( @td) as char(9))
select @tno=isnull(max(min_billid),'') from minhead where min_billid like @td+'%'
if (@tno='')
begin
set @tno=@td+'001'
end
else
begin
set @num=cast(substring(@tno,10,3) as int)+1;
set @tno=substring(@tno,1,9);
if (@num<10) set @tno=cast(@tno as char(9))+'00'+cast(@num as char(1))
if (@num>=10) and (@num<100) set @tno=cast(@tno as char(9))+'0'+cast(@num as char(2))
if (@num>=100) set @tno=cast(@tno as char(9))+cast(@num as char(3))
end
select @tno as maxno

GO
 
function Tadd_new_form.get_t_id():string;//得到总表的最大ID值
begin
if formatdatetime('dd',now)='01' then
result:=formatdatetime('yyyymmdd',now)+'0001'
else
with dm1.adoquery1 do
begin
close;
sql.Clear ;
sql.add('select max(id) from bxd');
open;
first;
if RecordCount>0 then
if trim(Fields[0].asstring)<>''then
result:=inttostr(strtoint64(Fields[0].asstring)+1)
else
result:=formatdatetime('yyyymmdd',now)+'0001'
else
result:=formatdatetime('yyyymmdd',now)+'0001';
end;
if result<formatdatetime('yyyymmdd',now)+'0001' then result:=formatdatetime('yyyymmdd',now)+'0001';
end;
 
http://www.delphibbs.com/keylife/iblog_show.asp?xid=5161
 
后退
顶部