Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   OOP (https://www.clubdelphi.com/foros/forumdisplay.php?f=5)
-   -   Seleccion de item en combobox da error list index out of bonds (https://www.clubdelphi.com/foros/showthread.php?t=83042)

jafera 06-05-2013 14:15:11

Seleccion de item en combobox da error list index out of bonds
 
Buenas a todos.

Pues como he puesto en el título, cuando selecciono un item del combobox si la columna [15] del grid está en visible :=false, me da el error.

Código Delphi [-]
procedure TF_Pagues.DBLookupComboBox1Exit(Sender: TObject);
begin
        If DBEdit3.Text='0' then
        begin
                JvDBUltimGrid1.Columns[15].Visible:=False;      // Aquí es donde da el error del list index out of bounds ya que si
                                                                               // en el mecanico anterior el visible de la columna es false, no la
                                                                               // encuentra y marca el error                 
                DBEdit3.Font.Color:=clBlack;
                DBEdit3.Color:=clWindow;
        end
        else
        begin
                JvDBUltimGrid1.Columns[15].Visible:=True;
                DBEdit3.Font.Color:=clRed;
                DBEdit3.Color:=clYellow;
        end;
end;

No se como puedo controlar la "visibilidad" de la columna [15] para que no de este error.
Si alguien tiene una idea o se ha encontrado con lo mismo.......

Gracias por adelantado

Josep

Casimiro Notevi 06-05-2013 14:21:13

Recuerda poner los tags al código fuente, ejemplo:



Gracias :)

jafera 06-05-2013 14:35:16

No los he puesto?

Es que he tenido que editar el mensaje un par de veces y posiblemente lo has visto mientras estaba en el chapista

Saludos

javier7ar 06-05-2013 16:06:24

"index out of bonds" da porque quiere acceder a una posicion de un array/lista que no existe, generalmente cuando te pasas del tamaño del array/lista.
Recorda que los indices en esas estructuras que heredan de TList o TCollection suelen ir de 0 a (Count -1), asi que si tenes 15 columnas, van de 0 a 14, quizas le estas errando en eso
Saludos

Casimiro Notevi 06-05-2013 16:15:28

Cita:

Empezado por jafera (Mensaje 459861)
No los he puesto? Es que he tenido que editar el mensaje un par de veces y posiblemente lo has visto mientras estaba en el chapista Saludos

^\||/^\||/^\||/

jafera 06-05-2013 16:37:41

Gracias por la respuesta.

Efectivamente las columnas van de 0 a 15 i mi columna es la 15 no la catorce.

Resumiendo que el problema es que no encuentra la columna porque su propiedad visible es false cuando cambio de registro, en el primer registro si visible es false o true funciona perfectamente.

Luego cambio de operario en un combobox y la propiedad visible sigue siendo false y aquí es dónde hace el out of bound[15]

Saludos

Josep

jafera 06-05-2013 16:42:51

Casimiro, acepto tu "tironcillo de orejas" :mad::mad: y sus correspondientes disculpas, jijiji. ^\||/^\||/

Intento en lo máximo cumplir las normas aunque hay una que es la del título descriptivo que creo nos cuesta bastante cumplir a todos.

Saludos

Josep

Casimiro Notevi 06-05-2013 18:05:27

1 Archivos Adjunto(s)
Cita:

Empezado por jafera (Mensaje 459873)
Intento en lo máximo cumplir las normas aunque hay una que es la del título descriptivo que creo nos cuesta bastante cumplir a todos.

je, je, je...

jafera 06-05-2013 18:20:58

Muy bueno el Bartolo Simpson, aunque yo me identifico más con su padre, donuts, donuts.....

Vamos a enderezar, que nos desviamos del tema y algun moderador nos va a reñir.

Saludos

ecfisa 06-05-2013 21:05:19

Cita:

Empezado por jafera (Mensaje 459858)
Buenas a todos.

Pues como he puesto en el título, cuando selecciono un item del combobox si la columna [15] del grid está en visible :=false, me da el error.

Código Delphi [-]
procedure TF_Pagues.DBLookupComboBox1Exit(Sender: TObject);
begin
  If DBEdit3.Text='0' then
  begin
    JvDBUltimGrid1.Columns[15].Visible:=False;  // Aquí es donde da el error del list index out of bounds ya que si
                                                // en el mecanico anterior el visible de la columna es false, no la
                                                // encuentra y marca el error                 
    DBEdit3.Font.Color:=clBlack;
    DBEdit3.Color:=clWindow;
  end
  else
  begin
    JvDBUltimGrid1.Columns[15].Visible:=True;
    DBEdit3.Font.Color:=clRed;
    DBEdit3.Color:=clYellow;
  end;
end;

No se como puedo controlar la "visibilidad" de la columna [15] para que no de este error.
Si alguien tiene una idea o se ha encontrado con lo mismo.......

Gracias por adelantado

Josep

Hola Josep.

No he usado los componentes Jedi, pero no pareciera tener sentido que exista esa relación entre la visibilidad y la existencia de la columna.

Segun entiendo de tu mensaje (y tal vez entendí mal), quiere decir que un código como este:
Código Delphi [-]
begin
  JvDBUltimGrid1.Columns[4].Visible := False;
  JvDBUltimGrid1.Columns[4].Visible := False;  // Error: La columna dejo de existir ??? :eek:
  ...
Lanzaría el error list index out of bounds en la tercer línea aún existiendo la columna 4, ¿ Entonces como se haría para volverla al estado visible ?

Saludos. :)

jafera 08-05-2013 12:46:42

Problema solucionado.

El problema no venia por el visible en false, venia porque en otro proceso destruía la columna en cuestión y evidentemente list index out of bounds.

Poco a poco iremos aprendiendo más cosillas los que nos dedicamos a esto en plan hobby, hay que darse de bruces con el suelo varias veces para saber que este está duro.

Gracias a todos y perdonad.

Josep

Al González 08-05-2013 15:01:56

Cita:

Empezado por jafera (Mensaje 460024)
Problema solucionado.

El problema no venia por el visible en false, venia porque en otro proceso destruía la columna en cuestión y evidentemente list index out of bounds.

¡Qué bien! Pero no estaría mal que explicaras con más detalle cómo es que ese otro proceso repercutía en el código que mostraste al principio. Puede servir a otros en alguna situación similar. :)

jafera 08-05-2013 17:26:11

Correcto Al.

En el DataModule tengo las tablas, pues bien en el after delete de la tabla que guarda las lineas del proceso tenia puesto esto:

Código Delphi [-]
If F_Pagues.DBEdit3.Text = '0' then 
begin 
  F_Pagues.JvDBUltimGrid1.Columns[15].Destroy; 
  L_PaguesDIA_BAIXA.Value:= 0; 
  F_Pagues.DBEdit3.Font.Color:=clBlack; 
  F_Pagues.DBEdit3.Color:=clWindow; 
end

y evidentemente la columna era destruida y era imposible hacera "invisible".

Saludos

Josep

Al González 08-05-2013 18:49:59

Comprendido. ^\||/

Aunque un módulo de datos no tiene por qué "ver" a la interfaz de usuario (sólo al revés). ;)

jafera 08-05-2013 19:52:13

Gracias Al.

Lo que yo decia, tengo que picar mucha piedra para sacar una pepita de oro.

Posiblemente tu comentario tiene su razón, cosa que desconocia por autodidacta pero siempre he hecho cosas así, de mandar desde el datamodule instrucciones al formulario.

Intentaré no mezclar interfaces en un futuro.

Repito gracias por el comentario, quiero ser el "mejor programador novato de delphi"

Saludos

Josep

ecfisa 08-05-2013 21:31:26

Cita:

Empezado por jafera (Mensaje 460049)
...
Posiblemente tu comentario tiene su razón, cosa que desconocia por autodidacta pero siempre he hecho cosas así, de mandar desde el datamodule instrucciones al formulario.
...

Hola Josep.

Si que la tiene...:)

Un modo de utilizar los eventos de los componentes que residen en tu TDataModule sin que este "vea" al form es definir los métodos dentro de él.

Ajustando el ejemplo a tu último código, sería:
Código Delphi [-]
...
type
  TDataSetEvent = procedure(DataSet: TDataSet) of object;
  TtuForm = class(TForm)
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
    ...
    procedure FormDestroy(Sender: TObject);
  private
    FOldEvent : TDataSetEvent;
    procedure DataSetAfterDelete(DataSet: TDataSet);
  public
  end; 
...

implementation

uses u_TuDataModule;

procedure TTuForm.DataSetAfterDelete(aDataSet: TDataSet);
begin
  JvDBUltimGrid1.Columns[15].Visible := False;
  tuDataModule.L_PaguesDIA_BAIXA.Value:= 0; // supongo que pertenece al datamodule...
  DBEdit3.Font.Color:=clBlack;
  DBEdit3.Color:=clWindow;
end;

procedure TFTuFormFormCreate(Sender: TObject);
begin
   // (En este punto supongo al DataModule ya creado)
  
  // Si ya hay asignado un método, resguardarlo
  if Assigned(tuDataModule.DataSet.AfterDelete) then
    FOldEvent := tuDataModule.DataSet.AfterDelete;

  // Asignar el nuevo método 
  tuDataModule.DataSet.AfterDelete := DataSetAfterDelete;
  tuDataModule.DataSet.Open
end;

...

procedure TTuForm.FormDestroy(Sender: TObject);
begin
  // Restaurar el evento a su condición anterior
  if Assigned(FOldEvent) then
    tuDataModule.DataSet.AfterDelete := FOldEvent;
end;
end.

Saludos :)

Al González 09-05-2013 00:01:59

Cita:

Empezado por ecfisa (Mensaje 460059)
Un modo de utilizar los eventos de los componentes que residen en tu TDataModule sin que este "vea" al form es definir los métodos dentro de él.

Ajustando el ejemplo a tu último código, sería...

Muy bien explicado, ecfisa. :)

Que es, permitiéndome un poco de "publicidad", similar a lo que hace la propiedad DataSetEvents del DataSource extendido:
Cita:

Empezado por Al González (Mensaje 459475)
Deriva del típico TDataSource que viene de fábrica, usado cotidianamente en la mayoría de las aplicaciones, sólo que añade dos útiles propiedades:
  • DataSetCloned — Para crear en tiempo de ejecución un "clon" del DataSet asignado. Uno o más formularios pueden trabajar y hacer lo que sea con sus respectivos DataSet clones, sin tocar el DataSet original. Nada de lo que haga un formulario con el DataSet interferirá con el buen funcionamiento de otros formularios que usen el mismo DataSet (porque cada formulario usa en realidad una copia).
  • DataSetEvents — Para trabajar con los eventos del DataSet asignado, pero en el "ámbito" del componente. El DataSet puesto en un módulo de datos, mientras que dentro de un formulario y unidad aparte un componente TghDataSource le establece manejadores de eventos BeforeXXX y AfterXXX que son ejecutados sólo con ese formulario (eventos del DataSet particulares por formulario).

Estas dos propiedades son independientes (puede usarse DataSetEvents sin clonar el conjunto de datos). Con la ventaja de que el componente hace todo el trabajo sucio. Enlace y rústico video.

Saludos.

Casimiro Notevi 09-05-2013 00:14:11

Vaya nivelazo que tienen ecfisa y Al :eek:

jafera 09-05-2013 10:21:54

SEÑORES, si, si con mayusculas, he quedado anonadado:eek:, aturdido:eek:, embelesado^\||/ etc., etc., etc. por los conocimientosqP:-) y el nivelazo como dice Casimiro.v:-)vv:-)vv:-)v

Da gusto pertenecer a este foro por la calidad con que muchos de vosotros os expresais e intentais hacernos ver claro lo oscuro de la programación.^\||/^\||/^\||/

Muchas veces os pongo preguntas que para vosotros pueden ser banales y llanas pero a mi muchas veces se me hacen una montaña ya que como comenté en algun post anterior yo solo hago esto como hobby.

He tomado buena nota de todo y voy a intentar separar al máximo la programación de los forms y del datamodule en un futuro.

Repito otra y otra y otra vez

GRACIAS (no estoy gritando, es admiración)

Saludos

Josep


La franja horaria es GMT +2. Ahora son las 13:34:31.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi