PDA

Ver la Versión Completa : TComboBox carga lo que quiere


Panasys
02-10-2013, 23:07:24
Bueno, me pasa algo con un TComboBox que no me pasa en otras partes del programa pero en particular esta es que en una parte del programa cargo un pasajero el cual tiene un pais, al TComboBox lo cargo desde una tabla donde tengo los paises.

con:

FData.QAux2.SQL.Clear;
FData.QAux2.SQL.Add('Select * From tpais');
FData.QAux2.Open;

// CARGO EL CAMPO DE PAIS
ModificaPais.Clear;
ModificaPais.Items.Add('Seleccione Pais'); //Este lo agrego para que me ocupe el 0 en el ComboBox
y mantenga concordancia con la tabla
FData.QAux2.First;
While Not FData.QAux2.Eof Do // Realizar mientras no sea fin de archivo
Begin
ModificaPais.Items.Add(FData.QAux2.FieldByName('PAIS').Value);
FData.QAux2.Next;
End;
//ModificaPais.Text := FData.QAux.FieldByName('PAIS').Value;
ModificaPais.ItemIndex := PaisID; // - 1;

Casimiro Notevi
02-10-2013, 23:38:31
Recuerda poner los tags al código fuente, ejemplo:

http://www.clubdelphi.com/images/UtilizarTAGs.png

Gracias :)

Pericles
03-10-2013, 00:07:23
Hola, no me queda claro el final de lo que haces en tu codigo ni el error propiamente dicho...

Aparentemente esta bien la carga del combo.. recorres el dataset y vas agregando elementos al combo(a partir del 1).
Luego queres asignar al pasajero el nuevo pais utilizando la referencia del itemIndex del combo= idTablaPaises??

eso no deberia dar problemas.. cual es el error puntual?


Yo haria una nueva consulta para obtener el Id del elemento y luego hacer el update del pasajero y ese nuevo pais selecccionado.
(ya que se puede agregar otro elemento o cambiar el nro de ids en la base y quede diferencia entre el index y el id de la tabla, generando errores futuros...)

ej:

combo
0 Seleccione pais
1 Arg
2 Bol
3 Can

y la tabla
1 Arg
2 Bol
4 Per

(si es seguro que no habra modificaciones podria llegar a ser.. )

Saludos

Nicolas Perichon

ecfisa
03-10-2013, 00:33:06
Hola Panasys.

A mi tampoco me queda del todo claro que estas buscando hacer... pero a ver si esto te sirve:


...
procedure TForm1.FormCreate(Sender: TObject);
begin
FData.QAux2.SQL.Clear;
FData.QAux2.SQL.Add('Select * From tpais');
FData.QAux2.Open;
with ModificaPais do
begin
Clear;
AddItem('Seleccione Pais', TObject(Integer(0)));
while not FData.QAux2.Eof do
begin
AddItem(FData.QAux2.FieldByName('PAIS').AsString,
TObject(Integer(FData.QAux2.FieldByName('PaisID').AsInteger)));
FData.QAux2.Next;
end;
ItemIndex := 0;
end;
end;

// Ejemplo de uso
procedure TForm1.ModificaPaisChange(Sender: TObject);
begin
with ModificaPais do
if Integer(Items.Objects[ItemIndex]) = 0 then
ShowMessage('¿ No sabe leer ? ¡ Seleccione un país !');
end;

...


Saludos :)

Panasys
03-10-2013, 02:04:05
PRIMERO PERDON POR EL POST, PASA QUE PRESIONE POR ACCIDENTE EL ENTER Y SE POSTEO EN CRUDO Y SIN COMPLETAR

Bueno, me pasa algo con un TComboBox que no me pasa en otras partes del programa pero en particular en esta parte del programa cargo un pasajero el cual tiene un pais, al TComboBox lo cargo desde una tabla donde tengo los paises.

con:

FData.QAux2.SQL.Clear;
FData.QAux2.SQL.Add('Select * From tpais');
FData.QAux2.Open;

// CARGO EL CAMPO DE PAIS
ModificaPais.Clear;
ModificaPais.Items.Add('Seleccione Pais'); //Este lo agrego para que me ocupe el 0 en el ComboBox
//y mantenga concordancia con la tabla
FData.QAux2.First;
While Not FData.QAux2.Eof Do // Realizar mientras no sea fin de archivo
Begin
ModificaPais.Items.Add(FData.QAux2.FieldByName('PAIS').Value);
FData.QAux2.Next;
End;
ModificaPais.ItemIndex := PaisID;

Bueno eso lo hace cuando hago click en una grilla de pasajeros, si el pasajero tiene un ID de pais dentro de los primeros 50 paises funciona todo ok, ahora cuando el ID pertenece a algun pais por encima de los 100 al guardar los datos guardo tambien el ItemIndex del combo, pero me guarda cualquiera menos el que corresponde al pais.

Es mas si en la grilla hago click en un pasajero que su pais tiene un index, por ejem 208 el combo me muestra el pais 230.

A alguien le paso? es una cuestion de que no soporta tantos registros un combo? Problemas de memoria? o acceso a la misma? alguna idea?

Gracias y abrazo.

Javier

ecfisa
03-10-2013, 04:27:28
Hola Javier.

Acabo de probar el código que sigue (basicamente igual al anterior) con 20716 datos y devuelve correctamente el ID de cada paciente:

procedure TForm1.FormCreate(Sender: TObject);
begin
with IBQuery1 do
begin
Close;
SQL.Clear;
SQL.Text := 'SELECT ID, NOMBRE FROM PACIENTES ORDER BY ID';
Open;
ComboBox1.Items.Add('PRIMER ITEM');
while not Eof do
begin
ComboBox1.AddItem(FieldByName('NOMBRE').AsString,
TObject(FieldByName('ID').AsInteger));
Next;
end;
end;
end;

procedure TForm1.ComboBox1Change(Sender: TObject);
begin
with TComboBox(Sender) do
ShowMessage(Format('%s %d',
[Items[ItemIndex], Integer(Items.Objects[ItemIndex])]));
end;

Por lo tanto descarto cualquier problema con el TComboBox. (Ignoro la memoria que dispones).

¿ Estas seguro que el valor de la propiedad ItemIndex se corresponde con el valor del campo PaisID ?

Saludos :)

Panasys
03-10-2013, 15:56:51
Hola ecfisa !

Bien, colocando el codigo como tu dices, el mensaje me da el ID correcto de la base, pero el ItemIndex del TComboBox es distinto.

Es decir, que cuando yo hago click en el pasajero en la grilla el valor del ID del pais de ese pasajero, por ej 208 que es Suiza en mi tabla, yo lo traslado a

ComboBox.ItemIndex := 208

Que en el combo el 208 es Taiwan y Suiza esta en el 204!, pero el showmessage que vos agregaste para que me muestre el Index asignado esta OK y me dice 208!

Entonces el ItemIndex del combo no me sirve, no se porque no carga los paises como debe con el item correspondiente.

Yo quiero que el combo me muestre el pais porque justo es una ventana de modificacion de datos.

Hay otra manera de acceder a la lista del combo que no sea combo.itemindex := xxx? para ver el nombre del registro en el combo?

El codigo completo:

procedure TFModificaRol.GrillaRolPasajerosCellClick(Column: TColumn);
begin
PasajeroID := FData.QRolPasajeros.FieldByName('ID').Value;

FData.QAux.SQL.Clear;
FData.QAux.SQL.Add('Select t1.ID, t1.APELLIDO, t1.NOMBRE, t1.NACIONALIDAD, t2.PAIS, t1.DOCUMENTO, t1.RESIDENTE, t3.ID as ROL, t4.ID as SALIDA, t5.PASAJE, t5.ID as PASAJEID');
FData.QAux.SQL.Add('From tpasajero t1, tpais t2, trol t3, tsalidas t4, tpasajes t5');
FData.QAux.SQL.Add('Where t1.ID = "'+IntToStr(PasajeroID)+'" and t2.ID = t1.NACIONALIDAD and t3.ID = "'+IntToStr(RolID)+'" and t4.ID = t3.SALIDA and t5.PASAJERO = t1.ID');
FData.QAux.Open;

ModificaNombre.Text := FData.QAux.FieldByName('NOMBRE').Value;
ModificaApellido.Text := FData.QAux.FieldByName('APELLIDO').Value;
ModificaDocumento.Text := FData.QAux.FieldByName('DOCUMENTO').Value;
ModificaEdad.Text := FData.QAux.FieldByName('PASAJE').Value;

Nombre := FData.QAux.FieldByName('NOMBRE').Value +' '+ FData.QAux.FieldByName('APELLIDO').Value;

/////////////////////////////////////////////////////////////////////////////

PaisID := FData.QAux.FieldByName('NACIONALIDAD').Value;
PasajeID := FData.QAux.FieldByName('PASAJEID').Value;

FData.QAux2.SQL.Clear;
FData.QAux2.SQL.Add('Select * From tpais');
FData.QAux2.Open;

// CARGO EL CAMPO DE PAIS
ModificaPais.Clear;
ModificaPais.Items.Add('Seleccione Pais');
FData.QAux2.First;
While Not FData.QAux2.Eof Do // Realizar mientras no sea fin de archivo
Begin
ModificaPais..AddItem(FData.QAux2.FieldByName('PAIS').AsString, TObject(FData.QAux2.FieldByName('ID').AsInteger));
FData.QAux2.Next;
End;

ModificaPais.ItemIndex := PaisID;

/////////////////////////////////////////////////////////////////////////////

Label13.Caption := 'Grilla dice: '+IntToStr(PaisID)+' Combo dice: '+IntToStr(ComboBox1.ItemIndex);
end;

El resultado:

http://panasys.com.ar/errorCombo.jpg

No conozco una forma de llamar al ItemIndex desde el ID asociado como me lo mostraste vos, sino estaria solucionado creo :)

Gracias por las molestias !!! :D

Javier

Pericles
03-10-2013, 16:16:13
Hola, si me permites te aconsejo una forma de hacer lo que creo que necesitas de manera de olvidarte de errores futuros de diferencias de id-itemIndex...

Podrias leer la tabla de paises y guardarla en una lista (un stringListPor ejemplo, o un KeyValue 1=Argentina, 2=Jamaica etc...

Ahora la referencia tuya esta en la LISTA...

Posibles consultas:

1)cuando el cliente cambia el combo: al cambiar buscas en la lista el valor del ID para el texto actual, y tienes el id...
2)si quieres mostrar el pais de un determinado id, asignas al comboBox.text el pais que corresponde al id en la lista!

De esta manera tienes integridad de datos mas segura(siempre y cuando se refresque la base y se realimente la lista nuevamente)


Saludos
Nicolas Perichon

fjcg02
03-10-2013, 16:49:22
Ecfisa ya te ha dado la solución... pero no te has dado cuenta.

TObject(FieldByName('ID').AsInteger));

En un item de un Tcombobox puedes guardar un objeto. En este caso ecfisa guarda el ID del país. Puedes accesder a él sabiendo cual es el índice del item que tienes seleccionado.

Integer(Items.Objects[ItemIndex])

Te remito a la ayuda de Delphi.

Un saludo

Pericles
03-10-2013, 16:55:55
y sino como esta planteado podria ser...

Agrego los paises con su respectivo ID


ComboBox1.AddItem('Jamaica', TObject(1)); //id1
ComboBox1.AddItem('Chile', TObject(2)); //id2
ComboBox1.AddItem('Peru', TObject(56)); //id56



Conozco el país por el id...



//Aca tenes el pais de un determinado id
showmessage(combobox1.items.Strings[ combobox1.Items.IndexOfObject( Tobject(56) ) ]);

//aca el id del pais seleccionado en el combo
showmessage( intToStr( integer(combobox1.Items.Objects[ComboBox1.ItemIndex ])) );
(aca tuve que convertir el Objeto a INT y luego de Int a String.. sino me da error...




Saludos
Nicolas Perichon

ecfisa
03-10-2013, 20:12:32
Hola.

Sólo para agregar, el componente TDBLookupComboBox (http://docwiki.embarcadero.com/Libraries/XE2/en/Vcl.DBCtrls.TDBLookupComboBox) puede realizar esta taréa.


Saludos :)