Search code examples
functiondelphivarianttadoquery

Function with Variant Parameter


I created a function to Refresh a Query with Parameters, and then Locate a Specific field .

function RefreshQuery(AQuery : TADOQuery; AField : string; AValue : integer; AParam : string; AParamValue : Variant) : boolean; overload;

When the AValue is integer it works , when I change it to Variant

I get a List Index Out of Bounds 1699364 error .

The Function itself looks like this :

function RefreshQuery(AQuery : TADOQuery; AField : string; AValue : integer; AParam : string; AParamValue : Variant) : boolean; overload;
var AfterOpen,AfterScroll,BeforeOpen : TDataSetNotifyEvent;
    AList : TStringList;
    i : integer;
begin
  result:=false;

  AfterOpen := AQuery.AfterOpen;
  AfterScroll := AQuery.AfterScroll;
  BeforeOpen := AQuery.BeforeOpen;

  AQuery.AfterOpen:=nil;
  AQuery.AfterScroll:=nil;
  AQuery.BeforeOpen:=nil;

  AList := TStringList.Create;
  AList.Delimiter:=';';
  AList.DelimitedText:=AParam;

  if AQuery.Active then AQuery.Close;

  if AList.Count = 1 then
    AQuery.Parameters.ParamByName(AList[i]).Value:=AParamValue // the error happens here
  else
    for i := 0 to AList.Count-1 do
      AQuery.Parameters.ParamByName(AList[i]).Value:=AParamValue[i];

  AQuery.Open;

  if not AQuery.Locate(AField, AValue, []) then
    result:=false
  else
    result:=true;

  AQuery.AfterOpen:=AfterOpen;
  AQuery.AfterScroll:=AfterScroll;
  AQuery.BeforeOpen:=BeforeOpen;

  if Assigned(AQuery.AfterScroll) then
    AQuery.AfterScroll(AQuery);

  AList.Free;
end;

I use it like this :

  if   RefreshQuery(CityQuery,'id',CityQueryID.Value,'Active',not(CheckBox1.Checked).ToInteger+2) = false then
  begin
    MessageDlg('blabla!',mtWarning, [mbOK], 0);
    Exit;
  end;

In the Above example CityQueryID.Value is of Integer Type . But Sometimes I would like to use String . So I would like to change the Function to work with Variants.


Solution

  • The error happens because at the statement

      if AList.Count = 1 then
        AQuery.Parameters.ParamByName(AList[i]).Value:=AParamValue // the error happens here
    

    you have not yet assigned a value to i and as it is a local variable, it will have a random value, depending on what's been on the stack before RefreshQuery is called.

    Changing the statement to

      if AList.Count = 1 then
        AQuery.Parameters.ParamByName(AList[0]).Value:=AParamValue
    

    should fix the problem.

    Once you have done that, you should find that you can change the parameter type of AValue to variant without problem.