在界面上放置2个ListBox——ListBoxItems和ListBoxItemFields,前者用于存放项目名称,后者用于存放与之相对应的字段
放置两个Memo——MemoFormula和MemoCondition,前者用于存放公式,后者用于存放限制条件
const ErrorStr = 'Unvalid String'; //用于表示非法
//***********获取用字段表示的考勤公式(限制条件)*************//
function Tfrmwage_attendence_formula.GetFieldsStr(FormulaStr: String): String;
var
ItemArray, FieldArray: array[1..MaxSize] of String; //表示字段的数组
i, j: integer;
Str: String;
begin
Str:= FormulaStr; //将FormulaStr赋给Str,备用
if(FormulaStr <> '') then
begin
if(JudgeFormula(FormulaStr) = false) then //公式不合法
begin
result:= ErrorStr;
Exit;
end;
SeperateStrToArray(formulaStr, ItemArray); //以符号为界,分离字符串到数组
//根据项目查找字段名, 并将字段名保存在FieldArray中;找不到字段则退出
if(GetFieldArray(ItemArray, FieldArray) = false) then
begin
Result:= ErrorStr;
Exit;
end;
//得到用字段表示的公式(限制条件)
i:= 1;
j:= 1;
while not(ItemArray[i] = '') do
begin
if not(IsNum(ItemArray[i])) then
begin
//在字符串Str中,用字段名替换项目名称
Str:= AnsiReplaceText(Str, ItemArray[i], FieldArray[j]);
j:= j + 1;
end;
i:= i + 1;
end;
result:= Str;
end //if
else
result:= '';
end;
/
//***************判断最终的公式是否合法*****************//
function Tfrmwage_attendence_formula.JudgeFormula(FormulaStr: String): boolean;
var
i, position: integer;
begin
//如果左括号不是第一个字符,并且它前面没有符号,不合法
position:= pos('(', FormulaStr);
if (AnsiContainsText(FormulaStr, '(') = true) and not(position = 1)
and not(FormulaStr[position - 1] in ['+', '-', '*', '/', '(', 'd', 'r', '>', '<']) then
begin
result:= false;
Exit;
end;
//如果右括号不是最后一个字符,并且它后面没有符号,不合法
position:= pos(')', FormulaStr);
if (AnsiContainsText(FormulaStr, ')') = true) and not(position = Length(FormulaStr))
and not(FormulaStr[position + 1] in ['+', '-', '*', '/', ')', 'a', 'o', '>', '<']) then
begin
result:= false;
Exit;
end;
//以这些符号结尾,不合法
if(FormulaStr[Length(FormulaStr)] in ['+', '-', '*', '/', '(', 'd', 'r', '>', '<'])
//左括号数不等于右括号数,不合法
or(GetCharCount(FormulaStr, '(') <> GetCharCount(FormulaStr, ')')) then
begin
result:= false;
Exit;
end; //if
for i:= 2 to Length(FormulaStr) do //连续出现2个以上运算符
begin
if(FormulaStr[i] in ['+', '-', '*', '/', '>', '<'])
and (FormulaStr[i - 1] in ['+', '-', '*', '/', '>', '<']) then
begin
result:= false;
Exit;
end;
end; //for
result:= true;
end;
/
//*****************以符号为界,分离字符串到数组****************//
procedure Tfrmwage_attendence_formula.SeperateStrToArray(formulaStr: String; var ItemArray: array of String); var
i, j: integer;
begin
j:= 0;
while not(FormulaStr = '') do
begin
i:= 1;
//在碰到符号之前递增
while not(FormulaStr[i] in ['+', '-', '*', '/', '(', 'a', 'o', '>', '<', ')']) do
begin
i:= i + 1;
if (i = Length(FormulaStr)) then //如果已经到达了FormulaStr的末尾
break;
end; //while
//碰到符号时,将符号前面的字符串拷到FieldArray数组
if (not(i = Length(FormulaStr))) and (not(i = 1))
or((i = Length(FormulaStr)) and (FormulaStr[i] = ')')) then
begin
ItemArray[j]:= Copy(FormulaStr, 1, i - 1);
j:= j + 1;
end
else if(i = Length(FormulaStr)) then
begin
ItemArray[j]:= Copy(FormulaStr, 1, i);
j:= j + 1;
end;
//截取ForMulaStr的后半部分,以便继续判断
if(FormulaStr[i] = 'a') then //and
FormulaStr:= Copy(FormulaStr, i + 3, Length(FormulaStr))
else if(FormulaStr[i] = 'o') then //or
FormulaStr:= Copy(FormulaStr, i + 2, Length(FormulaStr))
else
FormulaStr:= Copy(FormulaStr, i + 1, Length(FormulaStr));
end; //while not(FormulaStr = '')
end;
//
//*************根据项目名称数组得到字段名数组***************//
function Tfrmwage_attendence_formula.GetFieldArray(ItemArray: Array of String; var FieldArray: Array of String): boolean;
var
i, j: integer;
begin
i:= 0;
j:= 0;
while not(ItemArray[i] = '') do
begin
//不是数字项,并且没有找到字段,说明不合法
if not(IsNum(ItemArray[i])) and (GetFields(ItemArray[i]) = ErrorStr) then
begin
result:= false;
exit;
end //if
else if not (IsNum(ItemArray[i])) then //不是数字项
begin
FieldArray[j]:= GetFields(ItemArray[i]);
j:= j + 1;
end;
i:= i + 1;
end; //while
result:= true;
end;
//
//************判断字符串是否为数字************//
function Tfrmwage_attendence_formula.IsNum(str:string):boolean;
var
i:integer;
begin
for i:=1 to length(str) do
if not (str[i] in ['0'..'9']) then
begin
result:=false;
exit;
end;
result:=true;
end;
//****************获取Str字符串中字符Chr的数目*******************//
function Tfrmwage_attendence_formula.GetCharCount(Str: String; Chr: char): integer;
var
i, CharCount: integer;
begin
CharCount:= 0;
i:= 1;
while (i <= Length(Str)) do
begin
if(Str[i] = Chr) then
CharCount:= CharCount + 1;
i:= i + 1;
end; //while
result:= CharCount;
end;
//
//*************根据项目名称取得字段名*****************//
function Tfrmwage_attendence_formula.GetFields(ItemStr: String): String; //根据项目名称取得字段名
var
i: integer;
begin
i:= 0;
while(i < ListBoxItems.Items.Count)do //ListBoxItems:用于存放项目
begin
if(ItemStr = ListBoxItems.Items[i]) then
begin
result:= ListBoxItemFields.Items[i]; //ListBoxFields:用于存放字段
result:= 'Isnull( ' + result + ', 0)';
Exit;
end; //if
i:= i + 1;
end; //while
result:= ErrorStr;
end;
///