📄 dbutilseh.pas
字号:
Operator := foValue;
end
else
begin
case S[Pos] of
'!':
if CharAtPos(S, Pos + 1) = '=' then
SetOperatorPos(Pos, 2, Oper, opNotEqual)
else
SetOperatorPos(Pos, 1, Oper, opNot);
'=':
SetOperatorPos(Pos, 1, Oper, opEqual);
'(':
SetOperatorPos(Pos, 1, Oper, opOpenBracket);
'>':
if CharAtPos(S, Pos + 1) = '=' then
SetOperatorPos(Pos, 2, Oper, opGreaterOrEqual)
else
SetOperatorPos(Pos, 1, Oper, opGreaterThan);
'<':
if CharAtPos(S, Pos + 1) = '=' then
SetOperatorPos(Pos, 2, Oper, opLessOrEqual)
else if CharAtPos(S, Pos + 1) = '>' then
SetOperatorPos(Pos, 2, Oper, opNotEqual)
else
SetOperatorPos(Pos, 1, Oper, opLessThan);
'~':
SetOperatorPos(Pos, 1, Oper, opLike);
'&':
SetOperatorPos(Pos, 1, Oper, opAnd); //And
'|':
SetOperatorPos(Pos, 1, Oper, opOr); // Or
else
TheWord := ReadWord(S,Pos);
Oper := GetOperatorByWord(TheWord);
if Oper <> opNon then
Inc(Pos, Length(TheWord));
end; //case
if Oper = opNon then
begin
Result := ReadValues(S, Pos, PreferCommaForList);
if VarIsNull(Result) then
Operator := foNon
else
Operator := foValue;
Exit;
end;
Pos := SkipBlanks(S, Pos);
if Oper = opNot then
begin
GetLexeme(S, Pos, Operator1, PreferCommaForList);
case Operator1 of
foLike: Operator := foNotLike;
foIn: Operator := foNotIn;
foNull: Operator := foNotNull;
end
end
else if Oper = opIn then
begin
if CharAtPos(S, Pos) = '(' then
Inc(Pos)
else
raise Exception.Create(SLeftBracketExpectedEh + S);
Operator := foIn;
end
else
Operator := OperatorAdvFilterOperatorMap[Oper];
end;
end;
function ParseSTFilterExpression(Exp: String; var FExpression: TSTFilterExpressionEh): Boolean;
var
PreferCommaForList: Boolean;
procedure ResetPreferCommaForList;
begin
if (FExpression.ExpressionType = botNumber) and (DecimalSeparator = ',') then
PreferCommaForList := False
else
PreferCommaForList := True;
end;
var
v: Variant;
op, op1: TSTFilterOperatorEh;
p: Integer;
begin
Result := False;
ResetPreferCommaForList;
FExpression.Operator1 := foNon;
FExpression.Operand1 := Null;
FExpression.Relation := foNon;
FExpression.Operator2 := foNon;
FExpression.Operand2 := Null;
Exp := Trim(Exp);
if Exp = '' then
Exit;
// 1 [Oper] + Values
p := SkipBlanks(Exp, 1);
v := GetLexeme(Exp, p, op, PreferCommaForList);
if op = foValue then
begin
if VarIsArray(v) then
FExpression.Operator1 := foIn
else if FExpression.ExpressionType = botString then
FExpression.Operator1 := foLike
else
FExpression.Operator1 := foEqual;
FExpression.Operand1 := v;
end
else if (op = foNon) and (Length(Exp) <> 0) then
raise Exception.Create(SErrorInExpressionEh + Exp)
else
begin
if op in [foIn, foNotIn] then
PreferCommaForList := True;
p := SkipBlanks(Exp, p);
v := GetLexeme(Exp, p, op1, PreferCommaForList);
FExpression.Operator1 := op;
if op1 = foNull then
if op = foEqual then
FExpression.Operator1 := foNull
else if op = foNotEqual then
FExpression.Operator1 := foNotNull
else
raise Exception.Create(SUnexpectedExpressionBeforeNullEh + Exp)
else if op1 <> foValue then
raise Exception.Create(SUnexpectedExpressionAfterOperatorEh + Exp);
FExpression.Operand1 := v;
if op in [foIn, foNotIn] then
begin
p := SkipBlanks(Exp, p);
if CharAtPos(Exp, p) = ')' then
Inc(p)
else
raise Exception.Create(SRightBracketExpectedEh + Exp);
ResetPreferCommaForList;
end;
end;
while True do
begin
// 2 And or Or
p := SkipBlanks(Exp, p);
v := GetLexeme(Exp, p, op, PreferCommaForList);
if op = foNon then
if p <> Length(Exp) + 1 then
raise Exception.Create(SIncorrectExpressionEh + Exp)
else
Break;
if not (op in [foAND, foOR]) then
raise Exception.Create(SUnexpectedANDorOREh + Exp);
FExpression.Relation := op;
// 3 [Oper] + Values
p := SkipBlanks(Exp, p);
v := GetLexeme(Exp, p, op, PreferCommaForList);
if op = foNon then
if p <> Length(Exp) + 1 then
raise Exception.Create(SIncorrectExpressionEh + Exp)
else
Break;
if op = foValue then
begin
if VarIsArray(v) then
FExpression.Operator2 := foIn
else if FExpression.ExpressionType = botString then
FExpression.Operator2 := foLike
else
FExpression.Operator2 := foEqual;
FExpression.Operand2 := v;
end
else if (op = foNon) and (Length(Exp) <> 0) then
raise Exception.Create(SErrorInExpressionEh + Exp)
else
begin
if op in [foIn, foNotIn] then
PreferCommaForList := True;
p := SkipBlanks(Exp, p);
v := GetLexeme(Exp, p, op1, PreferCommaForList);
FExpression.Operator2 := op;
if op1 = foNull then
if op = foEqual then
FExpression.Operator2 := foNull
else if op = foNotEqual then
FExpression.Operator2 := foNotNull
else
raise Exception.Create(SUnexpectedExpressionBeforeNullEh + Exp)
else if op1 <> foValue then
raise Exception.Create(SUnexpectedExpressionAfterOperatorEh + Exp);
FExpression.Operand2 := v;
ResetPreferCommaForList;
end;
Result := True;
Break;
end;
if FExpression.Operator1 in [foEqual..foNotIn] then
ConvertVarStrValues(FExpression.Operand1, FExpression.ExpressionType)
else
FExpression.Operand1 := Null;
if FExpression.Operator2 in [foEqual..foNotIn] then
ConvertVarStrValues(FExpression.Operand2, FExpression.ExpressionType)
else
FExpression.Operand2 := Null;
end;
function ParseSTFilterExpressionEh(Exp: String; var FExpression: TSTFilterExpressionEh): Boolean;
var
PreferCommaForList: Boolean;
procedure ResetPreferCommaForList;
begin
if (FExpression.ExpressionType = botNumber) and (DecimalSeparator = ',') then
PreferCommaForList := False
else
PreferCommaForList := True;
end;
var
v: Variant;
op, op1: TSTFilterOperatorEh;
p: Integer;
begin
Result := False;
ResetPreferCommaForList;
FExpression.Operator1 := foNon;
FExpression.Operand1 := Null;
FExpression.Relation := foNon;
FExpression.Operator2 := foNon;
FExpression.Operand2 := Null;
Exp := Trim(Exp);
if Exp = '' then
Exit;
// 1 [Oper] + Values
p := SkipBlanks(Exp, 1);
v := GetLexeme(Exp, p, op, PreferCommaForList);
if op = foValue then
begin
if VarIsArray(v) then
FExpression.Operator1 := foIn
else if FExpression.ExpressionType = botString then
FExpression.Operator1 := foLike
else
FExpression.Operator1 := foEqual;
FExpression.Operand1 := v;
end
else if (op = foNon) and (Length(Exp) <> 0) then
raise Exception.Create(SErrorInExpressionEh + Exp)
else
begin
if op in [foIn, foNotIn] then
PreferCommaForList := True;
p := SkipBlanks(Exp, p);
v := GetLexeme(Exp, p, op1, PreferCommaForList);
FExpression.Operator1 := op;
if op1 = foNull then
if op = foEqual then
FExpression.Operator1 := foNull
else if op = foNotEqual then
FExpression.Operator1 := foNotNull
else
raise Exception.Create(SUnexpectedExpressionBeforeNullEh + Exp)
else if op1 <> foValue then
raise Exception.Create(SUnexpectedExpressionAfterOperatorEh + Exp);
FExpression.Operand1 := v;
if op in [foIn, foNotIn] then
begin
p := SkipBlanks(Exp, p);
if CharAtPos(Exp, p) = ')' then
Inc(p)
else
raise Exception.Create(SRightBracketExpectedEh + Exp);
ResetPreferCommaForList;
end;
end;
while True do
begin
// 2 And or Or
p := SkipBlanks(Exp, p);
v := GetLexeme(Exp, p, op, PreferCommaForList);
if op = foNon then
if p <> Length(Exp) + 1 then
raise Exception.Create(SIncorrectExpressionEh + Exp)
else
Break;
if not (op in [foAND, foOR]) then
raise Exception.Create(SUnexpectedANDorOREh + Exp);
FExpression.Relation := op;
// 3 [Oper] + Values
p := SkipBlanks(Exp, p);
v := GetLexeme(Exp, p, op, PreferCommaForList);
if op = foNon then
if p <> Length(Exp) + 1 then
raise Exception.Create(SIncorrectExpressionEh + Exp)
else
Break;
if op = foValue then
begin
if VarIsArray(v) then
FExpression.Operator2 := foIn
else if FExpression.ExpressionType = botString then
FExpression.Operator2 := foLike
else
FExpression.Operator2 := foEqual;
FExpression.Operand2 := v;
end
else if (op = foNon) and (Length(Exp) <> 0) then
raise Exception.Create(SErrorInExpressionEh + Exp)
else
begin
if op in [foIn, foNotIn] then
PreferCommaForList := True;
p := SkipBlanks(Exp, p);
v := GetLexeme(Exp, p, op1, PreferCommaForList);
FExpression.Operator2 := op;
if op1 = foNull then
if op = foEqual then
FExpression.Operator2 := foNull
else if op = foNotEqual then
FExpression.Operator2 := foNotNull
else
raise Exception.Create(SUnexpectedExpressionBeforeNullEh + Exp)
else if op1 <> foValue then
raise Exception.Create(SUnexpectedExpressionAfterOperatorEh + Exp);
FExpression.Operand2 := v;
ResetPreferCommaForList;
end;
Result := True;
Break;
end;
if FExpression.Operator1 in [foEqual..foNotIn] then
ConvertVarStrValues(FExpression.Operand1, FExpression.ExpressionType)
else
FExpression.Operand1 := Null;
if FExpression.Operator2 in [foEqual..foNotIn] then
ConvertVarStrValues(FExpression.Operand2, FExpression.ExpressionType)
else
FExpression.Operand2 := Null;
end;
function GetExpressionAsFilterString(AGrid: TCustomDBGridEh;
OneExpressionProc: TOneExpressionFilterStringProcEh;
DateValueToSQLStringProc: TDateValueToSQLStringProcEh;
UseFieldOrigin: Boolean = False;
SupportsLocalLike: Boolean = False): String;
function GetExpressionAsString(Column: TColumnEh): String;
var
FieldName: String;
begin
if Column.Field = nil then
FieldName := ''
else if UseFieldOrigin and (Column.Field.Origin <> '') and (Column.STFilter.DataField = '') then
FieldName := Column.Field.Origin
// else if (Column.STFilter.ListSource <> nil) or (Column.Filter.DataField <> '') then
// FieldName := Column.Filter.DataField
else
// FieldName := Column. Field.FieldName;
FieldName := Column.STFilter.GetFilterFieldName;
Result := '';
with Column.STFilter do
begin
if (Expression.ExpressionType = botNon) or (Column.Field = nil) or (Expression.Operator1 = foNon) then
Exit;
// if KeyField <> '' then
// Result := OneExpressionProc(Expression.Operator1, FKeyValues, FieldName, AGrid.DataSource.DataSet, DateValueToSQLStringProc)
// else
begin
Result := OneExpressionProc(Expression.Operator1, GetOperand1, FieldName,
AGrid.DataSource.DataSet, DateValueToSQLStringProc, SupportsLocalLike);
if Expression.Relation <> foNon then
begin
Result := Result + ' ' + STFilterOperatorsSQLStrMapEh[Expression.Relation];
Result := Result + OneExpressionProc(Expression.Operator2, GetOperand2,
FieldName, AGrid.DataSource.DataSet, DateValueToSQLStringProc, SupportsLocalLike);
end
end;
if Expression.Relation = foOR then
Result := '(' + Result + ')';
end;
end;
var
i: Integer;
s: String;
begin
Result := '';
if (AGrid.DataSource <> nil) and (AGrid.DataSource.DataSet <> nil) and
AGrid.DataSource.DataSet.Active then
begin
for i := 0 to AGrid.Columns.Count - 1 do
begin
s := GetExpressionAsString(TColumnEh(AGrid.Columns[i]));
if s <> '' then
Result := Result + s + ' AND ';
end;
Delete(Result, Length(Result) - 3, 4);
end;
end;
function GetOneExpressionAsLocalFilterString(O: TSTFilterOperatorEh; v: Variant;
FieldName: String; DataSet: TDataSet;
DateValueToSQLStringProc: TDateValueToSQLStringProcEh; SupportsLike: Boolean): String;
function VarValueAsFilterStr(v: Variant): String;
begin
if VarType(v) = varDouble then
Result := FloatToStr(v)
else if VarType(v) = varDate then
if @DateValueToSQLStringProc <> nil then
Result := DateValueToSQLStringProc(Dataset, v)
else
Result := '''' + DateTimeToStr(v) + ''''
else
Result := '''' + VarToStr(v) + '''';
end;
var
i: Integer;
begin
if O in [foIn, foNotIn] then
begin
Result := Result + ' (';
if VarIsArray(v) then
for i := VarArrayLowBound(v, 1) to VarArrayHighBound(v, 1) do
Result := Result + '[' + FieldName + '] = ' + VarValueAsFilterStr(v[i]) + ' OR '
else
Result := Result + '[' +FieldName + '] = ' + VarValueAsFilterStr(v) + ' OR ';
Delete(Result, Length(Result) - 3, 4);
Result := Result + ')';
end
else if O in [foLike, foNotLike] then
begin
Result := Result + ' [' + FieldName;
if SupportsLike then
if O = foLike
then Result := Result + '] Like '
else Result := Result + '] Not Like '
else
if O = foLike
then Result := Result + '] = '
else Result := Result + '] <> ';
Result := Result + VarValueAsFilterStr(v);
end else
begin
Result := Result + ' [' + FieldName + '] ' + STFilterOperatorsSQLStrMapEh[O];
if not (O in [foNull, foNotNull]) then
Result := Result + ' ' + VarValueAsFilterStr(v);
end;
end;
function GetOneExpressionAsSQLWhereString(O: TSTFilterOperatorEh; v: Variant;
FieldName: String; DataSet: TDataSet;
DateValueToSQLStringProc: TDateValueToSQLStringProcEh; SupportsLike: Boolean): String;
function VarValueAsFilterStr(v: Variant): String;
var
{$IFDEF CIL}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -