PDA

Ver la Versión Completa : Asignar 2 combobox a una variable


DOS
15-09-2013, 22:44:55
Hola a todos, resulta que tengo dos combobox en uno tengo lo que serian algunas horas y en otro algunos minutos, cada uno lo guardo en una variable h, m, para ello creo un procedimiento
procedure TForm20.horaminutos; //procedimiento para sumar la hora y los minutos
var
h,m :string;
begin
h:=ComboBox3.Text;
m:=ComboBox2.Text;
end; por supuesto que esta incompleto
entonces el usuario selecciona la hora y los minutos y una serie de datos, cuando le da al boton guardar, llama al procedimiento y deberia quedar ej.: 18:20, esto se guardaria en una tabla dentro del campo hora del tipo Time.
Estoy desorientado en como asignar esas dos variables al campo, agradesco que me ayuden.

DOS
16-09-2013, 00:19:07
Estuve realizando algunos cambios.
function EncodeTime( Hour, Min: Word ): TDateTime; // es necesario poner segundos?
begin
Tiempo:=EncodeTime( h1, m1 );
end;

procedure TForm20.horaminutos; //procedimiento para sumar la hora y los minutos
begin
h:=ComboBox3.Text;
m:=ComboBox2.Text;
h1:=strToInt(h);
m1:=StrToInt(m);
end;

este es el boton de guardar
// guarda turno
procedure TForm20.BitBtn4Click(Sender: TObject);
begin
horaminutos; // llama al procedimiento
DBEdit4.SetFocus;
table1.FieldByName('Cod_turnovet').AsInteger:=c;
if table2.FieldByName('Cod_prop').AsInteger=Table3.FieldByName('Cod_prop').AsInteger
then
table1.FieldByName('Cod_propi').AsInteger:=Table3.FieldByName('Cod_prop').AsInteger;
Table1Hora.AsDateTime:=tiempo;
table1.Post;
end;

El asunto que cuando corre la hora queda en 00:00:00 :(

ecfisa
16-09-2013, 03:52:24
Hola DOS.


function hmToDateTime(cbH, cbM: TComboBox): TDateTime;
begin
if (cbH.ItemIndex = -1)or(cbM.ItemIndex = -1) then
raise Exception.Create('Debe ingresar horas y minutos');
Result := EncodeTime(StrToInt(cbH.Items[cbH.ItemIndex]),
StrToInt(cbM.Items[cbM.ItemIndex]), 0, 0);
end;


Uso:

begin
Table1.Append;
Table1.FieldByName('Hora').Value := hmToDateTime(cbHoras, cbMinutos);
...


Saludos :)

DOS
18-09-2013, 05:12:56
Muchas gracias ecfisa, lo estuve probando y me tira un error "control has no parent window"
esta es la codificación como quedo a ver si tu te das cuenta de que esta mal, gracias.
// guarda turno
procedure TForm20.BitBtn4Click(Sender: TObject);
var
cbHoras, cbMinutos: TComboBox;

begin
cbHoras:=TComboBox.Create(Application);// inicializo la variable
cbMinutos:=TComboBox.Create(Application);
DBEdit4.SetFocus;
table1.FieldByName('Cod_turnovet').AsInteger:=c;
if table2.FieldByName('Cod_prop').AsInteger=Table3.FieldByName('Cod_prop').AsInteger
then
Table1.Append;
Table1.FieldByName('Hora').Value := hmToDateTime(cbHoras, cbMinutos);
table1.FieldByName('Cod_propi').AsInteger:=Table3.FieldByName('Cod_prop').AsInteger;
table1.Post;

end;

la función
function hmToDateTime(cbH, cbM: TComboBox): TDateTime;
begin
if (cbH.ItemIndex = -1)or(cbM.ItemIndex = -1) then
raise Exception.Create('Debe ingresar horas y minutos');
Result := EncodeTime(StrToInt(cbH.Items[cbH.ItemIndex]),
StrToInt(cbM.Items[cbM.ItemIndex]), 0, 0);
end;
^\||/

ecfisa
18-09-2013, 05:54:05
Hola DOS.
lo estuve probando y me tira un error "control has no parent window"
Como indica el mensaje de error, debes asignarle un parent a los controles creados, ejemplo:

