分數不是問題(若有人寫得好用的,或者修正好確實正確無誤的,本人加分);報表自定義表達式,驗證表達式的正確性,請各位help me提意見,並且可
//驗證表達式的正確性,做會計自定報表時用的;
//寫得太急,沒有仔細測試,真想重寫;
//請各位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;