分數不是問題(若有人寫得好用的,或者修正好確實正確無誤的,本人加分);報表自定義表達式,驗證表達式的正確性,請各位help me提意見,並且可

foreveryday007 2002-08-12 05:25:28
//驗證表達式的正確性,做會計自定報表時用的;
//寫得太急,沒有仔細測試,真想重寫;
//請各位help me提意見,並且可修正這里的bug;
//或者重新寫都可以;因為要急用,謝謝各位!
//其中:

//CheckNumber(strParam1: string): boolean;
// 判斷字符串strParam1是否數字型字符串(包含小數點'.'),
// 返回邏輯結果True,False

{sValue: 報表自定義表達式;
數字符:0,1,2,3,4,5,6,7,8,9,.
運算符:+,-,*,/
優先符:(,)
標誌符:[,]
(,)要匹配;[,]要匹配;其中:[,]之間的字符串是相應的科目代號(會計)
eg:
sValue = ([1001]+[1002])*10 //OK
sValue = ([1001]+[1002])()*10 //不可邊用('(')
}

//驗證sValue的合法性(前後空格會去掉);返回錯誤碼,為空表sValue合法
function TForm1.funGetErrMsg(sValue: string):string;
var
sTmp,sOther: string; //sOther:存放數字型的字符
i,j,iOper: integer; //iOper初始為0,有左括號時加1,在右括號時減1
bOper1,bOper2,bNum: Boolean;//bOper1,是否可以輸入操作符;
//bOper2,是否可以輸入運算符;+,-,*,/,...
//bNum,是否可以輸入數字型字符;
begin
Result := '';
sValue := Trim(sValue);

sOther := '';
bOper1 := True; bOper2 := True; bNum := True;
iOper := 0;
i := 1;

while (i <= length(sValue)) do
begin
case sValue[i] of
' ' : //空格時;前方是否有數字型,若有要檢驗;
//並且設置操作符不能輸入,運算符能輸入;數字型字符不能輸入
begin
if (sOther <> '') and (not CheckNumber(sOther)) then
begin
Result := '01';//'數字型不對'
Exit;
end;

inc(i);

sOther := '';
bOper1 := False; bOper2 := True; bNum := False;
end;
'[' : //'['時;先驗證能否輸入操作符;若能,找到匹配的']'為止;
//並且設置操作符不能輸入,運算符能輸入;數字型字符不能輸入
begin
if not bOper1 then
begin
Result := '02'; //操作符不可邊用
Exit;
end;

j := i+1;
sTmp := '';
while ( (sValue[j]<>']') and (j<=length(sValue)) ) do
begin
sTmp := sTmp +sValue[j];
j := j+1;
end;

if j > length(sValue) then Result := '09';//沒有匹配的']'
i := j+1;
bOper1 := False; bOper2 := True; bNum := False;
end;
'+','-','*','/': //前方是否有數字型,若有要檢驗;
//是否可輸入運算符
//並且設置操作符能輸入,運算符不能輸入,數字型字符能輸入
begin
if (sOther <> '') and (not CheckNumber(sOther)) then
begin
Result := '01';//'數字型不對'
Exit;
end;

if not bOper2 then
begin
Result := '03'; //運算符不可邊用
Exit;
end;

inc(i);

sOther := '';
bOper1 := True; bOper2 := False; bNum := True;
end;
'(':
begin //是否可輸入('('),iOper加1
//並且設置操作符能輸入,運算符不能輸入,數字型字符能輸入
if not bOper1 then
begin
Result := '04'; //不可邊用('(')
Exit;
end;

inc(i);
inc(iOper);

bOper1 := True; bOper2 := False; bNum := True;
end;
')':
begin //前方是否有數字型,若有要檢驗;
//是否可輸入('('),iOper加1
//並且設置操作符不能輸入,運算符能輸入,數字型字符不能輸入
if (sOther <> '') and (not CheckNumber(sOther)) then
begin
Result := '01';//'數字型不對'
Exit;
end;

if not bOper2 then
begin
Result := '05'; //不可邊用(')')
Exit;
end;

inc(i);
Dec(iOper);
bOper1 := False; bOper2 := True; bNum := False;
end;
else
begin //合併數字型字符串,並設置操作符不能輸入,運算符能輸入,
if not bNum then
begin
Result := '08';//不可用數字型字符串
Exit;
end;
sOther := sOther + sValue[i];
inc(i);
bOper1 := False; bOper2 := True;
end;
end;
end;

//Result := '09';//沒有匹配的']'
if Result <> '' then Exit;

if (sOther <> '') and (not CheckNumber(sOther)) then
begin
Result := '01';//'數字型不對'
Exit;
end;

if iOper <> 0 then begin Result := '05'; Exit; end;

if (sValue[length(sValue)] = '+') or (sValue[length(sValue)] = '-') or
(sValue[length(sValue)] = '*') or (sValue[length(sValue)] = '/') then
Result := '07';//最後一位不可用運算符
end;

function TForm1.CheckNumber(strParam1: string): boolean;
// 判斷字符串str1是否數字型字符串(包含小數點'.)
// 返回邏輯結果True,False
var
i, j : integer;
begin
checknumber := True;
J := 0;
for i := 1 to length(strParam1) do
begin
case strParam1[i] of
'0'..'9':;
'.': inc(J);
else begin checknumber := False; Exit; end;
end;
end;
if J>1 then checknumber := False;
end;
...全文
16 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
foreveryday007 2002-08-14
  • 打赏
  • 举报
回复
//驗證sValue的合法性(前後空格會去掉);返回錯誤碼,為空表sValue合法
function TForm1.sFunGetErrMsg(sValue: string):string;
var
sTmp: string;
begin
sValue := Trim(sValue);
Result := '';
if sValue = '' then Exit;

case sValue[1] of
'[' :
begin
sTmp := sFunGetErrMsg1(sValue,1);
if sTmp <> '' then begin Result := sTmp; Exit; end;
end;
'(' :
begin
sTmp := sFunGetErrMsg2(sValue,1);
if sTmp <> '' then begin Result := sTmp; Exit; end;
end;
'0','1','2','3','4','5','6','7','8','9':
begin
sTmp := sFunGetErrMsg3(sValue,1);
if sTmp <> '' then begin Result := sTmp; Exit; end;
end;
else
begin //不合法字符
Result := 'Not valid Char'; Exit;
end;
end;
end;
foreveryday007 2002-08-14
  • 打赏
  • 举报
回复
上次寫得比較亂,今天有空就修改了一下:各位幫忙測試,有問題貼出來
eg:
Edit1 -> Not valid Char
9*(9327) -> OK
9*(989*80824-) -> Last is operation
9*(989*80824-[1001]) -> OK
9*([989*80824-[1001]) -> OK
(9*([989*80824-[1001])-> Not Match (>)
.........以上測試數據是正確的
foreveryday007 2002-08-13
  • 打赏
  • 举报
回复
THANKS,今天上午再來修改
dejoy 2002-08-12
  • 打赏
  • 举报
回复
我建议把相关功能模块做成函数或过程,不然程序可读性很差。

5,388

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