雨
雨季飘零
Unregistered / Unconfirmed
GUEST, unregistred user!
我做了一个刷卡考勤系统,使用ADCOMPORT实时监听串口,每个人的刷卡数据格式为:
AA AA EE 01 04 BC F6 25 06 06 04 08 07 FB 61
说明:AA AA EE 为前导符,即每组刷卡数据都包含AA AA EE
01 04 BC F6 25 为卡号
06 06 04 为年、月、日
08 07 为时、分
FB 61 为校验位
目的:是要将每次传上来的数据,把卡号、年月日、时分分别去出来保存至考勤主表,字段分别是CardNo,EnterDate,EnterTime
串口监听程序如下:
procedure TMainForm.ComPort2Trigger(CP: TObject; Msg, TriggerHandle,Data: Word);
var
I : Word;
C : Char;
s1 : String;
begin
try
case Msg of
APW_TRIGGERDATA :
{got 'login', send response}
;
APW_TRIGGERAVAIL :
{extract and display/process the data}
begin
s1:='';
for I:= 1 to Data do
begin
C := ComPort2.GetChar;
s1:=s1+inttohex(byte(c),2)+' ';
end;
//myMemoAddText1为自定义过程,用来处理每次接收的数据
myMemoAddText1(s1);
end;
APW_TRIGGERTIMER :
{timed out waiting for login prompt, handle error}
;
end;
except
Comport2.Open:=False;
ComPort2.Open:=True;
end;
end;
数据处理过程如下:
// 收入井数据
procedure TMainForm.myMemoAddText1(strAdd : string);
var
s:string;
str1,ED,ET,MachineNo : string;
begin
//接收读卡数据
edit1.Text:=edit1.Text+strAdd; //我放置了一个EDIT,以帮助我判断每次数据
if length(edit1.Text)=45 then //每次刷卡数据的长度是45
begin
MachineNo:=Copy(edit1.Text,7,2); //取AA AA EE中的EE,EE为机号
ED:= DateTimeToStr(Date); //取当前日期
s:=copy(trim(edit1.Text),10,2)+copy(trim(edit1.Text),13,2)+copy(trim(edit1.Text),16,2)+copy(trim(edit1.Text),19,2)+copy(trim(edit1.Text),22,2);
//取卡号,即0104BCF625
edit1.Clear; //取完卡号,存入变量后,清除EDIT ,以便为下次接收做好准备
ET:= Copy(DateTimeToStr(now),12,5);
//取当前时间
with ADOQuery1 do //依据卡号从员工库查出员工的工号,姓名等信息
begin
Close;
SQL.Clear;
SQL.Add('select WorkNO,Name,IDCardNo,Part1,Business1 from Employe where IDCardNo='''+s+''' or IDCardNo1='''+s+'''');
Open;
end;
if MachineNo='EE' then
begin
//保存至数据库
if trim(s)<>'' then
begin
//插入到考勤主表中
ADOCommand1.CommandText:='Insert into Attenrecord (CardNO,WorkNO,Name,Part1,Business1, Enterdate, Entertime) values ('''+s+''','''+ADOQuery1.FieldByName('WorkNO').AsString+''','''+ADOQuery1.FieldByName('Name').AsString+''','''+ADOQuery1.FieldByName('Part1').AsString+''','''+ADOQuery1.FieldByName('Business1').AsString+''','''+ED+''','''+ET+''')' ;
ADOCommand1.Execute;
label9.Caption:='入井:'+Str1+#13+'时间:'+ED+' '+ET;
//显示到一个PANEL上信息
end;
end;
end;
处理流程:从我放置的EDIT判断,正常应该是第一次传上来:
AA AA EE 01 04 BC F6 25 八个字节,第二次传上来:06 06 04 08 07 FB 61 后七个字节,两次加起来长度是45,在我保存到变量后就清除了EDIT内容,然后存入数据库。
出现问题:起初运行的半个月里还比较正常,每天的刷卡数据都能实时收到库中,但在运行一个月后出现了一些问题,突然会出现有人刷不上,其实是EDIT中留下了上个人刷卡的后七个字节,既06 06 04 08 07 FB 61,那么下个人的数据再传上来的时候,我再以长度判断就会出错,往后的每个人的卡号取的都是错的,还必须重新关开一下实时程序。
我的判断:我判断是不是由于主考勤表中数据量变大(每个月3万条),是不是由于上个人的数据还未保存完,就又传上来新的刷卡数据导致,因为每次出现问题都是上个人的后七个字节留在了EDIT中。可是我是取到卡号,存入变量就清空EDIT啊,我就想不通,即使这个人的数据没存,EDIT也应该是空的啊。
请教大家:1、我以长度来取每个人的卡号这种办法是不是不够妥当?
2、是不是直接插入主考勤表很耗费时间,是不是应该有个中间表过度一下?
3、针对我以上的问题,我应该如何处理,最好给出我如何处理卡号的代码,小弟在这里谢谢大家了!我先下了,能解决问题的请留下QQ号!谢谢
AA AA EE 01 04 BC F6 25 06 06 04 08 07 FB 61
说明:AA AA EE 为前导符,即每组刷卡数据都包含AA AA EE
01 04 BC F6 25 为卡号
06 06 04 为年、月、日
08 07 为时、分
FB 61 为校验位
目的:是要将每次传上来的数据,把卡号、年月日、时分分别去出来保存至考勤主表,字段分别是CardNo,EnterDate,EnterTime
串口监听程序如下:
procedure TMainForm.ComPort2Trigger(CP: TObject; Msg, TriggerHandle,Data: Word);
var
I : Word;
C : Char;
s1 : String;
begin
try
case Msg of
APW_TRIGGERDATA :
{got 'login', send response}
;
APW_TRIGGERAVAIL :
{extract and display/process the data}
begin
s1:='';
for I:= 1 to Data do
begin
C := ComPort2.GetChar;
s1:=s1+inttohex(byte(c),2)+' ';
end;
//myMemoAddText1为自定义过程,用来处理每次接收的数据
myMemoAddText1(s1);
end;
APW_TRIGGERTIMER :
{timed out waiting for login prompt, handle error}
;
end;
except
Comport2.Open:=False;
ComPort2.Open:=True;
end;
end;
数据处理过程如下:
// 收入井数据
procedure TMainForm.myMemoAddText1(strAdd : string);
var
s:string;
str1,ED,ET,MachineNo : string;
begin
//接收读卡数据
edit1.Text:=edit1.Text+strAdd; //我放置了一个EDIT,以帮助我判断每次数据
if length(edit1.Text)=45 then //每次刷卡数据的长度是45
begin
MachineNo:=Copy(edit1.Text,7,2); //取AA AA EE中的EE,EE为机号
ED:= DateTimeToStr(Date); //取当前日期
s:=copy(trim(edit1.Text),10,2)+copy(trim(edit1.Text),13,2)+copy(trim(edit1.Text),16,2)+copy(trim(edit1.Text),19,2)+copy(trim(edit1.Text),22,2);
//取卡号,即0104BCF625
edit1.Clear; //取完卡号,存入变量后,清除EDIT ,以便为下次接收做好准备
ET:= Copy(DateTimeToStr(now),12,5);
//取当前时间
with ADOQuery1 do //依据卡号从员工库查出员工的工号,姓名等信息
begin
Close;
SQL.Clear;
SQL.Add('select WorkNO,Name,IDCardNo,Part1,Business1 from Employe where IDCardNo='''+s+''' or IDCardNo1='''+s+'''');
Open;
end;
if MachineNo='EE' then
begin
//保存至数据库
if trim(s)<>'' then
begin
//插入到考勤主表中
ADOCommand1.CommandText:='Insert into Attenrecord (CardNO,WorkNO,Name,Part1,Business1, Enterdate, Entertime) values ('''+s+''','''+ADOQuery1.FieldByName('WorkNO').AsString+''','''+ADOQuery1.FieldByName('Name').AsString+''','''+ADOQuery1.FieldByName('Part1').AsString+''','''+ADOQuery1.FieldByName('Business1').AsString+''','''+ED+''','''+ET+''')' ;
ADOCommand1.Execute;
label9.Caption:='入井:'+Str1+#13+'时间:'+ED+' '+ET;
//显示到一个PANEL上信息
end;
end;
end;
处理流程:从我放置的EDIT判断,正常应该是第一次传上来:
AA AA EE 01 04 BC F6 25 八个字节,第二次传上来:06 06 04 08 07 FB 61 后七个字节,两次加起来长度是45,在我保存到变量后就清除了EDIT内容,然后存入数据库。
出现问题:起初运行的半个月里还比较正常,每天的刷卡数据都能实时收到库中,但在运行一个月后出现了一些问题,突然会出现有人刷不上,其实是EDIT中留下了上个人刷卡的后七个字节,既06 06 04 08 07 FB 61,那么下个人的数据再传上来的时候,我再以长度判断就会出错,往后的每个人的卡号取的都是错的,还必须重新关开一下实时程序。
我的判断:我判断是不是由于主考勤表中数据量变大(每个月3万条),是不是由于上个人的数据还未保存完,就又传上来新的刷卡数据导致,因为每次出现问题都是上个人的后七个字节留在了EDIT中。可是我是取到卡号,存入变量就清空EDIT啊,我就想不通,即使这个人的数据没存,EDIT也应该是空的啊。
请教大家:1、我以长度来取每个人的卡号这种办法是不是不够妥当?
2、是不是直接插入主考勤表很耗费时间,是不是应该有个中间表过度一下?
3、针对我以上的问题,我应该如何处理,最好给出我如何处理卡号的代码,小弟在这里谢谢大家了!我先下了,能解决问题的请留下QQ号!谢谢