procedure TForm1.BitBtn4Click(Sender: TObject);
var
cbHoras, cbMinutos: TComboBox;
begin
cbHoras := TComboBox.Create(Self);
cbMinutos:= TComboBox.Create(Self);
with cbHoras do
begin
Left := 10;
Top := 10;
//...
Parent := Self;
end;
with cbMinutos do
begin
Left := 10;
Top := 50;
//...
Parent := Self;
end;
//...
end;


Saludos :)

DOS
20-09-2013, 01:13:06
Perdona ecfisa mi ignorancia y mi pesades, pero no entiendo, lo que tu pones parece como que quieres crear los combobox, pero ya estan en el form, son dos uno para las horas de 8 a 18 combobox3 y otro para los minutos de 0 a 50 cada 10 minutos combobox2, a ver si me puedes guiar un poco mas, muchas gracias.
// guarda turno
procedure TForm20.BitBtn4Click(Sender: TObject);
var
cbHoras, cbMinutos: TComboBox;

begin
cbHoras:=TComboBox.Create(Self);// deberia ser combobox3 y 2?
cbMinutos:=TComboBox.Create(Self);
with cbHoras do
begin
Left := 10;
Top := 10;
//... aca iria el resto de las especificaciones del combobox?
Parent := Self;
end;
with cbMinutos do
begin
Left := 10;
Top := 50;
//...
Parent := Self;
end;
DBEdit4.SetFocus;
table1.FieldByName('Cod_turnovet').AsInteger:=c;
if table2.FieldByName('Cod_prop').AsInteger=Table3.FieldByName('Cod_prop').AsInteger
then
Table1.Append;
Table1.FieldByName('Hora').Value := hmToDateTime(cbHoras, cbMinutos);
table1.FieldByName('Cod_propi').AsInteger:=Table3.FieldByName('Cod_prop').AsInteger;
table1.Post;
end;

ecfisa
20-09-2013, 01:50:55
Hola DOS.
lo que tu pones parece como que quieres crear los combobox,
Así es. Y esa idea la inferí basándome en el código de tu mensaje #4:
...lo estuve probando y me tira un error "control has no parent window"
esta es la codificación como quedo a ver si tu te das cuenta de que esta mal, gracias.
// guarda turno
procedure TForm20.BitBtn4Click(Sender: TObject);
var
cbHoras, cbMinutos: TComboBox;

begin
cbHoras:=TComboBox.Create(Application);// inicializo la variable
cbMinutos:=TComboBox.Create(Application);
DBEdit4.SetFocus;
table1.FieldByName('Cod_turnovet').AsInteger:=c;
if table2.FieldByName('Cod_prop').AsInteger=Table3.FieldByName('Cod_prop').AsInteger
then
Table1.Append;
Table1.FieldByName('Hora').Value := hmToDateTime(cbHoras, cbMinutos);
table1.FieldByName('Cod_propi').AsInteger:=Table3.FieldByName('Cod_prop').AsInteger;
table1.Post;

end;


Si agregaste los combos en tiempo de diseño no es necesario invocar a su constructor...

Por otro lado y por el comentario en tu código ("inicializo la variable"), veo que tenes una confusión entre la variable del objeto y sus propiedades.

Si el objeto ya esta creado (y lo está ya que fue echo en tiempo de diseño), lo que sigue es asignarle valores a la/las propiedades de la instancia de el/los TComboBox.
Con los combos creados en diseño y tu código estás eliminando el Parent previo, un ejemplo para que compruebes lo que estoy diciendo:

procedure TForm20.BitBtn4Click(Sender: TObject);
begin
ShowMessage('Soy cbHoras, mi padre es: ' + cbHoras.Parent.Name);
cbHoras := TComboBox.Create(Application);
if cbHoras.HasParent then
ShowMessage('No es posible, ¡ Mi padre es inmortal !'
else
ShowMessage('Ahora soy huérfano, acaban de matar a mi padre...');
end;


Saludos :)

DOS
20-09-2013, 03:13:12
ecfisa, si bien no entiendo mucho, creo que estoy mas cerca, pero mira lo que pasa.

http://img837.imageshack.us/img837/5031/xgql.jpg

