关于一个还款功能的实现 |
答題得分者是:malanlk
|
ntjrr
高階會員 發表:240 回覆:312 積分:110 註冊:2005-04-24 發送簡訊給我 |
功能如下:
重要数据库字段:姓名 应收金额,实收金额。(实收金额小于应收金额就视作欠费记录)
1。输入病人姓名后按回车键显示欠款总金额(这一点估计我自己会做)
2。输入还款金额,下面有可能出现几种情况:(主要是这一步不懂做)
(1)欠费记录只有一条(也就是说病人只欠了一次费),还款金额等于欠费金额
(2)欠费记录有N条(也就是说病人欠了N次费),还款金额等于欠费金额
(3)欠费记录有N条(也就是说病人欠了N次费),还款金额不等于欠费金额,也就是说只还一部份欠款,这是最难的一点了,还款金额如何分次记录到数据中。
上面所说的一切,包括查询和还款,其实都是在收费记录库中操作中的,不另外有欠费专门所有的数据表。
------
我的编程起步于ktop,我将永远支持ktop |
ntjrr
高階會員 發表:240 回覆:312 積分:110 註冊:2005-04-24 發送簡訊給我 |
我把我的思路一步一步写出来:
下面是欠费查询功能:
ADOQUery1.Close;
ADOQUery1.SQL.Clear;
ADOQUery1.SQL.Add('select 病人id,病人姓名,病人性别,病人年龄 from tb_sf where 应找金额<0');
ADOQUery1.Open;
这上面我还有一个功能未做到,也就是要sum 应找金额 如何selcet 在病人年龄后面,想要执行的代码如下:
ADOQUery1.SQL.Add('select 病人id,病人姓名,病人性别,病人年龄 sum (应找金额) from tb_sf where 应找金额<0');
现在sum (应找金额)加在后面就要出错,即使不出错的话,那个应找金额是个负数,我要求和的结果也是正数
------
我的编程起步于ktop,我将永远支持ktop |
malanlk
尊榮會員 發表:20 回覆:694 積分:577 註冊:2004-04-19 發送簡訊給我 |
你的 "應找金額" 是欄位之ㄧ嗎? 還是你自己編出來的? 應找金額=實收金額-應收金額 'select 病人id,病人姓名,病人性別,病人年齡,sum(應收金額-實收金額) as 欠費金額 from tb_sf where 實收金額-應收金額<0' 這樣試試! 收到欠費後 採用先欠先抵的原則, 逐一扣除即可...
其中要注意的就是 "實收金額" 應視為 "上次已收金額" 收到欠費攤到的金額則是 "本次實收金額", 這樣分的主要原因是可能有好幾次都欠費... 也就是 "上次已收金額" "本次實收金額"=應收金額
|
ntjrr
高階會員 發表:240 回覆:312 積分:110 註冊:2005-04-24 發送簡訊給我 |
|
malanlk
尊榮會員 發表:20 回覆:694 積分:577 註冊:2004-04-19 發送簡訊給我 |
('select 病人id,病人姓名,病人性別,病人年齡,sum(-1*應找金額) as 欠費金額 from tb_sf where 應找金額<0 and 病人id=''' patient_id ''' group by 病人id,病人姓名,病人性別,病人年齡') 將 select 出來的資料 放入 StringGrid 內 在 輸入 還款金額(假設是 Edit1) 時, 在 Edit1 的 OnChange Event 中 做攤還的動作
payment := StrToIntDef(Edit1.Text,-1); if payment>0 then begin for i:=1 to StringGrid.RowCount-1 do begin if payment>=本項欠費金額 then begin 本項本次還款金額=本項欠費金額 end else begin 本項本次還款金額=payment end; payment := payment-本項本次還款金額; if payment=0 then break; end; end;發表人 - malanlk 於 2005/10/14 12:36:01 |
ntjrr
高階會員 發表:240 回覆:312 積分:110 註冊:2005-04-24 發送簡訊給我 |
|
malanlk
尊榮會員 發表:20 回覆:694 積分:577 註冊:2004-04-19 發送簡訊給我 |
|
ntjrr
高階會員 發表:240 回覆:312 積分:110 註冊:2005-04-24 發送簡訊給我 |
欠费查询中加上group by 已经成功了。
在还款时所指的payment,我的理解是一个变量,应该是小数点后保留两位的数据(也就是常用的金额了)按您所指就是设两个变量,
var
i:integer;
payment:(这里应设为什么?设为FLOAT好象不行)
另外在还款单元中我不用DBGRID了(在查询时用的,但在这个还款功能窗口不用)是不是我就将for i:=1 to StringGrid.RowCount-1 do
改为for i:=1 to adoquery1.RowCount-1 do
------
我的编程起步于ktop,我将永远支持ktop |
ntjrr
高階會員 發表:240 回覆:312 積分:110 註冊:2005-04-24 發送簡訊給我 |
我目前已做到的功能如下:
1。在edit1框中填入拼音码后回车选择病人,那么EDIT2框中自动能计算出该病人的累计欠款,部分代码如下:
ADOQUery1.Close;
ADOQUery1.SQL.Clear;
ADOQUery1.SQL.Add('select sum(-1*应找金额) as 欠费金额 from tb_sf where 应找金额<0 ');
ADOQUery1.SQL.Add(' and 病人id=:brid');//病人的ID编号为唯一索引
ADOQuery1.Parameters.ParamByName('brid').Value:=strtoint(label4.Caption);
ADOQUery1.Open;
edit2.Text:=ADOQuery1.Fields[0].AsString;
我下一步想要做的,就是在EDIT3中填入还款的金额,按确定键实现还款。
------
我的编程起步于ktop,我将永远支持ktop |
malanlk
尊榮會員 發表:20 回覆:694 積分:577 註冊:2004-04-19 發送簡訊給我 |
ADOQuery1.Close; ADOQuery1.SQL.Clear; ADOQuery1.SQL.Add('select count(*) as 筆數,sum(-1*應找金額) as 欠費金額 from tb_sf where 應找金額<0 and 病人id=''' patient_id ''''); ADOQuery1.Open; ... 取出數量及欠費總金額 iTotalRecord := ADOQuery1.FieldByName('筆數').AsInteger; ... 依數量設定 StringGrid 列數 StringGrid1.RowCount := iTotalRecord 1; ADOQuery1.Close; ADOQuery1.SQL.Clear; ADOQuery1.SQL.Add('select 收費日期,應收金額,(-1*應找金額) as 欠費金額 from tb_sf where 應找金額<0 and 病人id=''' patient_id ''''); ADOQuery1.Open; i:=1; while not ADOQuery1.Eof do begin StringGrid1.Cells[0,i] := ADOQuery1.FieldByName('收費日期').AsString; StringGrid1.Cells[1,i] := ADOQuery1.FieldByName('應收金額').AsString; StringGrid1.Cells[2,i] := ADOQuery1.FieldByName('欠費金額').AsString; ADOQuery1.Next; i := i 1; end;發表人 - malanlk 於 2005/10/16 01:27:43 |
ntjrr
高階會員 發表:240 回覆:312 積分:110 註冊:2005-04-24 發送簡訊給我 |
前辈,您所说的stringgrid,小弟还没有能掌握相关的知识,不过在查询欠费上我基本上已做出来,我用的是dbgrid 显示查询出的记录的。
我一共做的是两个窗口,一个窗口是欠费统计查询,其中是用DBGRID做显示的,我现在所说的是还款结算窗口,我没有放STRINGGRID,也没有放DBGRID,依小弟的理解,您上面所指点的是欠费查询及显示一块的功能。
我现在关键一点是不懂还款如何摊还,如果依前辈在第五层所指点的还款方法来看,小弟的不理解之处也就是写在第八层中,一个是那个变量的数据类型,一个是我不用DBGRID也不用STRINGGRID时如何做?谢谢!
------
我的编程起步于ktop,我将永远支持ktop |
ntjrr
高階會員 發表:240 回覆:312 積分:110 註冊:2005-04-24 發送簡訊給我 |
|
malanlk
尊榮會員 發表:20 回覆:694 積分:577 註冊:2004-04-19 發送簡訊給我 |
vPayment: Double;
vItemPay, vPay: Double;
sItemNo: String;
bComplete: Boolean; 輸入還款金額後按 "確定" 照你的要求直接用 query 逐筆攤掉....
vPayment := StrToFloat(Edit1.Text);
...
ADOQuery1.Close; repeat ADOQuery1.SQL.Clear; ADOQuery1.SQL.Add('select top 1 收費編號,(-1*應找金額) as 欠費金額 from tb_sf where 應找金額<0 and 病人id=''' patient_id ''' order by 收費編號'); ADOQuery1.Open; if not ADOQuery1.Eof do begin vItemPay := ADOQuery1.FieldByName('欠費金額').AsFloat; sItemNo := ADOQuery1.FieldByName('收費編號').AsString; ADOQuery1.Close; ADOQuery1.SQL.Clear; if (vItemPay>vPayment) then vPay := vPayment-vItemPay; else vPay := 0; ADOQuery1.SQL.Add('update tb_sf set 應找金額=:vPay where 收費編號=:sItemNo'); ADOQuery1.Parameters.ParamByName('vPay').Value:= vPay; ADOQuery1.Parameters.ParamByName('sItemNo').Value:= sItemNo; ADOQuery1.ExecSQL; if (vItemPay>vPayment) then vPayment := 0 else vPayment := vPayment-vItemPay; end else begin bComplete := True; end; until (bComplete or (vPayment<=0)); |
ntjrr
高階會員 發表:240 回覆:312 積分:110 註冊:2005-04-24 發送簡訊給我 |
小弟将您的代码根据我的实际情况修改了一下:
var vPayment: Double; vItemPay, vPay: Double; sItemNo: String; bComplete: Boolean; begin if StrToFloat(Edit3.Text)> StrToFloat(Edit2.Text) then showmessage('还款金额不能大于欠费金额!') else begin vPayment := StrToFloat(Edit3.Text); ADOQuery1.Close; repeat ADOQuery1.SQL.Clear; ADOQuery1.SQL.Add('select top 1 票据号,(-1*应找金额) as 欠费金额 from tb_sf where 应找金额<0'); ADOQUery1.SQL.Add(' and 病人id=:brid'); ADOQUery1.SQL.Add(' order by 票据号'); ADOQuery1.Parameters.ParamByName('brid').Value:=strtoint(label4.Caption); ADOQuery1.Open; if not ADOQuery1.Eof then begin vItemPay := ADOQuery1.FieldByName('欠费金额').AsFloat; sItemNo := ADOQuery1.FieldByName('票据号').AsString; ADOQuery1.Close; ADOQuery1.SQL.Clear; if (vItemPay>vPayment) then vPay := vPayment-vItemPay else vPay := 0; ADOQuery1.SQL.Add('update tb_sf set 应找金额=:vPay,where 票据号=:sItemNo'); ADOQuery1.Parameters.ParamByName('vPay').Value:= vPay; ADOQuery1.Parameters.ParamByName('sItemNo').Value:= sItemNo; ADOQuery1.ExecSQL; if (vItemPay>vPayment) then vPayment := 0 else vPayment := vPayment-vItemPay; end else begin bComplete := True; end; until (bComplete or (vPayment<=0)); 目前测试了一下,所有代码能正常执行,因为这个问题虽然小,但比较复杂,所以我就分次提问如下了: 1。 bComplete 可能一次也执行不到 2。实收金额仍是为0,我想的要是实收金额也要填上 如果本来应收为100 实收为0,那么还款100后,实收也为100,如果还款90,那么实收就为90。 3.如果该病人欠费记录有N笔,那么还款时即使有足够的钱,但还是只会还掉第一笔欠费,其它欠费还不掉。 先处理好这一个,我再测试一下在数种还款可能的情况下的代码执行情况。發表人 - ntjrr 於 2005/10/16 19:55:14 發表人 - ntjrr 於 2005/10/16 22:13:51
------
我的编程起步于ktop,我将永远支持ktop |
malanlk
尊榮會員 發表:20 回覆:694 積分:577 註冊:2004-04-19 發送簡訊給我 |
如果不小心 輸入金額太多, Payment 就不會<=0 這個 repeat 就永遠停不了...
vPayment: Double; vItemPay, vPay, vItemPaid: Double; sItemNo: String; bComplete: Boolean; 輸入還款金額後按 "確定" 照你的要求直接用 query 逐筆攤掉.... vPayment := StrToFloat(Edit1.Text); ... ADOQuery1.Close; repeat ADOQuery1.SQL.Clear; ADOQuery1.SQL.Add('select top 1 收費編號,實收金額,(-1*應找金額) as 欠費金額 from tb_sf where 應找金額<0 and 病人id=''' patient_id ''' order by 收費編號'); ADOQuery1.Open; if not ADOQuery1.Eof do begin vItemPay := ADOQuery1.FieldByName('欠費金額').AsFloat; vItemPaid := ADOQuery1.FieldByName('實收金額').AsFloat; sItemNo := ADOQuery1.FieldByName('收費編號').AsString; ADOQuery1.Close; ADOQuery1.SQL.Clear; if (vItemPay>vPayment) then begin vPay := vPayment-vItemPay; vItemPaid := vItemPaid vPayment; end else begin vItemPaid := vItemPaid vItemPay; vPay := 0; end; ADOQuery1.SQL.Add('update tb_sf set 實收金額=:vItemPaid,應找金額=:vPay where 收費編號=:sItemNo'); ADOQuery1.Parameters.ParamByName('vPay').Value:= vPay; ADOQuery1.Parameters.ParamByName('vItemPaid').Value:= vItemPaid; ADOQuery1.Parameters.ParamByName('sItemNo').Value:= sItemNo; ADOQuery1.ExecSQL; if (vItemPay>vPayment) then vPayment := 0 else vPayment := vPayment-vItemPay; end else begin bComplete := True; end; until (bComplete or (vPayment<=0)); |
ntjrr
高階會員 發表:240 回覆:312 積分:110 註冊:2005-04-24 發送簡訊給我 |
|
ntjrr
高階會員 發表:240 回覆:312 積分:110 註冊:2005-04-24 發送簡訊給我 |
|
malanlk
尊榮會員 發表:20 回覆:694 積分:577 註冊:2004-04-19 發送簡訊給我 |
|
ntjrr
高階會員 發表:240 回覆:312 積分:110 註冊:2005-04-24 發送簡訊給我 |
|
malanlk
尊榮會員 發表:20 回覆:694 積分:577 註冊:2004-04-19 發送簡訊給我 |
|
ntjrr
高階會員 發表:240 回覆:312 積分:110 註冊:2005-04-24 發送簡訊給我 |
前辈,我根据您的指教,结合我的程序的实际情况,最终的代码如下:
现在经过初步的测试尚未测出什么问题,我还得仔细测,麻烦前辈先过目一下,我修改后的代码有无不妥之处,谢谢!
var vPayment: Double; vItemPay,vItempaid, vPay: Double; sItemNo: String; bComplete: Boolean; begin if edit3.Text='' then showmessage('还款金额不能为空白!') else if StrToFloat(Edit3.Text)> StrToFloat(Edit2.Text) then showmessage('还款金额不能大于欠费金额!') else begin vPayment := StrToFloat(Edit3.Text); ADOQuery1.Close; bComplete:=false; try repeat ADOQuery1.SQL.Clear; ADOQuery1.SQL.Add('select top 1 票据号,实收金额,(-1*应找金额) as 欠费金额 from tb_sf where 应找金额<0'); ADOQUery1.SQL.Add(' and 病人id=:brid'); ADOQUery1.SQL.Add(' order by 票据号'); ADOQuery1.Parameters.ParamByName('brid').Value:=strtoint(label4.Caption); ADOQuery1.Open; if not ADOQuery1.Eof then begin vItemPay := ADOQuery1.FieldByName('欠费金额').AsFloat; vItemPaid := ADOQuery1.FieldByName('实收金额').AsFloat; sItemNo := ADOQuery1.FieldByName('票据号').AsString; ADOQuery1.Close; ADOQuery1.SQL.Clear; if (vItemPay>vPayment) then begin vPay := strtofloat(format('%.2f',[vPayment-vItemPay])); vItemPaid := vItemPaid vPayment; end else begin vItemPaid := vItemPaid vItemPay; vPay := 0; end; ADOQuery1.SQL.Add('update tb_sf set 实收金额=:vItemPaid,应找金额=:vPay where 票据号=:sItemNo'); ADOQUery1.SQL.Add(' and 应收金额>0'); ADOQuery1.Parameters.ParamByName('vPay').Value:= vPay; ADOQuery1.Parameters.ParamByName('vItemPaid').Value:= vItemPaid; ADOQuery1.Parameters.ParamByName('sItemNo').Value:= sItemNo; ADOQuery1.ExecSQL; if (vItemPay>vPayment) then vPayment := 0 else vPayment := vPayment-vItemPay; end else begin bComplete := True; end; until (bComplete or (vPayment<=0)); showmessage('还款成功'); edit1.Text:=''; edit2.Text:=''; edit3.Text:=''; label4.Caption:=''; edit1.SetFocus; except showmessage('还款未成功'); end; end; end;
------
我的编程起步于ktop,我将永远支持ktop |
malanlk
尊榮會員 發表:20 回覆:694 積分:577 註冊:2004-04-19 發送簡訊給我 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |