Page 1 of 1

List index out of bounds -> InsertText

Posted: Fri Mar 14, 2014 5:00 pm
by rafakwolf
Hello

i'm trying to execute a Search and Replace this way:

Code: Select all

procedure GoToBeginTexto(RichView: TCustomRichView);
var Item, Off: Integer;
begin
  Item := 0;
  Off := RichView.GetOffsBeforeItem(Item);
  RichView.SetSelectionBounds(Item, Off, Item, Off);
end;

procedure proc_name...

const TEMP_TEXT : string = '@&#%$';
var
  PosPrimPtoVirg, PosSegPtoVirg, PosSinal,
  PosMaiorMaior, PosMenorMenor, PosInicioSe, SelLength: Integer;
  Campo, ValorCondicao, TextoIfTrue, TextoIfFalse: String;
  Sinal: TTipoSinalCond;
  Tipo: TPLTipoCampoModelo;

  procedure TrocaSePorTemp;
  begin
    RVSetSelection(rveTexto, PosInicioSe, 5);
    // Troca o "<<SE " por "TEMP_TEXT" para que não encontre o mesmo <<SE novamente.
    rveTexto.InsertText(TEMP_TEXT);
  end;

begin
  rveTexto.BeginUpdate;
  try
    GotoBeginTexto(rveTexto);

    while rveTexto.SearchText('<<SE ', [rvseoDown]) do
    begin
      RVGetSelection(rveTexto, PosInicioSe, SelLength);

      //Encontra o proximo ">>" depois do inicio da tag "<<SE"

      RVSetLinearCaretPos(rveTexto, PosInicioSe);

      if rveTexto.SearchText('>>', [rvseoDown]) then
        RVGetSelection(rveTexto, PosMaiorMaior, SelLength)
      else
        PosMaiorMaior := -1;

      //Encontra o proximo "<<" depois do inicio da tag "<<SE"

      RVSetLinearCaretPos(rveTexto, PosInicioSe);

      if rveTexto.SearchText('<<', [rvseoDown]) then
        RVGetSelection(rveTexto, PosMenorMenor, SelLength)
      else
        PosMenorMenor := -1;

      // Verifica se o "<<" está antes do ">>" ou se não existe um ">>",
      // caso alguma dessas condicoes seja verdadeira o "<<SE" não foi fechado
      // corretamente, nesse caso não substitui.

      if (PosMenorMenor > PosMaiorMaior) or (PosMaiorMaior = -1) then
        TrocaSePorTemp
      else

      // Se o "<<SE " foi fechado corretamente então procura o sinal e os dois ";" dentro da expressão.
      begin
        RVSetLinearCaretPos(rveTexto, PosInicioSe);

        //Procura o sinal de igual
        if rveTexto.SearchText('=', [rvseoDown]) then
        begin
          Sinal := tsIgual;
          RVGetSelection(rveTexto, PosSinal, SelLength);

          // Se o sinal de igual estiver depois do >> entao nao considera

          if PosSinal > PosMaiorMaior then
            PosSinal := -1;
        end
        else
          PosSinal := -1;

        // Se não validou o sinal de igual entao procura o sinal de diferente

        if PosSinal = -1 then
        begin
          RVSetLinearCaretPos(rveTexto, PosInicioSe);

          if rveTexto.SearchText('!', [rvseoDown]) then
          begin
            Sinal := tsDiferente;
            RVGetSelection(rveTexto, PosSinal, SelLength);

            //Se o sinal de diferente estiver depois do >> entao nao considera

            if PosSinal > PosMaiorMaior then
              PosSinal := -1;
          end
          else
            PosSinal := -1;
        end;

        if PosSinal <> -1 then
        begin
          RVSetLinearCaretPos(rveTexto, PosSinal + 1);

          //Procura o primeiro ponto e virgula.
          if rveTexto.SearchText(';', [rvseoDown]) then
          begin
            RVGetSelection(rveTexto, PosPrimPtoVirg, SelLength);

            // Se o primeiro ponto e virgula estiver antes do >> entao prossegue
            if PosPrimPtoVirg < PosMaiorMaior then
            begin
              RVSetLinearCaretPos(rveTexto, PosPrimPtoVirg + 1);

              //Procura o segundo ponto e virgula
              if rveTexto.SearchText(';', [rvseoDown]) then
              begin
                RVGetSelection(rveTexto, PosSegPtoVirg, SelLength);

                if PosSegPtoVirg > PosMaiorMaior then
                  PosSegPtoVirg := -1;
              end
              else
                PosSegPtoVirg := -1;
            end
            else
              PosPrimPtoVirg := -1;
          end
          else
            PosPrimPtoVirg := -1;
        end;

        //Se encontrou o sinal e os dois ";" então verifica se o nome do campo existe.

        if (PosSinal <> -1) and (PosPrimPtoVirg <> -1) and (PosSegPtoVirg <> -1) then
        begin
          Campo := RVGetTextRange(rveTexto, PosInicioSe + 5, PosSinal - PosInicioSe - 5);
          ValorCondicao := RVGetTextRange(rveTexto, PosSinal + 1, PosPrimPtoVirg - PosSinal - 1);
          TextoIfTrue := RVGetTextRange(rveTexto, PosPrimPtoVirg + 1, PosSegPtoVirg - PosPrimPtoVirg - 1);
          TextoIfFalse := RVGetTextRange(rveTexto, PosSegPtoVirg + 1, PosMaiorMaior - PosSegPtoVirg - 1);

          if Assigned(GetCampoViewFunc) then
            Campo := GetCampoViewFunc(Campo);

          if IsCampoFunc(Campo, Tipo) then
          begin
            RVSetSelection(rveTexto, PosInicioSe, (PosMaiorMaior - PosInicioSe) + 2);

            if ((sinal = tsIgual) and (GetValorCampoFunc(Campo).Trim.ToUpper = ValorCondicao.Trim.ToUpper)) or
               ((sinal = tsDiferente) and (GetValorCampoFunc(Campo).Trim.ToUpper <> ValorCondicao.Trim.ToUpper)) then
              rveTexto.InsertText(TextoIfTrue) // -> Error here
            else
              rveTexto.InsertText(TextoIfFalse); // -> Or error here
          end
          else
            TrocaSePorTemp;
        end
        else
          TrocaSePorTemp;
      end;
    end;

    GoToBeginTexto(rveTexto);
    while rveTexto.SearchText(TEMP_TEXT, [rvseoDown]) do
      rveTexto.InsertText('<<SE ');
  finally
    rveTexto.EndUpdate;
  end;
end;
somthing is wrong this code ?

Thanks alot.

Posted: Mon Mar 17, 2014 10:32 am
by Sergey Tkachenko
Sorry, this code is too complicated to find the bug in a browser.
Can you send me a code that I can compile (as simple as possible?)

Posted: Mon Mar 17, 2014 11:22 am
by rafakwolf
Hello, it's complicated to send an example for you...but after alot debugging i found a "solution" for this issue...

i do not konwn if this is correct, but you can tel me..

in CRVData

Code: Select all

function TCustomRVData.GetItem(ItemNo: Integer): TCustomRVItemInfo;
begin
//======================
  if ItemNo >= Items.Count then
    ItemNo := (Items.Count-1); 
//=====================

  Result := TCustomRVItemInfo(Items.Objects[ItemNo]); //--> List index out of bounds 
end;
That way works to me, this is correct ?

Thanks for now

Posted: Mon Mar 17, 2014 12:19 pm
by Sergey Tkachenko
This change only allows hiding errors in your code.
You must not access items outside of the range 0..ItemCount-1