急!!!井下刷卡考勤的问题,兄弟跪求解决办法,送300分(300分)

  • 主题发起人 主题发起人 雨季飘零
  • 开始时间 开始时间

雨季飘零

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号!谢谢
 
请问你的考勤机是什么型号的?
 
读考勤数据采用多线程。处理完一个发消息处理第二个。
 
你只取卡号不就行了嘛,年月日,时分秒以服务器的为准。也就是保存时间。
理论上传输的数据越少越好处理
 
年,月,日,时分就是取的服务器时间,考勤机和什么型号无关,主要看我收的数据格式,考勤机传上来的格式就是那样,只能按规则处理,哪位有做过的经验,最好给一段代码
 
网中戏,具体说说你的实现方法,处理完一个怎么发消息处理下一个?
 
你还不如设置一个字符串变量,每次都加到最后,一旦有符合条件的就截取,在某个时间段内没有变化就清空岂不是好
 
怎么判断某个时间段有没有变化?
 
对,我忘了一点,每取到一个卡号,是要向LED上显示一下的,所以必须一个一个的取
 
如果是处理不及时的原因,那么直接把取来的数据保存起来,以后再处理了
 
我的要求是怎么快速准确的取到数据,然后再保存到数据库,在保存到数据库这个过程中可能比较耗费时间,在保存的过程中又有人刷卡,这时候如何处理传上来的数据?能解决的请留下QQ或其他联系方式
 
如果格式固定的话,你可以用不同的模块来完成所需的工作,其中一个模块只负责接收数据,另一个模块验证数据,再弄一模块读写数据库
 
接收到的马上就要显示到LED上,并且保存,要实时刷新当前刷卡人数,分模块也不大行的
 
关于考勤存数据库的你的方法可以要改动一下,把采集分为两步,1,采集写文本,2,文本写数据库,我以前给一家做考勤的公司解决过类似的问题,QQ381014885,
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
928
SUNSTONE的Delphi笔记
S
I
回复
0
查看
680
import
I
后退
顶部