zoukankan      html  css  js  c++  java
  • 通用查询组件设计

    作者:nxyc_twz@163.com
    在当前的MIS系统中,数据维护与数据查询是其两个核心功能。如何设计一个通用的查询组件,使开发的MIS系统中具备统一的查询界面,是MIS系统开发人员一直在偿试解决的问题。笔者在多年的MIS系统的开发设计过程中,经过不断的摸索与实践,终于设计完成了这套相对比较完善、通用的查询组件。
    该组件继承自Tcomponet组件,主要包括一个查询窗体及一个显示查询摘要的窗体。主要设计思路是通过设置Tquery组件的Params(参数)以达到通用查询的目的。关于如何设计自定义组件,请参考:创建定制组件
    现将其设计思路与技巧公布出来,与广大编程爱好者共勉。定义通用查询类
     
    function WordPos(const AWord, AString: string): Integer;
    //在指定字符串中查找字符串
    var s: string;
        i, p: Integer;
    begin
      s := ' ' + AnsiUpperCase(AString) + ' ';  //忽略大小写
      for i := 1 to Length(s) do if not (s[i] in Identifiers) then s[i] := ' '; //常量定义
      p := Pos(' ' + AnsiUpperCase(AWord) + ' ', s);  
      Result := p;
    end;
     
    type
      TDBFilterDialog = class(TComponent)
      private
        FDialog : TMyDBFilterDialog;//查询窗体类
        FOriginalSQL : TStrings;//原来的SQL语句
        FModifiedSQL : TStrings;//修改后的SQL语句
        FDataSet : TQuery;//数据集
        FDefaultMatchType : TDBFilterMatchType;//过滤类型
        FOptions : TDBOptions;//过滤选项
        FCaption: String;//窗体标题
        FFields: TStringList;//字段列表
        FOriginalVariables : TList;//变量列表
        SQLProp : String;//SQL属性
        procedure SetDataSet(const Value: TQuery);//设置数据集
        procedure SetOptions(const Value: TDBOptions);//设置选项
        procedure SetCaption(const Value: String);//设置标题
        procedure SetDefaultMatchType(const Value: TDBFilterMatchType);//设置默认的匹配类型
        procedure SetFields;//设置字段
        procedure SetFieldsList(const Value: TStringList);//设置字段列表
        procedure SetOriginalSQL(const Value: TStrings);//设置SQL
        procedure RestoreSQL;//恢复SQL
        procedure SaveParamValues;//保存参数值
        { Private declarations }
      protected
        { Protected declarations }
        procedure Loaded; override;//装载过滤对话框
        procedure Notification(AComponent: TComponent;
          Operation: TOperation); override;//传送消息
        property OriginalSQL : TStrings read FOriginalSQL write SetOriginalSQL;
      public
        { Public declarations }
        constructor Create(AOwner : TComponent); override;//构造函数
        destructor Destroy; override;//析构函数
        function Execute : Boolean;//执行查询
        procedure ReBuildSQL;//重建SQL语句
        property ModifiedSQL : TStrings read FModifiedSQL;
      published
        { Published declarations }
        property Caption : String read FCaption write SetCaption;//设置标题
        property DataSet : TQuery read FDataSet write SetDataSet;//设置数据集
        property DefaultMatchType : TDBFilterMatchType read FDefaultMatchType write SetDefaultMatchType
           default fdMatchStart;//过滤类型
        property Options : TDBOptions read FOptions write SetOptions default
          [fdShowCaseSensitive, fdShowNonMatching];//过滤选项
        property Fields : TStringList read FFields write SetFieldsList;
      end;
     
    TDBVariable = class  //参数数据变量
      public
        VariableName : String;  //变量名 
        VariableValue : Variant;  //变量值
        constructor Create(name : String; value : Variant); //构造函数,设置变量名及变量值
      end;
     
    constructor TDBVariable.Create(name: String; value : Variant);
    begin
    //构造函数,设置变量名及变量值
      VariableName := name;
      VariableValue := value;
    end;
     
    const
      Identifiers = ['a'..'z', 'A'..'Z', '0'..'9', '_', '#', '$', '.', '"', '@'];
     
    procedure Register;//注册组件
     
    procedure Register;
    //注册组件
    begin
      RegisterComponents('我的数据库组件', [TDBFilterDialog]);
    end; {of Register}
     
    //过滤的匹配类型:完全匹配、起始处匹配、结束处匹配、任意位置匹配、范围匹配、不匹配
      TDBFilterMatchType = (fdMatchExact, fdMatchStart, fdMatchEnd,
    fdMatchAny, fdMatchRange, fdMatchNone);
     
    //过滤选项:大小写敏感  显示大小写敏感  显示不匹配记录
      TDBOption = (fdCaseSensitive, fdShowCaseSensitive, fdShowNonMatching);
      TDBOptions = Set of TDBOption;
     
    procedure TDBFilterDialog.SetDataSet(const Value: TQuery);
    begin
    //设置数据集
      if not ((Value is TQuery) or (Value = nil)) then//如果未指定数据集或指定的数据集不是Tquery,则发出异常
        Raise Exception.Create(SDBFilterNonDBError);
    //否则 
    FDataSet := Value;
    SQLProp := 'SQL';   
      if ([csDesigning, csLoading] * ComponentState) = [] then
      begin
        SetFields;//设置字段
        OriginalSQL := TStrings(GetOrdProp(FDataSet, SQLProp));//
      end;
    end;
     
    procedure TDBFilterDialog.SetOptions(const Value: TDBOptions);
    begin
    //设置选项
      FOptions := Value;
    end;
     
    procedure TDBFilterDialog.SetCaption(const Value: String);
    begin
    //设置标题
      FCaption := Value;
      FDialog.Caption := FCaption;
    end;

    procedure TDBFilterDialog.SetDefaultMatchType(const Value: TDBFilterMatchType);
    begin
    //设置默认的匹配类型
    FDefaultMatchType := Value;
      if Assigned(FDialog) and not (csDesigning in ComponentState) then
        case FDefaultMatchType of
          fdMatchNone :
          begin
            FDialog.grpSearchType.ItemIndex := 0;
            FDialog.cbxNonMatching.Checked := true;
          end;
          fdMatchRange:
            FDialog.pgeCriteria.ActivePage := FDialog.tabByRange;
          else
            FDialog.grpSearchType.ItemIndex := Integer(FDefaultMatchType);
        end;
    end;
     
    procedure TDBFilterDialog.SetFields;
    var
      i, j, p : Integer;
      field, display : String;
    begin
    //设置字段
      FDialog.lstAllFields.Clear;//清除所有字段
      if FFields.Count = 0 then
      begin
        for i := 0 to FDataSet.FieldList.Count - 1 do
         if FDataSet.Fields[i].Visible then //定义查询字段
           FDialog.lstAllFields.Items.AddObject(FDataSet.Fields[i].DisplayName,FDataSet.FieldList.Fields[i]);
      end
      else
        for j := 0 to FFields.Count - 1 do
        begin
          p := Pos(';', FFields.Strings[j]);
          field := Copy(FFields.Strings[j], 1, p - 1);
          if p = Length(FFields.Strings[j]) then
            display := field
          else
            display := Copy(FFields.Strings[j], p+1, Length(FFields.Strings[j]));
          for i := 0 to FDataSet.FieldList.Count - 1 do
            if FDataSet.FieldList.Fields[i].FieldName = field then
            FDialog.lstAllFields.Items.AddObject(display, FDataSet.FieldList.Fields[i]);
        end;
      if FDialog.lstAllFields.Items.Count > 0 then
      begin
        FDialog.lstAllFields.ItemIndex := 0;
        FDialog.FieldsListBoxClick(nil);//单击字段列表框
      end;
    end;
     
    procedure TDBFilterDialog.SetFieldsList(const Value: TStringList);
    begin
    //设置字段列表
      FFields.Assign(Value);
    end;
     
    procedure TDBFilterDialog.SetOriginalSQL(const Value: TStrings);
    var
      i : Integer;
    begin
    //设置SQL语句
      if FOriginalSQL.Text <> Value.Text then
      begin
        FOriginalSQL.Clear;
        FOriginalSQL.AddStrings(Value);
        if not (csLoading in ComponentState) then
          FFields.Clear;
        FDialog.NewSQL;//新建SQL查询
      end;
      for i := 0 to FOriginalVariables.Count - 1 do
        TDBVariable(FOriginalVariables[i]).Free;//定义参数数据变量类
      FOriginalVariables.Clear;
      if TStrings(GetOrdProp(FDataSet, SQLProp)).Text = '' then
        exit;
     
    for i := 0 to TQuery(FDataSet).Params.Count - 1 do
    FOriginalVariables.Add(TDBVariable.Create(TQuery(FDataSet).Params[i].Name, TQuery(FDataSet).Params[i].Value)); //定义参数数据变量类
      SetFields;//设置字段
    end;
     
    procedure TDBFilterDialog.RestoreSQL;
    var
      i : Integer;
    begin
    //恢复SQL语句
      // Disable the controls while we are working
      FDataSet.DisableControls;
      FDataSet.Close;
      // clear the existing SQL and variable declarations
      // restore the original SQL and variables
      SetOrdProp(FDataSet, SQLProp, Integer(FOriginalSQL));
      if FDataSet is TDataSet then
        for i := 0 to FOriginalVariables.Count - 1 do
          TQuery(FDataSet).ParamByName(TDBVariable(FOriginalVariables[i]).VariableName).Value :=
             TDBVariable(FOriginalVariables[i]).VariableValue
      else
        for i := 0 to FOriginalVariables.Count - 1 do
          TQuery(FDataSet).ParamByName(TdBVariable(FOriginalVariables[i]).VariableName).Value :=
             TDBVariable(FOriginalVariables[i]).VariableValue;
      FDataSet.Open;
      SetFields;
      FDataSet.EnableControls;
      FModifiedSQL.Assign(TStrings(GetOrdProp(FDataSet, SQLProp)));
    end;
     
    procedure TDBFilterDialog.SaveParamValues;
    var
      i : Integer;
    begin
    //保存参数值
       if FDataSet is TDataSet then
        for i := 0 to FOriginalVariables.Count - 1 do
          TDBVariable(FOriginalVariables[i]).VariableValue :=
            TQuery(FDataSet).ParamByName(TDBVariable(FOriginalVariables[i]).VariableName).Value
      else
        for i := 0 to FOriginalVariables.Count - 1 do
          TDBVariable(FOriginalVariables[i]).VariableValue :=
            TQuery(FDataSet).ParamByName(TDBVariable(FOriginalVariables[i]).VariableName).Value;
    end;
     
    procedure TDBFilterDialog.Loaded;
    var
      i : Integer;
    begin
      inherited;
      if Assigned(FDataSet) and not (csDesigning in ComponentState) then
      begin
        SetFields;
        OriginalSQL.Assign(TStrings(GetOrdProp(FDataSet, SQLProp)));
        for i := 0 to TQuery(FDataSet).Params.Count - 1 do
            FOriginalVariables.Add(TDBVariable.Create(TQuery(FDataSet).Params[i].Name,
              TQuery(FDataSet).Params[i].Value));
      end;
    end;
     
    procedure TDBFilterDialog.Notification(AComponent: TComponent;
      Operation: TOperation);
    begin
      inherited;
      if (AComponent = FDataset) and (Operation = opRemove) then
        FDataset := nil;
    end;
     
    constructor TDBFilterDialog.Create(AOwner: TComponent);
    begin
    //构造函数
      inherited Create(AOwner);
      FDialog := TMyDBFilterDialog.Create(self);
      FOptions := [fdShowCaseSensitive, fdShowNonMatching];
      FDefaultMatchType := fdMatchStart;
      Caption := SDBFilterCaption;
      FFields := TStringList.Create;
      FOriginalSQL := TStringList.Create;
      FModifiedSQL := TStringList.Create;
      FOriginalVariables := TList.Create;
    end;
    destructor TDBFilterDialog.Destroy;
    var
      i : Integer;
    begin
      FDialog.Free;
      FFields.Free;
      FOriginalSQL.Free;
      FModifiedSQL.Free;
      for i := 0 to FOriginalVariables.Count - 1 do
        TDBVariable(FOriginalVariables[i]).Free;
      FOriginalVariables.Free;
      inherited Destroy;
    end;
     
    function TDBFilterDialog.Execute : Boolean;
    var
      CurrentSQL : TStrings;
    begin
    //执行数据查询
      CurrentSQL := TStrings(GetOrdProp(FDataSet, SQLProp));
      // 检查SQL语句是否已经改变了
      if not FModifiedSQL.Equals(CurrentSQL) then
        OriginalSQL := CurrentSQL;
      if FDialog.lstAllFields.Items.Count = 0 then
        SetFields;
      FDialog.grpSearchType.ItemIndex := Integer(FDefaultMatchType);
      if fdShowCaseSensitive in Options then
        FDialog.cbxCaseSensitive.Visible := true
      else
        FDialog.cbxCaseSensitive.Visible := false;
      if fdShowNonMatching in Options then
        FDialog.cbxNonMatching.Visible := true
      else
        FDialog.cbxNonMatching.Visible := false;
      if fdCaseSensitive in Options then
        FDialog.cbxCaseSensitive.Checked := true
      else
        FDialog.cbxCaseSensitive.Checked := false;
      SaveParamValues;//保存参数值
      Result := FDialog.ShowModal = mrOK; //点击确定按钮
      if Result then
        ReBuildSQL;//重建SQL语句
    end;

    procedure TDBFilterDialog.SaveParamValues;
    var
      i : Integer;
    begin
    //保存参数值
       for i := 0 to FOriginalVariables.Count - 1 do
         TDBVariable(FOriginalVariables[i]).VariableValue :=
            TQuery(FDataSet).ParamByName(TDBVariable(FOriginalVariables[i]).VariableName).Value;
    end;
     
    procedure TMyDBFilterDialog.btnOkClick(Sender: TObject);
    var
      i : Integer;
      f : TMyFieldInfo;
    begin
    //点击确定按钮
      for i := FPreviousList.Count - 1 downto 0 do
      begin
        TMyFieldInfo(FPreviousList[i]).Free;
        FPreviousList.Delete(i);
      end;
      GetCriteria;//获取标准
      SetCriteria;//设置标准
      for i := 0 to FFilterList.Count - 1 do
      begin
        f := TMyFieldInfo.Create;//字段定义类
        f.Assign(TMyFieldInfo(FFilterList[i]));
        FPreviousList.Add(f);
      end;
    end;
     
    procedure TMyDBFilterDialog.GetCriteria ;
    //获取标准
    var
      FilterIndex, i : Integer;
    begin
      FilterIndex := -1;
      i := 0;
      while (i < FFilterList.Count) and (FilterIndex < 0) do
      begin
        if TMyFieldInfo(FFilterList[i]).DisplayLabel = lstAllFields.Items[LastIndex] then
          FilterIndex := i;
        Inc(i);
      end;
      // This is only enabled when at least one of the fields has entry
      if btnNewSearch.Enabled then
      begin
        // The user added a new criteria
        if FilterIndex < 0 then
        begin
          FFilterList.Add(TMyFieldInfo.Create);
          FilterIndex := FFilterList.Count - 1;
          lstSelectedFields.Items.AddObject(lstAllFields.Items[LastIndex],
            lstAllFields.Items.Objects[LastIndex]);
        end;
        // Set the fields
        with TMyFieldInfo(FFilterList[FilterIndex])  do
        begin
          CaseSensitive := cbxCaseSensitive.Checked;
          DisplayLabel := lstAllFields.Items[LastIndex];
          // Save off the TField for this field
          FieldName := TField(lstAllFields.Items.Objects[LastIndex]).FieldName;
          FieldOrigin := TField(lstAllFields.Items.Objects[LastIndex]).Origin;
          FieldType := TField(lstAllFields.Items.Objects[LastIndex]).DataType;
          // Match Criteria is either Range or one of the other 4
          if pgeCriteria.ActivePage = tabByRange then
            MatchType := fdMatchRange
          else
            MatchType := TDBFilterMatchType(grpSearchType.ItemIndex);
          // Only save the criteria that they want to work with
          if MatchType = fdMatchRange then
          begin
            EndingValue := edtEndingRange.Text;
            StartingValue := edtStartingRange.Text;
            FilterValue := '';
          end
          else
          begin
            EndingValue := '';
            StartingValue := '';
            FilterValue := edtFieldValue.Text;
          end;
          NonMatching := cbxNonMatching.Checked;
        end;
      end
      else
        // The user removed a criteria that existed
        if FilterIndex >= 0 then
        begin
          // remove the Selected list item
          lstSelectedFields.Items.Delete(lstSelectedFields.Items.IndexOf(
               TMyFieldInfo(FFilterList[FilterIndex]).DisplayLabel));
          // Free the FieldInfo Object
          TMyFieldInfo(FFilterList[FilterIndex]).Free;
          // Delete it from the list
          FFilterList.Delete(FilterIndex);
          if FFilterList.Count = 0 then
            btnViewSummary.Enabled := false;
        end;
    end;
     
    procedure TMyDBFilterDialog.SetCriteria;
    var
      FilterIndex, i : Integer;
      DisplayName : String;
    begin
      DisplayName := lstAllFields.Items[lstAllFields.ItemIndex];
      i := 0;
      FilterIndex := -1;
      // Find the Item in the list if it exists
      while (i < FFilterList.Count) and (FilterIndex < 0) do
      begin
        if TMyFieldInfo(FFilterList[i]).DisplayLabel = DisplayName then
          FilterIndex := i;
        Inc(i);
      end;
      if FilterIndex < 0 then
        // This has no current criteria
        ClearCriteria
      else
      begin
        with TMyFieldInfo(FFilterList[FilterIndex])  do
        begin
          cbxCaseSensitive.Checked := CaseSensitive;
          edtEndingRange.Text := EndingValue;
          edtFieldValue.Text := FilterValue;
          if MatchType <> fdMatchRange then
            grpSearchType.ItemIndex := Integer(MatchType);
          cbxNonMatching.Checked := NonMatching;
          edtStartingRange.Text := StartingValue;
          if MatchType = fdMatchRange then
            pgeCriteria.ActivePage := tabByRange
          else
            pgeCriteria.ActivePage := tabByValue;
        end;
      end;
    end;
     
    procedure TDBFilterDialog.ReBuildSQL;
    var
      s, s1 : String;
      SQL, NewSQL : TStringStream;
      p, i : Integer;
      hasWhere : boolean;
    begin
    //生成SQL语句
     if FDialog.lstSelectedFields.Items.Count = 0 then //如果没有已选字段,则
      begin
        if TStrings(GetOrdProp(FDataSet, SQLProp)) <> FOriginalSQL then
          RestoreSQL;
        exit;
      end;
     
      NewSQL := TStringStream.Create(s1);
      SQL := TStringStream.Create(s);
      try                              //保存到流
        FOriginalSQL.SaveToStream(SQL);
        SQL.Seek( 0, soFromBeginning);
        p := WordPos('WHERE', SQL.DataString);
     
        if p = 0 then  //如果SQL语句中没有WHERE子句
        begin
          hasWhere := false;
          p := WordPos('GROUP', SQL.DataString);
          if p = 0 then  //如果SQL语句中没有GROUP子句
            p := WordPos('HAVING', SQL.DataString);
            if p = 0 then  //如果SQL语句中没有HAVING子句
              P := WordPos('ORDER', SQL.DataString);
              if p = 0 then  //如果SQL语句中没有ORDER子句
                p := SQL.Size;
        end
        else
        begin //SQL语句中有WHERE子句
          hasWhere := true;
          Inc(p, 5);
        end;
     
        NewSQL.WriteString(SQL.ReadString(p - 1));
        if not hasWhere then  //如果SQL语句中没有WHERE子句
          NewSQL.WriteString(' WHERE ');
        for i := 0 to FDialog.FilterList.Count - 1 do
        begin
          NewSQL.WriteString(FDialog[i].CreateSQL);
          if i < FDialog.FilterList.Count - 1 then
            NewSQL.WriteString(' AND ')
          else
            if hasWhere then
              NewSQL.WriteString(' AND ');
        end;
        NewSQL.WriteString(SQL.ReadString(SQL.Size));
     
        // 在执行SQL时暂停有所的控件
         Application.MessageBox(PChar(NewSQL.DataString),'123',MB_OK);
          if FDataSet is TQuery then
            with FDataSet as TQuery do
            begin
              DisableControls;
              Close;
              SQL.Clear;
              SQL.Add(NewSQL.DataString);
              for i := 0 to FOriginalVariables.Count - 1 do
              begin
                ParamByName(TDBVariable(FOriginalVariables[i]).VariableName).Value :=
                      TDBVariable(FOriginalVariables[i]).VariableValue;
              end;
              // 设置新的变量
              for i := 0 to FDialog.FilterList.Count - 1 do
                FDialog[i].SetVariables(FDataSet);
              try
                Open;
              except
                RestoreSQL;  //如果出错,则恢复原来的SQL语句
              end;
            end;
     
        SetFields;
        FDataSet.EnableControls;
        FModifiedSQL.Assign(TStrings(GetOrdProp(FDataSet, SQLProp)));
      finally
        SQL.Free;
        NewSQL.Free;
      end;
    end;

    procedure TMyFieldInfo.SetVariables(d: TDataset);
    var
      value : String;
    begin
    //设置变量值
      if AnsiUpperCase(FilterValue) = 'NULL' then //如果FilterValue为空,则退出
        exit;
      if FieldType = ftString then //如果字段类型为字符串型,则
      begin
        if CaseSensitive then  //如果大小写敏感
          case MatchType of  //匹配类型
            fdMatchStart, fdMatchAny :  //起始部分匹配或任意位置匹配
              value := FilterValue;
            fdMatchEnd : //结束部分匹配
              value := '%' + FilterValue; 
            fdMatchExact : //非匹配记录
              value := FilterValue;
          end
    else  //大小写不敏感
      case MatchType of
            fdMatchStart, fdMatchAny : //起始部分匹配或任意位置匹配
              value := AnsiUpperCase(FilterValue);
            fdMatchEnd : //结束部分匹配
              value := '%' + AnsiUpperCase(FilterValue);  {do not localize}
            fdMatchExact : //非匹配记录
              value := AnsiUpperCase(FilterValue);
          end;
      end
      else//字段类型为非字符串型
     value := FilterValue;
     
      if MatchType <> fdMatchRange then//如果匹配类型不为按范围
    TQuery(d).ParamByName(FieldName + 'Filter').Value :=  value
    else //否则
        begin
          if CaseSensitive then //如果大小写敏感
          begin
            if StartingValue <> '' then //如果起始范围值不为空 
              TQuery(d).ParamByName(FieldName + 'Start').Value := StartingValue;  
        if EndingValue <> '' then //如果结束范围不为空
              TQuery(d).ParamByName(FieldName + 'End').Value := EndingValue;  
      end
          else //大小写敏感
          begin
            if StartingValue <> '' then //如果起始范围值不为空
              TQuery(d).ParamByName(FieldName + 'Start').Value := AnsiUpperCase(StartingValue);
             if EndingValue <> '' then //如果结束范围值不为空
              TQuery(d).ParamByName(FieldName + 'End').Value := AnsiUpperCase(EndingValue); 
          end;
        end;
      end
    end;
     
    TMyFieldInfo = class   //字段类
      public
        FieldName : String;  //字段名
        FieldOrigin : String; 
        FieldType : TFieldType;  //字段类型
        DisplayLabel : String;  //显示的名称
        MatchType : TDBFilterMatchType;  //匹配类型
        FilterValue : String; //过滤值
        StartingValue : String; //开始值
        EndingValue : String;  //结束值
        CaseSensitive : boolean; //是否大小写敏感
        NonMatching : boolean;  //不匹配
        procedure Assign(o : TMyFieldInfo); //指定字段定义
    function CreateSQL : String;  //创建SQL语句
    procedure SetVariables( d : TDataset);  //设置字段变量
      end;
    procedure TMyFieldInfo.Assign(o : TMyFieldInfo);
    begin
    //指定字段信息
      FieldName := o.FieldName;
      FieldOrigin := o.FieldOrigin;
      FieldType := o.FieldType;
      DisplayLabel := o.DisplayLabel;
      MatchType := o.MatchType;
      FilterValue := o.FilterValue;
      StartingValue := o.StartingValue;
      EndingValue := o.EndingValue;
      CaseSensitive := o.CaseSensitive;
      NonMatching := o.NonMatching;
    end;
    function TMyFieldInfo.CreateSQL: String;
    var
      Field : String;
    begin
    //创建SQL语句
      if FieldOrigin <> '' then
        Field := FieldOrigin
      else
        Field := FieldName;
      if NonMatching then
        Result := ' not ( '
      else
        Result := ' ( ';
      if AnsiUpperCase(FilterValue) = 'NULL' then
      begin
        Result := Result + Format('%s is NULL) ', [Field]);
        exit;
      end;
      if FieldType = ftString then
      begin
        if CaseSensitive then
          case MatchType of
            fdMatchStart:
              Result := Result + Format('%0:s starting with :%1:sFilter ) ', [Field, FieldName]);
            fdMatchAny:
              Result := Result + Format('%0:s containing :%1:sFilter ) ', [Field, FieldName]);
            fdMatchEnd :
              Result := Result + Format('%0:s = :%1:sFilter ) ', [Field, FieldName]);
            fdMatchExact :
              Result := Result + Format('%0:s = :%1:sFilter ) ', [Field, FieldName]);
            fdMatchRange :
            begin
              if StartingValue <> '' then
                Result := Result + Format('%0:s >= :%1:sStart)', [Field, FieldName]);
              if (StartingValue <> '') and (EndingValue <> '') then
                Result := Result + ' and (';
              if EndingValue <> '' then
                Result := Result + Format('%0:s <= :%1:sEnd)', [Field, FieldName]);
            end;
          end
        else
          case MatchType of
            fdMatchStart:
              Result := Result + Format('UPPER(%0:s) starting with :%1:sFilter ) ', [Field, FieldName]); {do not localize}
            fdMatchAny:
              Result := Result + Format('UPPER(%0:s) containing :%1:sFilter ) ', [Field, FieldName]); {do not localize}
            fdMatchEnd :
              Result := Result + Format('UPPER(%0:s) like :%1:sFilter ) ', [Field, FieldName]);  {do not localize}
            fdMatchExact :
              Result := Result + Format('UPPER(%0:s) = :%1:sFilter ) ', [Field, FieldName]);  {do not localize}
            fdMatchRange :
            begin
              if FieldType = ftString then
              begin
                if StartingValue <> '' then
                  Result := Result + Format('UPPER(%0:s) >= :%1:sStart)', [Field, FieldName]); {do not localize}
                if (StartingValue <> '') and (EndingValue <> '') then
                  Result := Result + ' and (';  {do not localize}
                if EndingValue <> '' then
                  Result := Result + Format('UPPER(%0:s) <= :%1:sEnd)', [Field, FieldName]); {do not localize}
              end
              else
              begin
                if StartingValue <> '' then
                  Result := Result + Format('%0:s >= :%1:sStart)', [Field, FieldName]);   {do not localize}
                if (StartingValue <> '') and (EndingValue <> '') then
                  Result := Result + ' and (';   {do not localize}
                if EndingValue <> '' then
                  Result := Result + Format('%0:s <= :%1:sEnd)', [Field, FieldName]);  {do not localize}
              end
            end;
          end;
      end
      else
        case MatchType of
          fdMatchRange :
          begin
            if StartingValue <> '' then
              Result := Result + Format('%0:s >= :%1:sStart)', [Field, FieldName]); {do not localize}
            if (StartingValue <> '') and (EndingValue <> '') then
              Result := Result + ' and ('; {do not localize}
            if EndingValue <> '' then
              Result := Result + Format('%0:s <= :%1:sEnd)', [Field, FieldName]);  {do not localize}
          end;
          else
            Result := Result + Format('%0:s = :%1:sFilter ) ', [Field, FieldName]); {do not localize}
        end;
    end;

    procedure TMyFieldInfo.SetVariables(d: TDataset);
    var
      value : String;
    begin
    //设置变量值
      if AnsiUpperCase(FilterValue) = 'NULL' then
        exit;
      if FieldType = ftString then
      begin
        if CaseSensitive then
          case MatchType of
            fdMatchStart, fdMatchAny :
              value := FilterValue;
            fdMatchEnd :
              value := '%' + FilterValue;
            fdMatchExact :
              value := FilterValue;
          end
        else
          case MatchType of
            fdMatchStart, fdMatchAny :
              value := AnsiUpperCase(FilterValue);
            fdMatchEnd :
              value := '%' + AnsiUpperCase(FilterValue);
            fdMatchExact :
              value := AnsiUpperCase(FilterValue);
          end;
      end
      else
        value := FilterValue;
      if d is TDataSet then
      begin
        if MatchType <> fdMatchRange then
          TQuery(d).ParamByName(FieldName + 'Filter').Value :=  value
        else
        begin
          if CaseSensitive then
          begin
            if StartingValue <> '' then
              TQuery(d).ParamByName(FieldName + 'Start').Value := StartingValue;
            if EndingValue <> '' then
              TQuery(d).ParamByName(FieldName + 'End').Value := EndingValue;
          end
          else
          begin
            if StartingValue <> '' then
              TQuery(d).ParamByName(FieldName + 'Start').Value := AnsiUpperCase(StartingValue);
            if EndingValue <> '' then
              TQuery(d).ParamByName(FieldName + 'End').Value := AnsiUpperCase(EndingValue);
          end;
        end;
      end
      else
      begin
        if MatchType <> fdMatchRange then
          TQuery(d).ParamByName(FieldName + 'Filter').Value :=  value
        else
        begin
          if CaseSensitive then
          begin
            if StartingValue <> '' then
              TQuery(d).ParamByName(FieldName + 'Start').Value := StartingValue;
            if EndingValue <> '' then
              TQuery(d).ParamByName(FieldName + 'End').Value := EndingValue;
          end
          else
          begin
            if StartingValue <> '' then
              TQuery(d).ParamByName(FieldName + 'Start').Value := AnsiUpperCase(StartingValue);
            if EndingValue <> '' then
              TQuery(d).ParamByName(FieldName + 'End').Value := AnsiUpperCase(EndingValue);  
          end;
        end;
      end
    end;
     
    TDBVariable = class  //参数数据变量
      public
        VariableName : String;  //变量名 
        VariableValue : Variant;  //变量值
        constructor Create(name : String; value : Variant); //构造函数
      end;
  • 相关阅读:
    poj 1050
    poj 2479 Maximum sum
    Trie树结构(AC自动机前奏)(转)
    poj 3624(zeroonepack)
    poj 3630(Phone List )
    KMP算法(AC自动机前奏)(转)
    AC自动机(转)
    AC自动机模板(hdu2222)
    Running CMD.EXE as Local System
    什么是WPF(Avalon)
  • 原文地址:https://www.cnblogs.com/todd/p/173986.html
Copyright © 2011-2022 走看看