Ir al contenido


Foto

[RESUELTO] List index out of bounds(-1) event onClickCheck CheckListBox?


  • Por favor identifícate para responder
9 respuestas en este tema

#1 adriano_servitec

adriano_servitec

    Advanced Member

  • Miembros
  • PipPipPip
  • 91 mensajes
  • LocationCuritiba-Pr - Brasil

Escrito 13 diciembre 2010 - 06:33

Buenos amigos, tengo un pequeño problema cuando trato de hacer clic en el event onClickCheck CheckListBox

El código es este


delphi
  1. iTributo := ObtenhaCodigoTributo(ChkLstBox.Items.Strings[ChkLstBox.ItemIndex]);
  2.   try
  3.     //Icms
  4.     if (iTributo = _iTributoICMS) and (ChkLstBox.Checked[ChkLstBox.ItemIndex]) then
  5.       ChamaFormularioICMS;
  6.     //Simples Nacional
  7.     if (iTributo = _iTributoSN) and (ChkLstBox.Checked[ChkLstBox.ItemIndex]) then
  8.       TfrmRelCalculoSimplesNacional.Run(edtMesAno.Text, Self);
  9.   finally
  10.     iTributo := 0;
  11.   end;



Más después del primer clic, funciona, esto sólo sucede por primera vez.
Espero que entiendas
Gracias


  • 0

#2 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.295 mensajes
  • LocationArgentina

Escrito 13 diciembre 2010 - 06:40

Hola adriano_servitec,
Tendríamos que ver con mayor profundidad ese procedimiento que realizas antes del try y las condiciones iniciales antes de que se de el click.

Muy posiblemente el error se deba a que inicialmente, por defecto, la propiedad ItemIndex del TCheckListBox tiene un valor -1 que indica que no hay elemento seleccionado o un item "activo".

Al no haber uno, de allí que al intentar evaluar o acceder a la posición ItemIndex se obtiene un error como el que indicas ya que no hay posición o índice -1.  ;)

La solución pasaría por establecer por defecto un índice válido o hacer una evaluación previa para determinar si el índice es válido (un if).

Saludos,

  • 0

#3 adriano_servitec

adriano_servitec

    Advanced Member

  • Miembros
  • PipPipPip
  • 91 mensajes
  • LocationCuritiba-Pr - Brasil

Escrito 13 diciembre 2010 - 06:50

Hola Delhius,

La solución pasaría por establecer por defecto un índice válido o hacer una evaluación previa para determinar si el índice es válido (un if).


Por default, este debe venir con CheckListBox ItemIndex -1.

El tratamiento sólo debe ocurrir cuando se hace click en el elemento seleccionado.

Si juego en un bucle para las del lazo (FOR), mayor que tengo con la condición de que siempre debe llamar a la FORM ira innecesariamente.

Esta parte del código aquí



delphi
  1. if (iTributo = _iTributoICMS) and (ChkLstBox.Checked[ChkLstBox.ItemIndex]) then



Necesidad de comparar las variables son iguales, y haga clic en el esitver seleccionado para abrir la otra form.

Si no jugar en el Índice de la Lista A de error para la digitalización de LOOP.


Más perciben comprobado el estado del elemento seleccionado, se abrirá el formulario cada vez que el paso LOOP. No es factible también.  Ouvir Ler foneticamente 


Es cod complet..


delphi
  1. procedure TfrmRelMemoriaCalculo.AbreFormularioExterno(ChkLstBox: TCRDCheckListBox);
  2. var
  3.   iTributo: Integer;
  4. //***************************************************
  5.   //Chama o form do ICMS
  6.   procedure ChamaFormularioICMS;
  7.   begin
  8.     frmPrincipal.MostraFormApuracaoICMS(
  9.     frmPrincipal.miLivroApuracaoICMS,
  10.     TCustomForm(Self),
  11.     StrToIntDef(Config.EnterpriseID, 0),
  12.     StrToIntDef(CRDEmpresa.Value,0),
  13.     edtMesAno.Text,
  14.     edtMesAno.Text);
  15.   end;
  16. //***************************************************
  17. begin
  18.   iTributo := ObtenhaCodigoTributo(ChkLstBox.Items.Strings[ChkLstBox.ItemIndex]);
  19.   try
  20.     //Icms
  21.     if (iTributo = _iTributoICMS) and (ChkLstBox.Checked[ChkLstBox.ItemIndex]) then
  22.       ChamaFormularioICMS;
  23.     //Simples Nacional
  24.     if (iTributo = _iTributoSN) and (ChkLstBox.Checked[ChkLstBox.ItemIndex]) then
  25.       TfrmRelCalculoSimplesNacional.Run(edtMesAno.Text, Self);
  26.   finally
  27.     iTributo := 0;
  28.   end;
  29. end;



chamar assi


delphi
  1. procedure TfrmRelMemoriaCalculo.chklistTributoClickCheck(Sender: TObject);
  2. begin
  3.   inherited;
  4.   AbreFormularioExterno(chklistTributo);
  5. end;

Espero que entiendas  :smiley:

Gracias.

  • 0

#4 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.295 mensajes
  • LocationArgentina

Escrito 13 diciembre 2010 - 07:17

Hola adriano_servitec,

La verdad es que no comprendí demasiado lo que buscas hacer  :( Se que haces un esfuerzo enorme por escribir español, y por explicarte pero esta vez me he mareado. No puedo pedirte que te esfuerces más en expresarte mejor puesto que ya es dificultoso para ti.

Hablas de un ciclo (loop) pero no veo en el código un ciclo. Lo que si he notado de tu código es que tu CheckListBox no es "original", se trata de uno de terceros o personalizado... por lo que se lee TCRDCheckListBox. Desconozco a ese componente... ¿Puede existir la posibilidad de este componente tenga algún defecto o bug?

Prueba añadiendo unos breakpoints y haciendo una traza o seguimiento a tu código para ver en que línea de código está el problema.

Saludos,

  • 0

#5 adriano_servitec

adriano_servitec

    Advanced Member

  • Miembros
  • PipPipPip
  • 91 mensajes
  • LocationCuritiba-Pr - Brasil

Escrito 13 diciembre 2010 - 07:23

Lamento no ser capaz de expresar mejor lo que necesito amigo.

Voy a reemplazar el componente por nativos de Delphi y ver si funciona ...

Puede que no sea el problema de traductor de google, pero el uso coloquial en la vida cotidiana lo que hace difícil de entender.    Entonces vuelvo aquí para enviar el resultado.

Saludos ... Adriano.
  • 0

#6 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.295 mensajes
  • LocationArgentina

Escrito 13 diciembre 2010 - 07:40

NO debes sentirte mal por no poderte expresar mejor. Se que tu no eres el problema, el problema es el traductor de Google.

Yo diría que primero hicieras un seguimiento a tu código poniendo unos breakpoints para ver en que línea efectivamente está el problema.

Si puedo asegurarte de que al menos con un CheckListBox normal la lectura del ItemIndex en un OnClick no tiene problemas de índice. Este ejemplo lo demuestra:



delphi
  1. procedure TForm1.CheckListBox1Click(Sender: TObject);
  2. var indice: Integer;
  3. begin
  4.   indice := CheckListBox1.ItemIndex;
  5.   Label1.Caption := CheckListBox1.Items[indice];
  6. end;



Y funciona bien aún forzando a que en su propiedad ItemIndex sea -1:



delphi
  1. procedure TForm1.FormCreate(Sender: TObject);
  2. begin
  3.   CheckListBox1.ItemIndex := -1;
  4. end;



Por otro lado puedo reproducir el error que dices haciendo algo como esto:



delphi
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. begin
  3.   CheckListBox1.ItemIndex := -1;
  4.   Label1.Caption := CheckListBox1.Items[CheckListBox1.ItemIndex];
  5. end;



La excepción correspondiente es:

---------------------------
Debugger Exception Notification
---------------------------
Project Project1.exe raised exception class EStringListError with message 'List index out of bounds (-1)'. Process stopped. Use Step or Run to continue.
---------------------------
OK  Help 
---------------------------

Puede que se trate de un bug en el componente... como quizá existe la posibilidad de que en algún momento de tu código se altera el valor de ItemIndex a -1.

Lo que si es evidente es que el problema se trata de una lectura a una posición inválida.

Saludos,
  • 0

#7 adriano_servitec

adriano_servitec

    Advanced Member

  • Miembros
  • PipPipPip
  • 91 mensajes
  • LocationCuritiba-Pr - Brasil

Escrito 13 diciembre 2010 - 07:52

Holla Delphius,
    Con el nativo ni el derecho.

Yo tenía una idea, no dar el error de -1, sólo contando el total de la lista con el count = 8.

¡Ay de los errores en List.Bounds (8) cuando el checkd es False

Aquí está el código 


delphi
  1. procedure TfrmRelMemoriaCalculo.AbreFormularioExterno(ChkLstBox: TCRDCheckListBox);
  2. var
  3.   i, iTributo: Integer;
  4. //***************************************************
  5.   //Chama o form do ICMS
  6.   procedure ChamaFormularioICMS;
  7.   begin
  8.     frmPrincipal.MostraFormApuracaoICMS(
  9.     frmPrincipal.miLivroApuracaoICMS,
  10.     TCustomForm(Self),
  11.     StrToIntDef(Config.EnterpriseID, 0),
  12.     StrToIntDef(CRDEmpresa.Value,0),
  13.     edtMesAno.Text,
  14.     edtMesAno.Text);
  15.   end;
  16. //***************************************************
  17. begin
  18.   for i := 0 to ChkLstBox.Items.Count - 1 do
  19.   begin
  20.     ChkLstBox.Items;
  21.     if ChkLstBox.Checked then
  22.       Break;
  23.   end;
  24.   iTributo := ObtenhaCodigoTributo(ChkLstBox.Items.Strings);
  25.   try
  26.     //Icms
  27.     if (iTributo = _iTributoICMS) and (ChkLstBox.Checked) then
  28.       ChamaFormularioICMS;
  29.     //Simples Nacional
  30.     if (iTributo = _iTributoSN) and (ChkLstBox.Checked) then
  31.       TfrmRelCalculoSimplesNacional.Run(edtMesAno.Text, Self);
  32.   finally
  33.     iTributo := 0;
  34.   end;
  35. end;


[/]
Así también no funcionó  :sad:


delphi
  1. procedure TfrmRelMemoriaCalculo.AbreFormularioExterno(ChkLstBox: TCRDCheckListBox);
  2. var
  3.   i, iTributo: Integer;
  4. //***************************************************
  5.   //Chama o form do ICMS
  6.   procedure ChamaFormularioICMS;
  7.   begin
  8.     frmPrincipal.MostraFormApuracaoICMS(
  9.     frmPrincipal.miLivroApuracaoICMS,
  10.     TCustomForm(Self),
  11.     StrToIntDef(Config.EnterpriseID, 0),
  12.     StrToIntDef(CRDEmpresa.Value,0),
  13.     edtMesAno.Text,
  14.     edtMesAno.Text);
  15.   end;
  16. //***************************************************
  17. begin
  18.   for i := 0 to ChkLstBox.Items.Count -1 do
  19.   begin
  20.     ChkLstBox.Items;
  21.     if ChkLstBox.Checked then
  22.       Break;
  23.   end;
  24.   if i < ChkLstBox.Items.Count  then
  25.   begin
  26.     iTributo := ObtenhaCodigoTributo(ChkLstBox.Items.Strings);
  27.     try
  28.       //Icms
  29.       if (iTributo = _iTributoICMS) and (ChkLstBox.Checked) then
  30.         ChamaFormularioICMS;
  31.       //Simples Nacional
  32.       if (iTributo = _iTributoSN) and (ChkLstBox.Checked) then
  33.         TfrmRelCalculoSimplesNacional.Run(edtMesAno.Text, Self);
  34.     finally
  35.       iTributo := 0;
  36.     end;
  37.   end;
  38. end;



Es imposible hacerlo FOR


delphi
  1. for i := 0 to ChkLstBox.Items.Count -1 do
  2.   begin
  3.     ChkLstBox.Items;
  4.     if ChkLstBox.Checked then
  5.       Break; <=== siempre cai 1º
  6.   end;



Not funcionó assi tambiem  :sad:


delphi
  1. procedure TfrmRelMemoriaCalculo.AbreFormularioExterno(ChkLstBox: TCRDCheckListBox);
  2. var
  3.   i, iTributo: Integer;
  4. //***************************************************
  5.   //Chama o form do ICMS
  6.   procedure ChamaFormularioICMS;
  7.   begin
  8.     frmPrincipal.MostraFormApuracaoICMS(
  9.     frmPrincipal.miLivroApuracaoICMS,
  10.     TCustomForm(Self),
  11.     StrToIntDef(Config.EnterpriseID, 0),
  12.     StrToIntDef(CRDEmpresa.Value,0),
  13.     edtMesAno.Text,
  14.     edtMesAno.Text);
  15.   end;
  16. //***************************************************
  17. begin
  18.   for i := 0 to ChkLstBox.Items.Count -1 do
  19.   begin
  20.     ChkLstBox.Items[i];
  21.     iTributo := ObtenhaCodigoTributo(ChkLstBox.Items.Strings[i]);
  22.     if (iTributo = _iTributoICMS) and (ChkLstBox.Checked[i]) then //Not functionó
  23.       Break;
  24.   end;
  25.   if i < ChkLstBox.Items.Count  then
  26.   begin
  27.     iTributo := ObtenhaCodigoTributo(ChkLstBox.Items.Strings[i]);
  28.     try
  29.       //Icms
  30.       if (iTributo = _iTributoICMS) and (ChkLstBox.Checked[i]) then
  31.         ChamaFormularioICMS;
  32.       //Simples Nacional
  33.       if (iTributo = _iTributoSN) and (ChkLstBox.Checked[i]) then
  34.         TfrmRelCalculoSimplesNacional.Run(edtMesAno.Text, Self);
  35.     finally
  36.       iTributo := 0;
  37.     end;
  38.   end;
  39. end;


  • 0

#8 adriano_servitec

adriano_servitec

    Advanced Member

  • Miembros
  • PipPipPip
  • 91 mensajes
  • LocationCuritiba-Pr - Brasil

Escrito 13 diciembre 2010 - 11:09

NO debes sentirte mal por no poderte expresar mejor. Se que tu no eres el problema, el problema es el traductor de Google.

Yo diría que primero hicieras un seguimiento a tu código poniendo unos breakpoints para ver en que línea efectivamente está el problema.

Si puedo asegurarte de que al menos con un CheckListBox normal la lectura del ItemIndex en un OnClick no tiene problemas de índice. Este ejemplo lo demuestra:



delphi
  1. procedure TForm1.CheckListBox1Click(Sender: TObject);
  2. var indice: Integer;
  3. begin
  4.   indice := CheckListBox1.ItemIndex;
  5.   Label1.Caption := CheckListBox1.Items[indice];
  6. end;



Y funciona bien aún forzando a que en su propiedad ItemIndex sea -1:



delphi
  1. procedure TForm1.FormCreate(Sender: TObject);
  2. begin
  3.   CheckListBox1.ItemIndex := -1;
  4. end;



Por otro lado puedo reproducir el error que dices haciendo algo como esto:



delphi
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. begin
  3.   CheckListBox1.ItemIndex := -1;
  4.   Label1.Caption := CheckListBox1.Items[CheckListBox1.ItemIndex];
  5. end;



La excepción correspondiente es:

---------------------------
Debugger Exception Notification
---------------------------
Project Project1.exe raised exception class EStringListError with message 'List index out of bounds (-1)'. Process stopped. Use Step or Run to continue.
---------------------------
OK  Help 
---------------------------

Puede que se trate de un bug en el componente... como quizá existe la posibilidad de que en algún momento de tu código se altera el valor de ItemIndex a -1.

Lo que si es evidente es que el problema se trata de una lectura a una posición inválida.

Saludos,

Holla Delphius, sí usa-lo code arriba not puedes usa-lo este code  :sad:

no events DrawItem do CheckListBox


delphi
  1. procedure TfrmRelMemoriaCalculo.chklistTributoDrawItem(Control: TWinControl; Index: Integer; Rect: TRect;
  2.   State: TOwnerDrawState);
  3. begin
  4.   inherited;
  5.   //
  6.   with TCRDCheckListBox(Control).Canvas do
  7.   begin
  8.     try
  9.       Brush.Color := TCRDCheckListBox(Control).Color;
  10.       FillRect(Rect);
  11.       if odSelected in State then
  12.       begin
  13.         //Apenas se quiser deixar a barra de indicação do texto ativa
  14.         Brush.Color := clHighLight;
  15.         Font.Color := clHighLightText;
  16.         //Se não quiser a barra de indicação de texto ativa então deixar desta forma
  17.         //Font.Color := clBlack;
  18.       end
  19.       else
  20.         Font.Color := TCRDCheckListBox(Control).Font.Color;
  21.         with Rect do
  22.           TextOut(Left + 4, (Top + Bottom - TextHeight('Texto')) div 2,
  23.                 TCRDCheckListBox(Control).Items[Index]);
  24.     finally //Deixei num bloco protegido para ter certeza que sempre executará esta instrução abaixo
  25.       //Verifica se o controle do checklistbox esta em foco para acionar o abort.
  26.       if TCRDCheckListBox(Control).Focused then
  27.         Abort;
  28.     end;
  29.   end;
  30.   //
  31. end;


  • 0

#9 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.295 mensajes
  • LocationArgentina

Escrito 13 diciembre 2010 - 11:36

Hola adriano_servite,
Al componente que utilizas no lo conozco, por lo que no sabría decirte mucho. Sólo puedo estimar o divagar sobre su funcionamiento teniendo como base al TCheckListBox original.

El código que yo expuse es una muestra simple y elemental de como se comporta el TCheckListBox en su evento OnClick para determinar si es posible conseguir una excepción de fuera de rango como el error. Si pruebas en un proyecto nuevo en limpio el código que expuse notarás que no hay modo que se consiga el error.

La única manera de reproducir el error es alternar, intencionalmente o sin percatarse de ello, el valor de ItemIndex por código, como lo ejemplifiqué en el ejemplo del botón cuando lo fuerzo a que su valor sea -1 y luego intentar acceder a esa posición.

Hay algo en tu código que provoca esa excepción, por ello te había indicado que probaras añadiendo breakpoints y realizando un seguimiento hasta llegar a la línea conflictiva. Ve paso a paso.

Tienes una mezcla de código que dificulta entender el verdadero problema... No se vé en ese código alguna alteración de ItemIndex, Intencional o no, y es posible que el error venga arrastrado desde otro lado.

¿Eso no es todo el código verdad? ¿MostraFormApuracaoICMS es un procedimiento, que hace? ¿Qué es miLivroApuracaoICMS, Config,CRDEmpresa que se ven en el procedimiento ChamaFormularioICMS?

Cuando hablas de que es imposible hacerlo con un FOR pones este código:


delphi
  1. for i := 0 to ChkLstBox.Items.Count -1 do
  2.   begin
  3.     ChkLstBox.Items;
  4.     if ChkLstBox.Checked then
  5.       Break; <=== siempre cai 1º
  6.   end;



¿Que es es ChkLstBox.Items? Se me hace que está fuera de lugar.

Veo demasiados procedimientos fuertemente vinculados y se hace que en parte hay un error de diseño... Algo me dice que lo estás complicando demasiado y se podría conseguir un código más limpio.... procedimientos que llaman a un form, o que crea un form... pasas datos de un form a otro... y eso dificulta entender lo que buscas hacer.

No es mi intención decirte que tu código está mal, pero si me lo permites quisiera decirte que me llama demasiado la atención la manera en como lo estás encarando.

No se que de todo ese código esta mal... hay cosas que no entiendo que significan o que hacen (o deberían hacer). Se que puede parecer pesado y quizá sea un exceso de mi parte si te pido que nos expliques el objetivo de tu código... habría que analizarlo de arriba hacia abajo y ver que es lo que está pasando.

Saludos,

  • 0

#10 adriano_servitec

adriano_servitec

    Advanced Member

  • Miembros
  • PipPipPip
  • 91 mensajes
  • LocationCuritiba-Pr - Brasil

Escrito 13 diciembre 2010 - 12:16

Hola Delphius,

Me da vergüenza decirle a sus amigos que esto era todo lo que estaba dentro de un GroupBox CheckListBox.

Sé que el código era difícil entender por qué utilizar los métodos de clase para crear diferentes metodologías, en lugar de poner todo el código aquí se confunde ...[/]

a solucion és simples..veja[/]


delphi
  1. procedure TfrmRelMemoriaCalculo.AbreFormularioExterno(ChkLstBox: TCRDCheckListBox);
  2. var
  3.   iTributo: Integer;
  4. //***************************************************
  5.   //Chama o form do ICMS
  6.   procedure ChamaFormularioICMS;
  7.   begin
  8.     frmPrincipal.MostraFormApuracaoICMS(
  9.     frmPrincipal.miLivroApuracaoICMS,
  10.     TCustomForm(Self),
  11.     StrToIntDef(Config.EnterpriseID, 0),
  12.     StrToIntDef(CRDEmpresa.Value,0),
  13.     edtMesAno.Text,
  14.     edtMesAno.Text);
  15.   end;
  16. //***************************************************
  17. begin
  18.   iTributo := ObtenhaCodigoTributo(ChkLstBox.Items.Strings[ChkLstBox.ItemIndex]);
  19.   try
  20.     //Icms
  21.     if (iTributo = _iTributoICMS) and (ChkLstBox.Checked[ChkLstBox.ItemIndex]) then
  22.       ChamaFormularioICMS;
  23.     //Simples Nacional
  24.     if (iTributo = _iTributoSN) and (ChkLstBox.Checked[ChkLstBox.ItemIndex]) then
  25.       TfrmRelCalculoSimplesNacional.Run(edtMesAno.Text, Self);
  26.   finally
  27.     iTributo := 0;
  28.   end;
  29. end;

Como disse o problem estava en parent GroupBox.[/]


Ahora bien, este trabajo .... resuelto

Gracias amigo.
  • 0




IP.Board spam blocked by CleanTalk.