// guarda turno
procedure TForm20.BitBtn4Click(Sender: TObject);
var
cbHoras, cbMinutos: TComboBox;
begin
cbHoras := ComboBox3;
cbMinutos := ComboBox2;
DBEdit4.SetFocus;
table1.FieldByName('Cod_turnovet').AsInteger:=c;
if table2.FieldByName('Cod_prop').AsInteger=Table3.FieldByName('Cod_prop').AsInteger
then
Table1.Append;
Table1.FieldByName('Hora').Value := hmToDateTime(cbHoras, cbMinutos);
table1.FieldByName('Cod_propi').AsInteger:=Table3.FieldByName('Cod_prop').AsInteger;
table1.Post;
end;

No deberia funcionar bien? :confused:(obvio que no)v\||/

ecfisa
20-09-2013, 05:51:35
Hola DOS.

No termino de entender la relación del gráfico con el código.

Pero volvamos a los ComboBox, ahora aparecen en escena dos nuevos ComboBox2 y ComboBox3, que supongo también están creados en tiempo de diseño.

El siguiente código no debería existir:

procedure TForm20.BitBtn4Click(Sender: TObject);
var cbHoras, cbMinutos: TComboBox; (* ¡ Esto no corresponde ! *)
begin
...

Al declarar cbHoras y cbMinutos como variables locales al método BitBtn4Click, este trabajará sobre estas y no sobre las homónimas creadas en tiempo de diseño. Provocando de ese modo una excepción ya que las locales no han sido instanciadas.

Por otro lado, la asignación de los combos debería hacerse:

procedure TForm20.BitBtn4Click(Sender: TObject);
begin
cbHoras.Items.Assign(ComboBox2.Items);
cbMinutos.Items.Assign(ComboBox3.Items);
...

Eso independientemente del buen o mal funcionamiento que pudiera tener el código que lo sucede.

Saludos :)

DOS
22-09-2013, 04:16:39
Gracias ecfisa, ya eliminie la parte del codigo que estaba mal, pero de que tipo deben ser las variables, las declaro del tipo global, pero si pongo string o integer me dice que no es compatible con el comboBox:confused: corre solo si pongo que son del tipo TcomboBox, el codigo queda asi
// guarda turno
procedure TForm20.BitBtn4Click(Sender: TObject);
begin
cbHoras := ComboBox3.Text;
cbMinutos := ComboBox2.Text;
//cbHoras.Items.Assign(comboBox2.Items); //no funciona
//cbMinutos.Items.Assign(ComboBox3.Items);//[Error] Unit20.pas(226): Record, object or class type required
DBEdit4.SetFocus;
table1.FieldByName('Cod_turnovet').AsInteger:=c;
if table2.FieldByName('Cod_prop').AsInteger=Table3.FieldByName('Cod_prop').AsInteger
then
Table1.Append;
Table1.FieldByName('Hora').Value := hmToDateTime(cbHoras, cbMinutos);
table1.FieldByName('Cod_propi').AsInteger:=Table3.FieldByName('Cod_prop').AsInteger;
table1.Post;
end;

El asunto que cuando cargo todos los datos y le doy click al boton de guardar, me queda como en la imagen , el del codigo de turno 10000006 , quedan todos los datos pero la hora queda en otra linea sola, por eso lo remarque con una flecha.
Si lo cargo asignando como tu lo escribiste, se cuelga tirando un error Access violation at Addres 0053a434 in module 'Project1.exe'... declarando las variables del tipo Tcombobox y si las declaro del tipo string o integer no anda y aparece el error que se muestra arriba.
creo que esta cerca de la solucion, falta un ultimo pasito, muchas gracias por tu paciencia.^\||/

DOS
28-09-2013, 01:39:28
ecfisa, todavia no lo pude resolver :(

ecfisa
28-09-2013, 15:03:30
Hola DOS.

La verdad, me falta información para poder darte una respuesta a tu anteúltimo mensaje. Asì que te hago unas consultas:

¿ cbHoras y cbMinutos son dos TComboBox donde se elijen horas y minutos respectivamente ?
¿ Que función desempeñan ComboBox3 y ComboBox2 ?
¿ De que tipo es el campo Hora de Table1 ?


Saludos :)

DOS
29-09-2013, 04:06:32
Hola DOS.

La verdad, me falta información para poder darte una respuesta a tu anteúltimo mensaje. Asì que te hago unas consultas:

¿ cbHoras y cbMinutos son dos TComboBox donde se elijen horas y minutos respectivamente ?
¿ Que función desempeñan ComboBox3 y ComboBox2 ?
¿ De que tipo es el campo Hora de Table1 ?


Saludos :)
En realidad cbHoras y cbMinutos son dos variables que se le asignan los datos de los combobox seleccionados.
En el ComboBox3 se muestran las horas de 8 a 18 y en el ComboBox2 los minutos de a 10 (10, 20, 30, 40, 50, 00)
el campo Hora es del tipo datatime.
Lo que pasa es que fui modificando a medida que me aconsejabas y tal vez borre algo o hice algo de mas o menos asi que tambien pongo el codigo, lo cambie tantas veces tratando de que funcione que ya me perdi.

variables generales:
var
Form20: TForm20;
c,h1,m1,s:integer;
h,m:string;
tiempo : TDateTime;
cbHoras, cbMinutos: TComboBox;

Funcion
function hmToDateTime(cbH, cbM: TComboBox): TDateTime;
begin
if (cbH.ItemIndex = -1)or(cbM.ItemIndex = -1) then
raise Exception.Create('Debe ingresar horas y minutos');
Result := EncodeTime(StrToInt(cbH.Items[cbH.ItemIndex]),
StrToInt(cbM.Items[cbM.ItemIndex]), 0, 0);
end;

boton de nuevo:
// nuevo turno
procedure TForm20.BitBtn6Click(Sender: TObject);
begin
DBEdit4.SetFocus;
Table1.Open;
Table1.Last;
c:=Table1.FieldByName('Cod_turnovet').Asinteger;
c:=c+1;
Table1.insert;
table1.edit;
BitBtn6.Enabled:=False;
BitBtn3.Enabled:=false;
BitBtn2.Enabled:=true;
BitBtn4.Enabled:=true;
DBEdit2.Visible:=false;
DBEdit3.Visible:=false;
DateTimePicker1.Visible:=true;
end;


boton de guardar nuevo:
// guarda turno
procedure TForm20.BitBtn4Click(Sender: TObject);
begin
table1.Last;
cbHoras := ComboBox3;// como esta funcionando ahora
cbMinutos := ComboBox2;
//cbHoras.Items.Assign(comboBox2.Items);
//cbMinutos.Items.Assign(ComboBox3.Items);
DBEdit4.SetFocus;
// Table1.Append;
// table1.FieldByName('Cod_turnovet').AsInteger:=c;
if table2.FieldByName('Cod_prop').AsInteger=Table3.FieldByName('Cod_prop').AsInteger
then
Table1.Append;
table1.FieldByName('Cod_turnovet').AsInteger:=c;
Table1.FieldByName('Hora').Value := hmToDateTime(cbHoras, cbMinutos);
table1.FieldByName('Cod_propi').AsInteger:=Table3.FieldByName('Cod_prop').AsInteger;
table1.Post;
BitBtn5.Enabled:=True;
BitBtn6.Enabled:=True;
BitBtn4.Enabled:=false;
BitBtn3.Enabled:=True;
DateTimePicker1.Visible:=false;
DBEdit2.Visible:=true;
DBEdit3.Visible:=true;
end;

Espero que te aclare un poco mas y puedas ver que esta mal, muchas gracias.

ecfisa
29-09-2013, 11:35:56
Hola DOS.

Supongamos que las horas y los minutos se seleccionan desde dos TComboBox, llamados ComboBoxHoras y ComboBoxMinutos respectivamente.

La conversión y posterior asignación al campo "Hora" de "Table1" debería ser:

...
var
h,m: Word;
begin
// Si hay horas y minutos seleccionados...
if (ComboBoxHoras.ItemIndex <> -1) and (ComboBoxMinutos.ItemIndex <> -1) then
begin
Table1.Append; // Agregar
...
Table1.FieldByName('Hora').AsDateTime := EncodeTime(
StrToInt(ComboBoxHoras.Items[ComboBoxHoras.ItemIndex]), // Horas
StrToInt(ComboBoxMinutos.Items[ComboBoxMinutos.ItemIndex]), //Minutos
0, 0); // Segundos, ms
...
end;
end;


Saludos :)

DOS
29-09-2013, 17:20:34
Hola, sigue habiendo un error al grabar los datos, le realice algunas modificaciones, las variables h y m no se utilizan y los combobox son ComboBoxHoras = ComboBox3 y ComboBoxMinutos = ComboBox2(ya se que es mas claro como tu lo escribiste)
// guarda turno
procedure TForm20.BitBtn4Click(Sender: TObject);
begin
// Si hay horas y minutos seleccionados...
if (ComboBox3.ItemIndex <> -1) and (ComboBox2.ItemIndex <> -1) then
begin
Table1.Append; // Agregar
table1.FieldByName('Cod_turnovet').AsInteger:=c;
table1.FieldByName('Cod_propi').AsInteger:=Table3.FieldByName('Cod_prop').AsInteger;
Table1.FieldByName('Hora').AsDateTime := EncodeTime(
StrToInt(ComboBox3.Items[ComboBox3.ItemIndex]), // Horas
StrToInt(ComboBox2.Items[ComboBox2.ItemIndex]), //Minutos
0, 0); // Segundos, ms
table1.Post;
BitBtn5.Enabled:=True;
BitBtn6.Enabled:=True;
BitBtn4.Enabled:=false;
BitBtn3.Enabled:=True;
DateTimePicker1.Visible:=false;
DBEdit2.Visible:=true;
DBEdit3.Visible:=true;
end;
end;

Queda de la siguiente manera cuando cargo los datos y le doy guardar en el boton, se ve asi en el DBGrid y si realizo una nueva cargaobviamente me da un error de violation key, dado que esto se esta complicando mucho y no se llega a una solucion, ¿tu crees que seria mas facil si al campo Horas, lo paso como string o integer en ves de datatime?
http://img854.imageshack.us/img854/3563/y2vz.jpg
que puede ser?

ecfisa
29-09-2013, 23:23:24
... si realizo una nueva cargaobviamente me da un error de violation key,...
Hola DOS.

Ese error no tiene que ver con la asignación del campo "Hora" en sí. Lo que está indicando, es que estas ingresando un valor en el campo determinado como clave primaria que ya existe en otro registro de Table1.

¿ Como se llama ese campo y que valor le asignas antes de guardar el registro ?

Saludos :)

DOS
30-09-2013, 00:25:17
La clave principal Cod_turnovet, el problema es que no se porque no se muestra todo en una sola linea, por eso adjunté la imagen, fijate como vienen en el DBGrid el 1, 2, 3... y el 6 que es el que grabo, pone los datos por separado en dos linea distintas.
Al quedar una linea sin el numero de la clave principal al crea un nuevo ingreso es logico que tire ese error. gracias.

ecfisa
30-09-2013, 04:38:12
Hola DOS.

Sin dudas el problema se encuentra en el valor que contiene la variable "c" al momento de la asignación:

...
Table1.FieldByName('Cod_turnovet').AsInteger := c;
...

Sería mas conveniente que definieras la clave "Cod_turnovet" como autoincremental, de ese modo no tendrías que preocuparte por su valor.

Saludos :)

DOS
04-10-2013, 03:05:25
ecfisa, ya lo solucione estaba de mas Table1.Append; asi que quedo asi:
// guarda turno
procedure TForm20.BitBtn4Click(Sender: TObject);
begin
// Si hay horas y minutos seleccionados...
if (ComboBox3.ItemIndex <> -1) and (ComboBox2.ItemIndex <> -1) then
begin
table1.FieldByName('Cod_turnovet').AsInteger:=c;
table1.FieldByName('Cod_propi').AsInteger:=Table3.FieldByName('Cod_prop').AsInteger;
Table1.FieldByName('Hora').AsDateTime := EncodeTime(
StrToInt(ComboBox3.Items[ComboBox3.ItemIndex]), // Horas
StrToInt(ComboBox2.Items[ComboBox2.ItemIndex]), //Minutos
0, 0); // Segundos, ms
table1.Post;
BitBtn5.Enabled:=True;
BitBtn6.Enabled:=True;
BitBtn4.Enabled:=false;
BitBtn3.Enabled:=True;
DateTimePicker1.Visible:=false;
DBEdit2.Visible:=true;
end
else // si no ingresa horas o minutos
ShowMessage('Debe ingresar horas y minutos');
end;
ahora ecfisa, abusando de tu conocimiento, estaria bueno poder restringir si el veterinario ya tiene un turno reservado, que no pueda elegir el mismo, entoces deberia restringir al veterinario y a las horas y minutos, crees que me puedas ayudar con eso, ya que no veo otro que lo haga o abro un nuevo trhead, desde ya muchas gracias por todo. ^\||/
Creo que deberia hacer un if anidado, primero restringiendo al veterinario luego la hora y los minutos, crees que funcionaria asi?