PDA

Ver la Versión Completa : Ayuda en un código


kbaby
09-05-2008, 15:11:33
Hola! Estoy haciendo una minibase de datos con lo que he aprendido. Utilizo la MEMO para guardar los ITEMS. Me gustaría hacer algo para que cuando ponga por ejemplo: García ... me salieran todos los garcías de mi base de datos y yo elejir uno que se mostrara en una tabla ^^.

Espero expresarme bien. Un saludo.

Delphius
09-05-2008, 16:24:56
Hola kbaby,
Podrías explicar mejor tu situación?
Por empezar sácame una duda... Cuando dices:
Utilizo la MEMO para guardar los ITEMS

¿A qué te refieres? ¿A un TMemo? ¿Y como es que ingresas los datos?
Así?:

Dato1
Dato2
...
DatoN

O ¿Así?
Dato1 Dato2 ... DatoN


De cualquier manera no creo que sea lo más adecuado para ingresar los items... No se me parece que hay algo que se nos escapa de esta explicación.

Además, deberías aportarnos más detalles. Por empezar que base de datos usas, componentes de acceso a la base de datos ¿ADO?, un poquito de tu código para saber como es que estás haciendo las cosas.

Saludos,

kbaby
09-05-2008, 20:09:21
Vale empiezo.

- Utilizo la utilidad ListBox*.

- Para añadir items a la lista utilizo el siguiente comando:
l.items.add(edit1.text); // donde l es el nombre de la ListBox* y edit1.text el cuadro de edicción que utilizo para meter el nombre o el dato de la persona.

- Los datos los guardo en un documento de texto .txt y un ejemplo sería:

Alfonso Megías Navarro 19/05/1921 Hombre 54875422I Granada
Alfonso Megías Navarro 19/05/1921 Hombre 54875422I Granada
Alfonso Megías Navarro 19/05/1921 Hombre 54875422I Granada
Alfonso Megías Navarro 19/05/1921 Hombre 54875422I Granada Pero cambiarían los datos a mostrar. Así que yo quiero que cuando ponga el DNI XXXXXXXXXX salga la persona que yo quiero en una tabla :p.

- No se lo que es ADO
- No te pego código porque lo que tengo está en mi libreta de apuntes y eso no lo tengo (porque no lo vimos).

Gracias ^^

*Antes puse TMemo, me equivoque.

kbaby
09-05-2008, 20:42:03
También quiero añadir unas dudas que me surgen mientras compilo el programa.

Tengo dos formularios. En el FORM1 tengo una ListBox y en el FORM2 tengo los datos que voy a guardar en la ListBox cuando pulse un button. ¿Cómo lo hago? Yo se hacerlo si la ListBox está dentro del mismo formulario pero no fuera. Gracias.

Otra duda: Me gustaría ponerle a los button iconos. Por ejemplo al de salir, una puerta... y así. No se que tipo de button es ni como hacerlo.

Gracias :o es un proyecto lo que estoy haciendo.

Casimiro Notevi
09-05-2008, 21:05:30
Puedes visitar la wiki del clubdelphi:http://wiki.clubdelphi.com/
Puedes visitar la ftp del clubdelphi, donde encontrarás libros tan buenos como este: http://www.terawiki.clubdelphi.com/archivos/Delphi-Win32/Libros/LaCaraOcultaDeDelphi4.pdf.zip
Puedes visitar los trucos del clubdelphi: http://www.clubdelphi.com/trucos/
Si tienes alguna duda, pregunta :)

Delphius
09-05-2008, 21:09:44
Hola kbaby,
Entonces no estamos hablando de base de datos... sino de uso de ficheros.
Olvida lo que dije sobre ADO, motores de base de datos.

¿A que le llamas tabla? Para mi una tabla es un TxxxTable. Y esto si es ya el mundo de base de datos.

Sería bueno que nos expliques profundamente que es lo quienes. Porque cualquier palabra que digas puede tener un significado para otros. Como dije... una tabla para mi es una tabla de una base de datos, a la cual accedo mediante un TTable, o un TQuery, linqueado a un DataSource y una TConeection... etc Y como ves, esto es un mundo que no estás explorando por el momento.

Por el momento lo que te entiendo es que tienes unos datos en el TListBox y tu deseas buscar un item en específico. Para ello se cuenta con el método IndexOf() que devuelve el índice del item si lo encuentra.

El código que te paso a continuación busca el contenido de un TEdit en un TListBox, en caso de encontrarlo lo selecciona, de otra manera recibes un mensaje:

procedure TForm1.Button1Click(Sender: TObject);
var Index: integer;
begin
Index := ListBox1.Items.IndexOf(Edit1.Text);
if Index >= 0
then ListBox1.Selected[Index] := True
else ShowMessage('Elemento no encontrado');
end;

Por lo segundo, Tienes dos forms. Cada uno con su respectiva Unit. Para hacer lo que buscas debes declarar la unit de uno en otro en la sección unit.

Unit Unit2;

interface
...

uses
bla, bla, bla, Unit1.

...


Entonces esto permite de que desde Unit2 "veamos" y tengamos acceso a Unit1.

Pero he aquí un dilema, Si Unit1 "llama" a Unit2 y Unit2 debe comunicarse a Unit1 y si declaras en uses la Unit del otro, provocarás un conflicto que recibe el nombre de referencia circular. ¿Como solucionarlo?
Uno de los Unit debe tener declarado el uso de la otra unit en la sección implementation y el otro en interface:

Unit UnitX;

...

implementation

uses
UnitY;
...

Espero que esto te haya dado una idea. Más no puedo decirte puesto que no comprendo tu idea. Como he dicho, sería oportuno que nos describieses mejor el problema.

Saludos,

kbaby
09-05-2008, 21:40:28
Bueno empezemos:

La 1º duda solucionada, lo de buscar un ITEM y señalarlo. Luego lo que quiero es que ese ITEM con otros que vienen asociados a la información de la persona, se muestren en la tabla. Mi tabla, es la StringGrid (eso es la unica tabla que yo se). Así que voy a probar tu solución de buscar para mostrar para ver si puedo hacer lo que yo quiero.

Lo que yo quiero es... que si pongo el DNI XXX.XXX.XX.X que corresponde a HHHHH HHHHH HHHHH pues en la tabla que tiene sólo una fila... tiene que salir el nombre de HHHHH sus apellidos HHHHHH HHHHH y mas datos que guardo.


La 2º duda... cuando me la explicaste :D me recordó a algo que dijo el profesor así que muchas gracias jajaja. Solucionada.

La 3º duda... eso si que no la entiendo... si me diera el error la uso, sino ... mejor me quedo quieto y parado.



PD: Puse otro post con "mini dudas que me surgen cuando compilo".

Gracias tio,.

kbaby
09-05-2008, 21:48:00
Con respecto a la 3º duda... efectivamente me a ocurrido y creo que con lo que hice se solucionó, claro está gracias a tu explicación. Sigo indagando por aquí.

---EDITO---

He hecho lo de poner Unit1 y Unit2 (en mi caso se llama: fiesta y fiesta2). // no se porqué xD. Bueno el resultado es que cuando estoy en fiesta2 y quiero usar la ListBox que tengo en fiesta me dice que no conoce L. "L" es el nombre que le di a la ListBox.

Cuando estoy en Unit1 (en mi caso "fiesta")... pongo en uses (los que hay dentro de interface) bla, bla, bla, fiesta2; y cuando estoy en Unit2 (en mi caso "fiesta2").... pongo en uses (los que hay dentro de implementation) uses fiesta;
Pues le doy a F9 y lo ejecuto y me dice noseque circular noseque.... osea eso que me dijiste jajaja. ¿Qué hago?.

Te pego aquí los codigos:

Mi Unit1:

unit hospital;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, Menus, StdCtrls, Grids, hospital2;

type
TForm1 = class(TForm)
Image1: TImage;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
Label4: TLabel;
Label5: TLabel;
MainMenu1: TMainMenu;
MENU1: TMenuItem;
NuevoPaciente1: TMenuItem;
Salir1: TMenuItem;
t: TStringGrid;
l: TListBox;
Button1: TButton;
Button2: TButton;
Button3: TButton;
Edit1: TEdit;
Button4: TButton;
Button5: TButton;
procedure NuevoPaciente1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure Button4Click(Sender: TObject);
procedure Button5Click(Sender: TObject);
procedure Button1Click(Sender: TObject);

private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation





Mi Unit2

unit hospital2;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TForm2 = class(TForm)
Edit1: TEdit;
Edit2: TEdit;
Edit3: TEdit;
Edit4: TEdit;
Edit5: TEdit;
Edit6: TEdit;
Label1: TLabel;
Label2: TLabel;
Label4: TLabel;
Label5: TLabel;
Label6: TLabel;
Label7: TLabel;
Button1: TButton;
Button2: TButton;
Button3: TButton;
procedure Button3Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form2: TForm2;

implementation

uses hospital;

kbaby
10-05-2008, 12:14:09
Sigo sin poder utilizar la ListBox de mi Form1 en el Form2 :S aquí arriba os puse el code de mis dos formularios. Gracias :rolleyes:;)

Delphius
10-05-2008, 16:37:09
A ver... No veo donde está el problema...

Te paso un ejemplo sencillo para que veas de lo que hablo.
Ya nos dirás como avanzas.

Saludos,

kbaby
11-05-2008, 13:18:53
Voy a ver que tal el ejemplo. Gracias tio.

kbaby
26-05-2008, 16:55:39
aqui vuelvo, con el mismo problema, no se como hacerlo. no se hacer lo siguiente:
cuando en un listbox tengo los items metidos... yo quiero insertar el dni de una persona en un edit y al pulsar en un button... que me salga un mensaje (si puede ser en una tabla stringnoseke) con los datos de la persona.

Sería asi:

Lisbox:
dni1
nombre1
apellido1
telefono1
dni2
nombre2
apellido2
telefono2


Cuando en el edit ponga "dni2" me volcara en una tabla:
dni2 - nombre2 - apellido2 - telefono2

Espero explicarme bien (aunque no lo se).

gracias

kbaby
26-05-2008, 16:58:18
Tu ejemplo me ayuda mucho porque porlomenos BUSCA el item. Ahora yo quiero aprender como pasar ese item (y los que les siguen) a una tabla.

Delphius
26-05-2008, 18:10:47
Hola kbaby... el siguiente código es un ejemplo de lo que buscas:

procedure TForm1.Button2Click(Sender: TObject);
var indice: integer;
i: integer;
begin
// primero buscamos el dato. Supuesto: que siempre estamos buscando un DNI
indice := ListBox1.Items.IndexOf(Edit5.Text);
if indice <> -1
then begin
for i := 1 to 4 do //este cuatro corresponde a la cantidad
// de datos a mostrar. En este caso son: DNI, Nombre, Apellido,
// Teléfono
begin;
// mostrar cada dato en una celda distinta
// De hecho, lo mostramos en la primera fila
// [columna,fila]
StringGrid1.Cells[i,1] := ListBox1.Items[indice];
inc(indice);
end;
end
else ShowMessage('DNI no encontrado');
end;

El código funciona, siempre que busques el DNI. Si buscas el apellido o cualquier otro dato no vas a obtener lo que deseas... Hice el supuesto de que siempre están disponibles todos los datos, de otro modo el algoritmo falla. Para hacerte una idea de porque funciona. piensa al listBox como una lista. Y cada elemento ocupa una posición.

0 - DNI
1 - Nombre
2 - Apellido
3 - Teléfono
4 - DNI
5 - Nombre
6 - Apellido
7 - Teléfono

¿Ves algo extraño? ¿No parece haber una correlación entre 0 y 4?¿Lo mismo que para 1 y 5?
Es por ello que al encontrar la posición del DNI, la copio a la posición [1,1] del stringGrid, luego, exploro las siguientes 3 posiciones y las añado a la posición [i,1]. ¿Porqué sacamos siempre el valor del Indice? Pues porque si te fijas, al final de cada bucle FOR incremento (la función inc()) la variable indice en 1. Y esto hace que con cada pasada, se obtenga el siguiente elemento del ListBox.

Inc(indice) es análogo a indice := indice + 1;
inc(indice, 2) es análogo a indice := indice + 2;

Analiza el código que te pasee y ve de que manera se adapta a lo que buscas.

Muchas de las cosas que preguntas tienen tanto de lógica como del uso del uso de las propiedades de los objetos que empleas. No temas pulsar F1 al seleccionar un objeto. Por ejemplo, si no sabes como usar el StringGrid, arrastra uno al form, seleccionalo y presiona F1. Obtendrás la ayuda.

El inglés no es pretexto, habiendo traductores on-line como off-line.

Saludos,

kbaby
26-05-2008, 18:44:00
Tio, muchas gracias, me entere fenomenal. Ahora viene la segunda parte... ver si yo puedo. Ahora te aviso.

kbaby
26-05-2008, 19:04:44
Primer problema que me surge:

"Estoy intentando que el programa lea un archivo .txt previamente creado con los datos puestos:

nombre
apellido
nombre
apellido

(esto es una prueba)

Bueno el problema es que cuando le doy a "recuperar" pues me lo lee y sale en el LISTBOX pero con un espacio entre nombre y apellido... así:

pepe
//aqui hay un espacio que no había
gomez
// aquí tambien
juan
// aqui tambien
lopez

El codigo es:

Código Delphi [-] (http://www.clubdelphi.com/foros/#)var f:textfile;
n:string;
begin assignfile(f,'nombres.txt');
reset(f);
while not eof(f) do begin readln(f,n); edit1.Text:=n; button1.Click; //añadir ¿en mis apuntes sale ke tengo que poner esto... pq?
button2.Click; //lo que hace es volcar
end;
closefile(f);
end;

end.

kbaby
26-05-2008, 19:05:35
Primer problema que me surge:

"Estoy intentando que el programa lea un archivo .txt previamente creado con los datos puestos:

nombre
apellido
nombre
apellido

(esto es una prueba)

Bueno el problema es que cuando le doy a "recuperar" pues me lo lee y sale en el LISTBOX pero con un espacio entre nombre y apellido... así:

pepe
//aqui hay un espacio que no había
gomez
// aquí tambien
juan
// aqui tambien
lopez

El codigo es:


var f:textfile;
n:string;
begin
assignfile(f,'nombres.txt');
reset(f);
while not eof(f) do
begin
readln(f,n);
edit1.Text:=n;
button1.Click; //añadir ¿en mis apuntes sale ke tengo que poner esto... pq?
button2.Click; //lo que hace es volcar
end;
closefile(f);
end;

end.

Delphius
26-05-2008, 19:14:43
kbaby, el TListBox cuenta con los métodos LoadFromFile y SaveToFile que hace todo el trabajo más fácil.

LoadFromFile abre un archivo y lo muestra. SaveToFile lo guarda.
El archivo que se genera es como aparece en el ListBox. Cada texto en un "renglón". Es decir que si en un ListBox tienes esto (cada uno en una linea):

Hola como estas kbaby
yo aqui un poco adivinando
lo que hace ese button1.click
y también desorientado con el button2.click

Tu archivo quedará escrito en la misma forma.

El problema con ese código puede deberse al Readln() ya que eso hace que se pase al siguiente "renglón". El porque en tus apuntes invocas a un Button1.Click y luego a un Button2.Click lo desconozco... es cosa de tus apuntes... y pues... no estoy allí para ver que es lo dicen.:D

Si nos aportaras más datos podría saber el modo de ayudarte.

Saludos,

kbaby
26-05-2008, 19:19:42
¿Por qué utilizas el Inc(indice)?

Es lo único que no me ha quedado claro.


Yo pulso f1, y lo leo, pero no veo como se adapta lo que a mí me han enseñando y no puedo llevar algo que no haya yo enseñado. Ahora si yo el " Inc(indice)" lo adapto a lo que me han enseñado pues sí.

Espero me comprendas.

kbaby
26-05-2008, 19:25:30
kbaby, el TListBox cuenta con los métodos LoadFromFile y SaveToFile que hace todo el trabajo más fácil.

LoadFromFile abre un archivo y lo muestra. SaveToFile lo guarda.
El archivo que se genera es como aparece en el ListBox. Cada texto en un "renglón". Es decir que si en un ListBox tienes esto (cada uno en una linea):

Hola como estas kbaby
yo aqui un poco adivinando
lo que hace ese button1.click
y también desorientado con el button2.clickTu archivo quedará escrito en la misma forma.

El problema con ese código puede deberse al Readln() ya que eso hace que se pase al siguiente "renglón". El porque en tus apuntes invocas a un Button1.Click y luego a un Button2.Click lo desconozco... es cosa de tus apuntes... y pues... no estoy allí para ver que es lo dicen.:D

Si nos aportaras más datos podría saber el modo de ayudarte.

Saludos,


Problema solucionado, fue simplemente ir probando, el código quedaría así:


var i:integer;
begin
t.rowcount:=l.items.count div 4 +1;
for i:=0 to (l.items.count-1)div 4 do
begin
t.cells[1,I+1]:=l.items[i*4];
t.cells[2,I+1]:=l.items[i*4+1];
t.cells[3,I+1]:=l.items[i*4+2];
t.cells[4,I+1]:=l.items[i*4+3];
end;
end;

procedure TForm1.Button3Click(Sender: TObject);
var f:textfile; i:integer;
begin
assignfile (f,'nombres.txt');
rewrite(f);
for i:=0 to l.items.count-1 do
writeln (f,l.items[i]);
closefile(f);
end;

procedure TForm1.Button4Click(Sender: TObject);
var f:textfile;
n:string;
begin
assignfile(f,'nombres.txt');
reset(f);
while not eof(f) do
begin
readln(f,n);
edit1.Text:=n;
readln(f,n); //lo que he hecho es añadir esto
edit2.Text:=n; //y esto por cada item que tenga, como en mi caso son 4, pues sería esto.
readln(f,n);
edit4.Text:=n;
readln(f,n);
edit5.Text:=n;
button1.Click; //esto hace añadir. si lo quito falla... así que lo dejo mejor.
button2.Click; //lo que hace es volcar en la tabla todo el contenido del listbox.
end;
closefile(f);
end;

end.


Lo que hace el boton añadir es irse esto:

Mete la 1º linea del .txt en el edit1.text, luego la 2º linea en el edit2.text y así hasta las cuatro lineas y luego las añade al listbox.
Esto lo repite hasta llegar al final.

Luego lo vuelca en la tabla. He quitado lo de volcarlo porqueno me interesa volcar TODO.

Duda: ¿Cabe la posibilidad de recuperar la información del .TXT en el LISTBOX sin tener que hacerlo de mi manera tan "cutre"?.

Delphius
26-05-2008, 19:33:16
¿Por qué utilizas el Inc(indice)?

Es lo único que no me ha quedado claro.


Yo pulso f1, y lo leo, pero no veo como se adapta lo que a mí me han enseñando y no puedo llevar algo que no haya yo enseñado. Ahora si yo el " Inc(indice)" lo adapto a lo que me han enseñado pues sí.

Espero me comprendas.

Pues es una costumbre mia. Inc() es una función que lo que hace es incrementar una variable (no puede utilizarse con las propiedades de un objeto, por ejemplo... la propiedad ItemIndex) en un valor. Por defecto el incremento es de 1. Te explico:

cuando uno hace:

inc(tu_variable);

Lo que consigues es incrementar tu_variable en 1. Al hacer:

inc(tu_variable,5);

Lo que consigues es incrementar tu variable en 5.

De cualquier manera, puedes sustituir, como he dicho, a inc() por su equivalente:


tu_variable := tu_variable + 1 // 5, 300, 2321321, lo que se te ocurra.


¿El porqué uso la variable indice para incrementar? Pues... para ahorrarme otra variable. Si te fijas, la uso inicialmente para localizar la posición de un texto. Y si se dicha posición puedo saber la de los demás.

Si el archivo SIEMPRE contendrá TODOS los datos y en dicho ORDEN, con saber la posición del DNI se puede conocer la de los demás datos.
Por ejemplo:
Nombre ocupa la posición siguiente a indice. Lo que se traduce a Indice + 1.
Apellido ocupa la posición siguiente a Nombre. Traducido: indice + 2.
Telefono ocupa la posición siguiente a Apellido. Traducido: indice + 3.

Con cada paso del bucle FOR, no sólo me desplazo sobre la fila del StringGrid, sino también sobre el indice del ListBox.

¿Me vas entendiendo?

Saludos,

kbaby
26-05-2008, 20:13:42
Entendido :rolleyes: Gracias profe :D

kbaby
28-05-2008, 15:37:45
Aqui volviii :p Con dudas :D bueno en realidad son solo dos dudas.

1º Duda: Como acordamos, el codigo que funciona para buscar a los usuarios por DNI es el siguiente:

var indice: integer;
i: integer;
begin
indice := l.Items.IndexOf(Edit3.Text);
if indice <> -1
then begin
for i := 1 to 4 do
begin;

t.Cells[i,1] := l.Items[indice];
inc(indice);
end;
end
else ShowMessage('Este DNI no pertenece a ningún usuario');
Exit;
end;

Pero funciona eso porque los datos son:
0-DNI
1-NOMBRE
2-APELLIDOS
3-CIUDAD
4-DNI
5-NOMBRE
6-APELLIDOS
7-CIUDAD

Entonces, como dijiste, entre el 0 y el 3 existe una relacion. Pero y si yo lo que quiero ahora es ampliar el programa ¿y si busco por los APELLIDOS me salga en la tabla la persona con esos apellidos? Creo, que lo que hay que tocar es:

t.Cells[i,1] := l.Items[indice];

Pero como ya te dije, eso de INC no lo entendi bien. Por lo visto, va aumentando de 1 en 1 ¿no? Por eso sale el item 0, luego 1, 2,3...
Entonces si yo pongo en el EDIT de la busqueda los APELLIDOS... en la tabla me salen los items 3,4,5,6.
¿Como arreglo eso? :D Ya estoy indagando xD pero nada.


Otra cosa es la siguiente. Yo se volcar el contenido de mi LISTBOX en una TABLA (STRINGRID). AQUI TENEIS UN EJEMPLO:

MI TABLA
----------------------------------
|dni1 |nombre1 |apellido1 |
----------------------------------
----------------------------------
|dni2 |nombre2 |apellido2 |
----------------------------------
----------------------------------
|dni3 |nombre3 |apellido3 |
----------------------------------
----------------------------------
|dni4 |nombre4 |apellido4 |
----------------------------------

Y así, con todas las personas de mi listbox. Entonces si al nombre3 (un ejemplo) le cambio el nombre y se llama pepito en vez de juan... y le doy a GUARDAR... (guardar para que se guarden los cambios)... pierdo todas las otras personas y solo se me queda la persona "3" con sus cambios. ¿Por qué? ¿Qué manera usais vosotros para hacer lo que yo intento? Lo siento por ser tan... malo... pesimo.... en mis detalles.


gracias.

kbaby
28-05-2008, 15:41:57
La PRIMERA DUDA la he resuelto solo!!! Siii!!! En la linea

indice := l.Items.IndexOf(Edit3.Text);

La modifique haciendo esto:

indice := (l.Items.IndexOf(Edit3.Text))-2;

Con este cambio, en la variable indice, metera el item que yo pongo en el edit pero bajandolo dos casillas (por el -2).

Siguiente duda: ¿Y si ahora hay dos personas con los mismo apellidos... hermanos? Solo me sale la primera... ¿alguna manera? :o:p

Delphius
28-05-2008, 19:21:11
Aqui volviii :p Con dudas :D bueno en realidad son solo dos dudas.

1º Duda: Como acordamos, el codigo que funciona para buscar a los usuarios por DNI es el siguiente:


var indice: integer;
i: integer;
begin indice := l.Items.IndexOf(Edit3.Text); if indice <> -1
then begin for i := 1 to 4 do begin;

t.Cells[i,1] := l.Items[indice];
inc(indice);
end;
end else ShowMessage('Este DNI no pertenece a ningún usuario');
Exit;
end;



Pero funciona eso porque los datos son:
0-DNI
1-NOMBRE
2-APELLIDOS
3-CIUDAD
4-DNI
5-NOMBRE
6-APELLIDOS
7-CIUDAD

Entonces, como dijiste, entre el 0 y el 3 existe una relacion. Pero y si yo lo que quiero ahora es ampliar el programa ¿y si busco por los APELLIDOS me salga en la tabla la persona con esos apellidos? Creo, que lo que hay que tocar es:

[DELHPI]
t.Cells[i,1] := l.Items[indice];
[/DELPHI]

Pero como ya te dije, eso de INC no lo entendi bien. Por lo visto, va aumentando de 1 en 1 ¿no? Por eso sale el item 0, luego 1, 2,3...
Entonces si yo pongo en el EDIT de la busqueda los APELLIDOS... en la tabla me salen los items 3,4,5,6.
¿Como arreglo eso? :D Ya estoy indagando xD pero nada.

Creo que eso ya te lo había dicho. El algoritmo es simple, y he recalcado que si buscabas cualquier otro dato obtendrías otros resultados.


Otra cosa es la siguiente. Yo se volcar el contenido de mi LISTBOX en una TABLA (STRINGRID). AQUI TENEIS UN EJEMPLO:

MI TABLA
----------------------------------
|dni1 |nombre1 |apellido1 |
----------------------------------
----------------------------------
|dni2 |nombre2 |apellido2 |
----------------------------------
----------------------------------
|dni3 |nombre3 |apellido3 |
----------------------------------
----------------------------------
|dni4 |nombre4 |apellido4 |
----------------------------------

Y así, con todas las personas de mi listbox. Entonces si al nombre3 (un ejemplo) le cambio el nombre y se llama pepito en vez de juan... y le doy a GUARDAR... (guardar para que se guarden los cambios)... pierdo todas las otras personas y solo se me queda la persona "3" con sus cambios. ¿Por qué? ¿Qué manera usais vosotros para hacer lo que yo intento? Lo siento por ser tan... malo... pesimo.... en mis detalles.

gracias.
Primeramente sería oportuno que nos indicaras de que modo estás volcando la información desde el TListBox hacia el StringGrid. Y si me explicaras mejor lo que estás buscando hacer...

El problema kbaby es que tu estás empleando un método para guardar y leer archivos un tanto incompatible con los controles que estás usando.
Habiendo la posibilidad de emplear SaveToFile y LoadFromFile tanto para ListBox como para StringGrid el trabajo se hace más fácil.

Pero si es como dices, que no puedes emplear nada fuera de lo que viste ¿De que sirve que te indiquemos de que manera lo hacemos, si es mucho más probable de que sea algo complejo y/o algo que no has visto ni tienes en tus apuntes?
A lo que voy, es que si te estás basando en tus apuntes, poco puedo imaginarme el modo de hacerte más fácil los ejemplos. No se que tienes en tus apuntes, y eso me condiciona mucho.

Y es posible que también lo sea para otros foristas.

La PRIMERA DUDA la he resuelto solo!!! Siii!!! En la linea


indice := l.Items.IndexOf(Edit3.Text);




La modifique haciendo esto:


indice := (l.Items.IndexOf(Edit3.Text))-2;




Con este cambio, en la variable indice, metera el item que yo pongo en el edit pero bajandolo dos casillas (por el -2).

Siguiente duda: ¿Y si ahora hay dos personas con los mismo apellidos... hermanos? Solo me sale la primera... ¿alguna manera? :o:p
Me alegro que vayas comprendiendo y logrando las cosas por ti mismo. ¿No es gratificante?:)

¿A que te refieres? ¿A que si buscas en el ListBox, a los Martinez (un ejemplo) te liste a todos los martinez?
Hay manera de hacerlo... y puede que se me ocurra una, y vuelvo al tema que comenté antes... existe la posibilidad de que lo haga de un modo al que para ti resulte chinesco.
Si pudiera conocer hasta que punto es compatible las opciones que te ofrecemos con los contenidos que tu estás estudiando sería más fácil.

El mayor problema, es el TListBox. y la manera en que estás guardando los datos. Una opción sería guardar los datos separados y delimitados por comas o algún otro caracter... y emplear las propiedades CommaText, DelimiterChar, DelimiterText, pertenecientes a Items. Pero es posible que esto sea el chinesco que a ti no te agradaría.

kbaby, lamentablemente para ayudarte del mejor modo es conociendo lo que sabes, y haz estado estudiando.
Lamento decirtelo, pero no se me ocurre, por el momento, un modo de demostrarte una solución de más bajo nivel como para el que tu comprendieras.

El método (algoritmo) más sencillo que se me está ocurriendo es algo similar a este:
1. Iniciar una variable i al valor 2. La usaremos para ir recorriendo lal ListBox.
2. Mientras i sea menor a la cantidad de elementos hacer:
2.1. Si el item i-ésimo es igual al valor buscado
2.1.1. incrementamos una variable j. Sera usada para ir agregando las filas a la "tabla". Inicialmente debe valer cero.
2.1.2. agregamos a la fila j-ésima:
2.2.2.1. en la primera columna el DNI. Cuya posición es igual a i - 2.
2.2.2.2. en la segunda columna el Nombre. Cuya posición es igual a i - 1.
2.2.2.3. en la tercera columna el Apellido. Cuya posición es igual a i.
2.2.2.4. en la cuarta columna la ciudad. Cuya posición es igual a i + 1.
2.2. incrementar a la variable i en 4.

¿Porqué lo redacté así? Para que descubras que lo que necesitas es dominar el arte de lógica, en vez de buscarle un sentido en el uso de propiedades y métodos.
Además lo hago con la finalidad de que lo pienses tu, y le encuentres solución.

El algoritmo que te pasé lo que hace es ir dando saltos de 4 en 4 sobre los items del TListBox. Si en dicha posición el contenido del ListBox es igual al buscado suceden las siguientes cosas:
1. incrementa una variable j. Es decir j = j + 1.
2. agrega en la posición [1,j] lo almacenado en el listbox, posición i - 2.
3. agrega en la posición [2,j] lo almacenado en el listbox, posicion i - 1.
etc...

Es decir que en cada ocurrencia, agrega los items que corresponde a dichos datos. Recuerda que SIEMPRE que se mantenga el orden:
DNI
NOMBRE
APELLIDO
CIUDAD

el algoritmo podrá encontrar la información.

Ten presente que el StringGrid guarda sus datos del siguiente modo:

[1,1][2,1][3,1][4,1][5,1]
[1,2][2,2]...
...
[1,N][2,N]

Espero haberte dado una idea.
Disculpa que he haya extendido, pero no veo otro modo de demostrarte lo limitado que estamos para ayudarte si te proponemos alternativas que posiblemente tu no comprendas y que no estén en tus apuntes.

Saludos,

kbaby
28-05-2008, 19:48:18
Bueno yo voy a intentar darte mas información de lo que hago. Para guardar utilizo este código:


var f:textfile; i:integer;
begin
assignfile (f,'nombres.txt');
rewrite(f);
for i:=0 to l.items.count-1 do
writeln (f,l.items[i]);
closefile(f);


Y cuando abro el programa, para "cargar" el listbox utilizo esto:


var f:textfile;
n:string;
begin
assignfile(f,'nombres.txt');
reset(f);
while not eof(f) do
begin
readln(f,n);
edit1.Text:=n;
readln(f,n);
edit2.Text:=n;
readln(f,n);
edit4.Text:=n;
readln(f,n);
edit5.Text:=n;
button1.Click; //lo que va haciendo esto, es ir poniendo en edits cada item y añadirlo automaticamente. Por eso al final limpio los edits.
end;
closefile(f);
edit1.text:='';
edit2.text:='';
edit4.text:='';
edit5.text:='';
end;


1). En la tabla NO vuelco todo el contenido, solo la persona que se apellida Martinez Perez. Pero el caso es si hay dos personas con Martinez Perez. Como poner a los dos?.

2) Y la otra duda es, una vez volcada a Pepe Martinez Perez, si le tengo que cambiar algun dato, por ejemplo su nombre (cosa que hago desde la tabla, una vez volcado cuando lo busque...) pues le doy y borro su nombre y escribo ahora Jose. Le doy a guardar y se borra TODOS LOS ITEMS del listbox, menos la "persona" con sus 4 datos (DNI,NOMBRE,APELLIDOS,CIUDAD).


El código que utilizo para borrar lo que hay en la tabla y que se guarde es este:
l.items.clear;
edit1.text:=t.cells[1,1];
edit2.text:=t.cells[2,1];
edit4.text:=t.cells[3,1];
edit5.text:=t.cells[4,1];
button1.click;

¿Que pasa? Pues que borra toda la lista y añade a esa persona con sus cuatro datos, pero las otras las pierdo. ¿Alguna otra forma?

gracias.

Delphius
28-05-2008, 20:29:07
Bueno, con respecto a buscar los martinez y mostrarlos te he propuesto una solución. ¿Porqué no la traduces a código? Sería un buen ejercicio para ti.

Con respecto al tema de porque borra el contenido del TListBox es simplemente porque al principio de todo invocas al método Clear.

No debes llamar al método Clear. Sino que debes realizar el paso inverso al algoritmo que te he pasado:
Analizemos la situación:
Antes ibamos saltando por los items de 4 en 4 y volcando la información. De este modo de cumplía lo siguiente.
Si buscamos por el apellido,
El DNI siempre está en la posición i - 2.
El Nombre siempre está en la posición i - 1
El Apellido siempre está en la posición i
La Ciudad siempre está en la posición i + 1

Por tanto, lo que hacíamos era agregar estos datos en el StringGrid del siguiente modo:
Celda[1,j] = La info de i - 2
Celda[2,j] = la info de i - 1
Celda[3,j] = la info de i
Celda[4,j] = la info de i + 1

A la inversa tenemos:

La info de i - 2 = Celda[1,y]
La info de i - 1 = Celda[2,y]
La info de i = Celda[3,y]
La info de i + 1 = Celda[4,y]

¿Se entiende? No debes hacer Clear, sino sustituir un dado de una celda por el de la posición en un índice:

ListBox1.Items[i] := StringGrid1.Cells[x,y];

¿Porque y? y no i?
El problema es que cuando agregamos desde el ListBox hacia el StringGrid perdemos referencia a la posición i-esima del campo Apellido de dicha persona. Lo más fácil es, que al agregar la información al StringGrid guardemos dicha posición para asi poder hacer el paso inverso. Tal vez, algo como esto:

Indice - DNI - Nombre - Apellido - Ciudad
De modo que en [1,j] tenemos la posición i-ésima del campo Apellido de los datos de la persona j-esima en el StringGrid.
En [2,j] su DNI.
En [3,j] su Nombre.
Y así sucesivamente.

¿Que significa ese j?
Pues la fila. De modo que si j es 1, nos referimos la persona que ocupa la fila 1 en el StringGrid. Ojo: no confundir a ese j con la posición i en el ListBox.
Cuando j vale 2, nos estamos refiriendo a la persona que ocupa la fila 2.

Por ejemplo, si en [1,1] tenemos el valor 6 quiere decir que en el ListBox, la información del apellido para dicha perona está en 6. Hacemos que i sea 6.
Por tanto:
1. El DNI está en i - 2. Es decir, 6 - 2 = 4. Item[4] = Celda[2,1].
2. El Nombre está en i - 1. Es decir, 6 - 1 = 5. Item[5] = Celda[3,1]
3. El Apellido está en i. Es decir, 6. Item[6] = Celda[4,1]
4. La Ciudad está en i + 1. Es decir, 6 + 1 = 7. Item[7] = Celda[5,1]

Cuando en [1,2] tenemos el valor 14, entonces:
DNI: 14 - 2 = 12. Item[12] = Celda[2,2]
Nombre: 14 - 1 = 13. Item[13] = Celda[3,2]
Apellido: 14. Item[14] = Celda[4,2]
Ciudad: 14 + 1 = 15. Item[15] = Celda[5,2]

¿Se entiende? Tendrás que modificar un poco tus códigos pero se consigue tener referencia a que persona estramos cambiando la información.

kbaby, te he dicho que esto se trata de lógica. No pienses en código... deja que el código salga del análisis de la situación y de un planteo del problema.

Saludos,

kbaby
28-05-2008, 20:37:14
Una cosa que he notado es que el boton que tengo de "buscar" cuando en el edit pones una palabra con espacio en mi ejemplo: apellido1_apellido2 salta error. ¿por que?

Delphius
28-05-2008, 20:48:47
Una cosa que he notado es que el boton que tengo de "buscar" cuando en el edit pones una palabra con espacio en mi ejemplo: apellido1_apellido2 salta error. ¿por que?
kbaby, si no dices el error no te podré ayudar ¿Modificaste el código de buscar? ¿Si es así, como lo tienes?

Lo siento, pero si no aprendes a aportar verdaderamente la información que nos ayude a ayudarte no podemos seguir.
La paciencia tiene cierto límite. Yo he estado siendo paciente... pero ha sido dificil sacarte la información para que te pueda asesorar.

Cuando uno dice me sale error, ¿que puede ser?... Menos ganas de ayudar me dan.
Tu ya conoces como funciona esto... el que aporta detalles recibe soluciones y alternativas, el que no tiene dos opciones:
1. lamentarse
2. Ceder parte de su tiempo en explicar acabadamente su situación

Me parece fabuloso que estés dandole a esto de programación. Es admirable porque muchos cuando lo intentan y ven que las cosas no les va se tiran abajo...
Tu no te tiras abajo, nos tiras abajo. Posteo y inmediatamente posteas. Analiza primero en frio lo que te he dicho y luego adaptalo a tus necesidades.

Por hoy, lo dejamos. Vuelve en frio, y yo tambien.

Saludos,

kbaby
28-05-2008, 20:52:01
Lo siento por no saber expresarme, pero aquí esta todo. He montado el programa en un pispas puesto que no lo tengo en mi casa sino en el instituto. Así que aqui tienes mas o menos "mi proyecto" que en el instituto esta mucho mejor hecho.

http://rapidshare.com/files/118382413/PROYECTO_INFORMATICA.rar.html

Bajalo de ahí, y veras el problema al buscar algun item que contenga espacio y el problema al modificar una persona que esta en la tabla.

Gracias, más no se que poder ofrecerte.

Llevo toda la tarde, toda, toda pero no piyo nada ni lo saco por logica. Eso del I,J no lo comprendi bien, o eso creo. Voy a volver a leerlo.

kbaby
28-05-2008, 21:04:25
ListBox1.Items[i] := StringGrid1.Cells[x,y];

Voy a comentarte. Segun ese codigo quiere decir que en el Item de posicion I (no se sabe, es una variable) se va a cambiar por la cadena que hay en la celda [x,y].

Pero ahora viene mi cuestion... siento ser tan pesado pero tengo muy poco tiempo y experiencia y por eso acudo aqui, a pedir ayuda y porque veo que es un sitio util ¿Cómo sabe el programa que vale I? Cuando yo pulse el button que le asigne el codigo, el no sabe que ITEM es... ni que CELDA he modificado. ... Eso es mi problema. Gracias.

Delphius
29-05-2008, 20:48:47
kbaby, antes que nada te recuerdo algo que tu habías dicho:

y no puedo llevar algo que no haya yo enseñado.
Y esto lo hago no con la finalidad de ser pesado sino de hacerte notar de que muchas veces uno por ponerse a ser original termina descubriendo cosas que están fuera de nuestra comprensión y atentan con lo que estuvimos haciendo.

El que nos digas a nosotros que quieres hacer esto, hacer esto otro... y a riesgo de que nos saltes diciendo algo parecido a esto:

Pero eso no lo vi en clase. ¿Hay una forma de hacerlo más fácil? No puedo usar algo que no me enseñaron.

Nos pone en una situación difícil. Porque sin conocer hasta donde llegan tus conocimientos no vamos a poder ayudarte.

Pusiste a disposición tu código fuente, lo estuve viendo... En cuanto a estética deja que desear, pero eso no es problema.
En cuanto a código... también deja que desear. Puede mejorarse.
Y es aquí donde voy a hacer una pausa para darte algunos consejos:
1. Declaración de variables. Debes declarar a tus variablesy controles de mejor manera. Un "l", un "t" no es adecuado. Termina confundiendo más. A veces es mejor tener un StringGrid1, que un t.
2. Mucho código puede reducirse y compartirse entre los controles. Aqui debo volver hacia lo que te dije al comienzo de este post: Al no saber hasta donde llegan tus conocimientos no sabría decirte y preguntarte el porqué no haces usos de procedimientos y funciones. Buena parte del código se ahorra teniendo funciones y procedimientos que hagan las tareas comunes e invocandolas cuando sea conveniente.

Código Delphi [-] (http://www.clubdelphi.com/foros/#)ListBox1.Items := StringGrid1.Cells[x,y];


Voy a comentarte. Segun ese codigo quiere decir que en el Item de posicion I (no se sabe, es una variable) se va a cambiar por la cadena que hay en la celda [x,y].

Pero ahora viene mi cuestion... [I]siento ser tan pesado pero tengo muy poco tiempo y experiencia y por eso acudo aqui, a pedir ayuda y porque veo que es un sitio util ¿Cómo sabe el programa que vale I? Cuando yo pulse el button que le asigne el codigo, el no sabe que ITEM es... ni que CELDA he modificado. ... Eso es mi problema. Gracias.

Creo que fui claro en mi post anterior. He dicho que cuando se hace el volcado desde el TListBox hacia el TStringGrid (te sugiero que empieces a llamar las cosas por su nombre, un StringGrid no es una tabla; es una rejilla en todo caso) perdemos la referencia hacia que elemento nos referimos.
Debido a ello es que cuando deseamos hacer el paso inverso no sabemos a quien atribuírsele.
¿Como se soluciona esto?
Lo he dicho en el post anterior: Una alternativa es que al volcar los datos, usar la primera columna para hacer referencia al índice en cuestión. De modo que con leer dicha celda sabemos a que índice o posición (ya sea del Apellido, DNI, o el que fuera) podemos aplicar el paso inverso valiendonos de un corrimiento por arriba y debajo de dicho indice.

No interesa si modificaste uno o varios campos. El proceso funciona igual. ¿Que importa si antes un campo tiene PEPE y lo sustituímos por PEPE? ¿Afectó en algo?
Si por cuestiones de "perfomance" deseas evitar recorrer todos los elementos, deberías llevar un registro de cuales son las celdas que han sido editadas. Y esto implicaría más código...
Y más código, sobre todo para ti y la funcionalidad que buscas, es más de lo que estarías dispuesto a hacer. Nuevamente volvemos a lo que te he dicho al inicio: ¿Cuanto sabes? ¿Que puedes usar? ¿Que no puedes usar?
¿Si te ofresco una solución, cuál es la probabilidad de que entiendas de lo que hablo?

Digo... si me baso en lo que pasó al explicarte sobre el uso de la función inc()... ¿que puedo esperar si te ofrezco un algoritmo que lleve registro de las celdas editadas y luego recorrerlas a fin de aplicar los cambios adecuados?
Un algoritmo como ese implica de una u otra forma el uso de una estructura de datos dinámica, ya sea que termine usando un array dinámico, un TList, un lo que sea.... lo más seguro es que termines diciendome nuevamente que no entiendes y/o que no viste nada de eso y no puedes usarlo.

kbaby, te he dicho que tus problemas están en la lógica. Y ahora lo veo también por la prisa que tienes de hacer tu "tarea".

Con respecto al error que dices, no me arroja error. El algoritmo que tienes funciona tanto para un apellido simple como para uno compuesto. Da lo mismo que pongas MARTINEZ que MARTINEZ VELASQUEZ. Si en el TListBox existe, lo encontrará. Lo acabo de probar, no alteré el código... FUNCIONA.

Habría que ver que es lo que realmente haz puesto tu, a lo mejor fue un despiste "de dedo".

kbaby, ¿Recuerdas como empezaste en el Club? Varios foristas salieron a tu ayuda y tu lograste dar con la solución.
¿Porqué no haces nuevamente eso? Analiza el problema, deja de pensar en TListBox, en TStringGrid.... borra de tu mente el código y piensa objetivamente sobre la raiz del problema. Olvidate de la PC, agarra un lapiz, y papel. Y describe tu problema. Todo en forma textual... ahora piensa un poco y redacta en la forma una solución.
¿Listo? Luego a cada oración, párrafo o idea buscale un sentido en programación.

Ese ejercicio te puede ayudar a comprender que los mayores problemas no están en el lenguaje sino en tu cabeza.
No es mi intensión llamarte tonto, ni nada de eso. Sino que lo que nos detiene a muchos aquí es que se meten en un código buscando que la idea se adapte a él, cuando es la inversa lo que debe suceder.

Hace tiempo te comunicaste conmigo pidiendome una opinión sobre que carrera te convenía. En vista a que quiere meterte en informática, y tal parece por lo que me comentaste, te gusta mucho esto de la programación.
No es por asustarte ¿pero sabes los golpes que nos damos a diario muchos aqui?
No pretendo decir que esto no es para cualquiera... porque no es ni lo uno ni lo otro.
Hazme caso kbaby... Piensa en frio. imagina a las cosas de manera más simple, buscale a los problemas una representación similar a algo real, algo que ya hayas resuelto. Incrementa tu habilidad de abstracción.
¿Me creerías si te digo que me imagino al TStringGrid como varias pilas de platos una al lado de la otra? ¿Me creerías si te digo que le encuentro al procedo del volcado inverso una analogía al proceso de desapilar las pilas de platos?

Si... tal vez te parezca que me he estado dando unos cuantos golpes y que he salido con unos extraños personajes de los años 70 que profetizaban la frase "paz y amor, viejo". Pero lo cierto es que prefiero no matarme buscando adaptar la idea al código, sino que la idea me de el código.

Lenguajes hay muchos, y cada uno te puede hacer más o menos fácil la vida. Y no tiene sentido que te aprendas el lenguaje.
Aqui muchos preferimos Delphi, a mi me gusta... pero ¿cuanto se de él? ¿Un 20%? ?Un 50%? ¡Pues que importa! si lo que realmente importa es resolver el problema....

Piensa en frio.
Tal vez estas palabras te sean rudas... No es mi intención que así sea.
Noto en ti muchas ganas de aprender y disfrutar de esto. Y ando buscando el modo de demostrarte, y creo que lo que ha estado sucediendo en este hilo lo está demostrando en parte, de que las cosas no se hacen de un día a otro.
A su tiempo.
Analiza en frio el problema, y mi propuesta. ¿Existe otra manera? Muy posiblemente. Me extraña que otros no se hayan animado a ofrecerte ayuda.

Esto si será rudo: No te voy a resolver el código, porque considero que allí no está el problema. Creo que hay un bosque que te tapa el arbol ¿O se trata de que un Arbol te tapa el bosque?;)

Saludos,

Fenareth
29-05-2008, 21:20:37
...Olvidate de la PC, agarra un lapiz, y papel. Y describe tu problema. Todo en forma textual... ahora piensa un poco y redacta en la forma una solución.
¿Listo? Luego a cada oración, párrafo o idea buscale un sentido en programación....

Para mí esta frase da exactamente en el clavo de lo que la programación es y resuelve, al final es un proceso de automatización y de manejo de información, pero no solucionará nada que no pueda ser resuelto por métodos convencionales y primitivos...

Si aún no encuentras esa respuesta convencional y primitiva cómo es que la automatizarás ? No puedes hacer más fácil algo que no sabes cómo se hace de ninguna manera...

El consejo que te da Delphius te permitirá darte cuenta de que el problema no es tan difícil como lo crees, simplemente te falta sentarte y realmente analizarlo...

Saludos :)

kbaby
30-05-2008, 14:45:11
Bueno, yo he leido los dos post y pienso que entiendes como si yo no hiciera eso. Claro que lo hago, pero llega un momento que lo que yo he aprendido me pone una barrera que no me deja acceder a otras cosas. Yo solo puedo hacer cosas limitadas. Eso sí, nos dejaron indagar en libros, internet, foros, para aprender cosas nuevas e implantarlas en el proyecto final. Por eso estoy aquí, preguntando cosas de las que NUNCA he odio hablar.

Con respecto a la estetica... fue un programa que hice en 10 o 15 minutos rapidamente para que veas como lo tengo organizado en el aula de informatica... pero allí uso 3 formularios, imagenes, paneles.... En mi casa lo que hago es pensar en un codigo para luego, ponerlo allí, pues solo tengo 1 hora de informatica y alli no puedo pensarlo. En mi casa lo pienso y lo pruebo y me lo apunto en mi libreta de delphi.

Yo pienso que hago todo lo posible por aprender, no he llegado al extremo de imaginarme esas cosas que me dijiste el final, pero si a dibujarlo e intentar solucionar las cosas "dificiles" con procedimientos faciles...

Lo de "t" a la <rejilla> y lo de l al <listbox> tienen ese nombre porque así me enseño mi profesor. Nos dijo que para ser mas rapidos, usaramos variables cortas y facil de recordar... en ningun momento lo eleji yo.

Hoy estuve en informatica, ya me queda muy poco por acabar. Os cuento de lo que hace mi proyecto ^^
- Añade a personas (al listbox)
- Las modifica (aunque al modificar una, se borra todas del .txt).
- Puedes bucar a personas por DNI, apellidos, telefono (gracias Delphius).
- Puedes ver el estado del hotel (% de habitaciones ocupado, gente dentro...)
- Mi super boton close; (para salir :P)

¿Qué me queda?
- Arreglar lo de modificar a las personas y que se guarde.
- Poder buscar y ver en el StrinGrid1 (lo dije bien ehh) todas las personas que sus apellidos sean MARTINEZ LOPEZ y no solo, la primera.


Eso es todo.

Espero que no pienses que soy un vago que lo quiere todo hecho. Me he leido la caraocultadedelphi, el libro que me compre en la feria del libro por 1€ (si ese), he consultado en personas que saben (sin encontrar ayuda por parte de ellas), he venido al foro y entré, desde el primer miomento que di programacion. Yo tengo aun la idea en mi mente de poder ser informatico, alomejor programando no valgo (cosa que no me preocupa, intentare conseguir la meta) pero dentro de la informatica hay muchisimos campos.

Gracias.

PD: Lo de apellidos compuesto ya se porque me tiro error, por el error de "dedo".
Gracias

kbaby
30-05-2008, 17:52:08
Pues aquí, desde el último post, estaba indagando un codigo para borrar del LISTBOX a una persona que tengo volcada en un StringGrid. Pues el código que se me ocurrio fue este:


var a,i:integer;
begin
a:=t.row;
for i:= 0 to 3 do l.items.delete(a+i);


Pero el problema es el siguiente si mi listbox es:
0-dni
1-nombre
2-apellidos
3-telefono
4-(y asi, sucesivamente).

Lo que hara es borrar el dni y entonces "nombre" pasara a la posicion "0" y así todos bajan una. Por lo siguiente, al repetir el FOR, borrará a+1 "posicion 2" ... el telefono de la persona...

Bueno voy a seguir intentando sacar codigo (te estoy haciendo caso, con papel y lapiz).

--------------------Minutos despues.......---------------------------

Aquí estoy, se me iluminó la bombilla y... tachán! Mirad que código mas sencillo para borrar a una persona (dni,nombre,apellido,ciudad) sin borrar las otras.

var a,i:integer;
begin
a:=t.row;
l.items.delete(a-1);
l.items.delete(a-1);
l.items.delete(a-1);
l.items.delete(a-1);

Delphius
30-05-2008, 18:41:55
Bueno, yo he leido los dos post y pienso que entiendes como si yo no hiciera eso. Claro que lo hago, pero llega un momento que lo que yo he aprendido me pone una barrera que no me deja acceder a otras cosas. Yo solo puedo hacer cosas limitadas. Eso sí, nos dejaron indagar en libros, internet, foros, para aprender cosas nuevas e implantarlas en el proyecto final. Por eso estoy aquí, preguntando cosas de las que NUNCA he odio hablar.

kbaby, en ningún momento te he dicho que seas flojo. Sino que estás un poco impaciente. Lo mejor es hacer las cosas a su ritmo.
Con respecto a lo que te había comentado antes, si te lo digo es porque al intentar explicarte el uso de inc() tu mismo dijiste que no puedes poner nada que no haya sido visto.

Y si no puedo estar seguro de que has visto o no haz visto... ¿de que modo te puedo ser de ayuda?

Ahora, si estás aqui con la finalidad de ver cosas nuevas y mejorar el código. Entonces, aquel comentario que mi hiciste sobre de que no puedes poner nada visto está de más y tus preguntas debieron hacerse de otro modo para que nosotros si te pudieramos ofrecer alternativas.
Por el modo en que redactabas tus dudas se vee reflejado el deseo de "apagar un incendio" y no de ver buscar alternativas.

Si para el trabajo final puedes poner otras cosas y sustituir algunos códigos te sugeriría que te evitaras ese código para abrir y guardar en el archivo.
Es mucho más cómodo el método LoadFromFile y SaveToFile del cual disponen tanto el TStringGrid como como el TListBox y te aseguras de que lo está "escrito" en pantalla se guardará.
También podría ser útil el uso de funciones y procedimientos.
Mucho código del cual empleas puede concentrarse en unas pocas funciones y/o procedimientos y con ello evitar repitir código.

En ocasiones tener un:

procedure TForm1.Button1Click(Sender: TObject);
var Indice: integer;
begin
Indice:= BuscarPaciente(Edit1.Text; BUSCAR_POR_DNI);
if Indice <> -1
then ...
else MessageBox(....)
end;

Es mucho más conveniente que estar implementando en varios controles el mismo o similar código. En este ejemplo, BuscarPaciente es una función que recibe en el primer parámetro el texto a buscar, el segundo parámetro es una constante definida y sirve para establecer el criterio de búsqueda.
Si Se diseña un algoritmo que busque por cualquier criterio, puede usarse en distintas partes y sin ningún cambio, sólo basta con suministrar el criterio adecuado.

El algoritmo que te yo te di como ejemplo puede fácilmente ser adaptado a esta necesidad con unos pocos cambios.


Con respecto a la estetica... fue un programa que hice en 10 o 15 minutos rapidamente para que veas como lo tengo organizado en el aula de informatica... pero allí uso 3 formularios, imagenes, paneles.... En mi casa lo que hago es pensar en un codigo para luego, ponerlo allí, pues solo tengo 1 hora de informatica y alli no puedo pensarlo. En mi casa lo pienso y lo pruebo y me lo apunto en mi libreta de delphi.
[/delphi]
El comentario que te hice sobre estética no fue con la intención de atacar. Sino un comentario que debe ser tomado con ligereza. Si lees bien, he dicho: "pero ese no es el problema".

Y no lo es porque yo pongo atención a la lógica y no a la pantalla... Yo dejo la interfaz para el último, y si tengo que ir haciendola, la hago burdamente.
Sólo lo hice para recordarte de que al final debes mejorarla.
El problema de la gran mayoría de los sistemas es de lógica y no de interfaz. Por eso a mi poco me importa como se vea... fue un simple recordatorio para cuando termines.


[quote=kbaby;290150]
Yo pienso que hago todo lo posible por aprender, no he llegado al extremo de imaginarme esas cosas que me dijiste el final, pero si a dibujarlo e intentar solucionar las cosas "dificiles" con procedimientos faciles...

Ninguno nace aprendiendo.
Yo no me creo genio, ni un experto. Esta profesión, como cualquier otra requiere de constancia. Y las cosas no salen de un día a otro.
De hecho, hay un algoritmo que yo todavía lo tengo trabado (pero gracias a Dios, no es vital) y el compañero Seoane me lo dió vueltas en una patada.
Hay cosas que nos salen, otras que no.
Y con el tiempo comprenderás que lo que cuesta ahora en un futuro lo verás como (perdón por la palabra) una estupidez.

Yo te he recalcado algo: analizalo en frio.
Y es así porque he notado que en el momento en que posteabas te quedabas esperando a que posteara. Y ni bien yo posteaba no pasaban muchos minutos y ya había un post tuyo diciendo que tenías problemas para entender mis propuestas.
Algunas veces las soluciones no se hallan en minutos ni en días. Aprenderás esta lección cuando estés estudiando en la universidad y/o salgas a la calle.
No desesperes, porque es lo último que debes perder.



Lo de "t" a la <rejilla> y lo de l al <listbox> tienen ese nombre porque así me enseño mi profesor. Nos dijo que para ser mas rapidos, usaramos variables cortas y facil de recordar... en ningun momento lo eleji yo.

Es cierto lo que te comenta el profesor. Es preferible variables cortas. ¿Pero una sola letra?
kbaby, los extremos son peligrosos: Muchas son muchas, pocas son pocas.
¿Te gusta leer esto?:

ComboQueTieneLosHorariosDeLosPacientes.ItemIndex := 5;

¿Y esto otro?:
a.Expr := '(5 x %2');

En el primero tenemos un caso en que hay demasiado información. En el segundo en el que hay poca.
Mientras que el primer caso se sobre entiende que se trata de un Combo, en el segundo, No sabemos que es a, y el porqué existe lo que pareciera ser una Propiedad llamada Expr que vaya a saber que hace.

Lamento decirlo pero tu profesor tiene razón parcialmente.


Hoy estuve en informatica, ya me queda muy poco por acabar. Os cuento de lo que hace mi proyecto ^^
- Añade a personas (al listbox)
- Las borra (la que tu quieras)
- Las modifica (aunque al modificar una, se borra todas del .txt).
- Puedes bucar a personas por DNI, apellidos, telefono (gracias Delphius).
- Puedes ver el estado del hotel (% de habitaciones ocupado, gente dentro...)
- Mi super boton close; (para salir :P)

¿Qué me queda?
- Arreglar lo de modificar a las personas y que se guarde.
- Poder buscar y ver en el StrinGrid1 (lo dije bien ehh) todas las personas que sus apellidos sean MARTINEZ LOPEZ y no solo, la primera.

Me alegra saber que te queda poco.
Creo que te he dado buenas pistas. ¿Las repasamos desde tu punto de vista como la entiendes? Yo entiendo el problema... hace falta que aquí comprendamos tu visión de la propuesta.
Te propongo que redactes lo que entiendes de mi propuesta.

Para el caso de la búsqueda de todos los pacientes con determinado apellido, el algoritmo que tienes en volcar te debe ser de orientación.
De hecho haste esta pregunta ¿Que diferencia existe entre volcar toda la información de un TListBox de volcar sólo la que coincide con cierto criterio?

Una pista más:
Por "cada item" hacer:
1. ¿Es igual a criterio?.
1.1. SI: entonces agreamos sus datos a la rejilla
1.2. NO: entonces no hacemos nada.

Lo de guardar los datos es la inversa de volcar. Pasar lo que haya en el TStringGrid hacia el TListBox. He aquí que para hacerlo debemos contemplar una situación que ya he explicado y me gustaría "oir" que es lo que entiendes y no entiendes de mi propuesta. ¿Cómo te lo estabas imaginando?




Espero que no pienses que soy un vago que lo quiere todo hecho. Me he leido la caraocultadedelphi, el libro que me compre en la feria del libro por 1€ (si ese), he consultado en personas que saben (sin encontrar ayuda por parte de ellas), he venido al foro y entré, desde el primer miomento que di programacion. Yo tengo aun la idea en mi mente de poder ser informatico, alomejor programando no valgo (cosa que no me preocupa, intentare conseguir la meta) pero dentro de la informatica hay muchisimos campos.

Gracias.

No pienso que eres vago, sino que estás apresurado. Y ello ye hace no ver las cosas del mejor modo.
Es bueno que leas libros, son de ayuda. Pero en los libros es posible que no encuentres la receta para preparar el algoritmo para buscar más de un paciente. Esto, lamentablemente, se aprende por ensayo y error.

Yo me vivo dando golpes con código kbaby... por algo he dicho y sigo sosteniendo: es una actividad mental, muy humana. Y al ser humanos, nos vemos movidos por miles de cosas.

Me alegro que sientas la convicción y ganas de estudiar sobre informática.
No digo que seas mal programador. Nunca he dicho eso...
Sólo te digo estas cosas para que te prepares, mentalmente, para cuando tengas dificultades.
No es agradable darse golpes... hay que aprender a vivir con ellos. Y no sólo en la vida profesional, sino en lo personal, en lo anímico, en lo sentimental, en lo existencial.

Muy cierto que la informática es amplia, y como te había comentado por MP: debes informarte y asesorarte bien sobre que del amplio abanico de posibilidades deseas enfocarte.

Yo no prefiero darte código kbaby... y me parece que es la decisión adecuada. Porque es necesario que logres ver donde está el problema... el porque te cuesta hallar el paso inverso (StringGrid a TListBox). Creeme que es lo mejor para ti, porque no sólo te sentirás mejor por encontrar tu mismo hecho el algoritmo sino porque comprenderás al problema y lograrás formular una solución.

Y creeme que te digo que la solución está en tus narices. Cuando la encuentres dirás, posiblemente algo como esto: "Pero que g... que soy. Si había sido una tontera".

¿Que diferencia a un TListBox de un TStringGrid?
Pues yo veo a un TStringGrid como una varios TListBox horizontales, uno debajo del otro.
ListBox1: [0][1][2][3][4]
ListBox2: [0][1][2][3][4]
....
ListBoxN: [0][1][2][3][4]

Puede que eso te sirva de ayuda.


PD: Lo de apellidos compuesto ya se porque me tiro error, por el error de "dedo".
Gracias
No hay de que agradecer.
Puede que esa metida de dedo sea por impaciencia...

Hazme caso... redacta la comprensión que tienes de mis propuestas y vemos ¿Si?

No te sientas atacado. Si asi te has sentido, lo lamento, disculpa.
Lo que quiero es hacerte ver que esto es mucho más mental que lo que algunos piensan.
Y si deseas irte por las ingenierías, con más razón. Yo diría que repases por las dudas un poco de matemática, física y química. ¿Porqué crees que en los primeros años de la carrera verás más números que a la PC? ¿Sólo para hacer a las carreras más duras? ¿Porque son relleno? Cada materia tiene su propósito, no sólo forma parte de la cultura general.

kbaby, te deseo que tengas triunfos en la carrera. No cometas el mismo error que yo: no desesperes por unas cuantas LDC (lineas de código).

Saludos,

kbaby
30-05-2008, 19:53:56
Antetodo... vaya pedazo de texto... tienes que escribir muy rápido jaja. Bueno vamos al grano.

Lo de que me ves impaciente es por el tiempo que tengo. Estamos en exámenes finales en España porque es final de curso. El proyecto queda una semana y me siento agobiado por el tiempo y por todo lo que me gustaría ponerle y nose.

Con respecto a que no puedo usar nada de lo que no me hayan enseñado... es hasta un punto cierto. Yo puedo llevar un algoritmo "un cacho codigo, como yo lo llamo" a clase y exponerlo pero el profesor me preguntará... y bien... ¿por qué pusiste lo de inc(indice)? Al no saber la respuesta, el profesor puede que piense este chico no ha hecho el proyecto, se lo han hecho. Y no quiero que piense eso, para nada. Yo pido ayuda, pido información y comprension. Para poderle decir que:

inc(indice);

es lo mismo que

a:= indice + 1;

pero de una manera mas "correcta" creo yo.


Una cosa que me gustaría preguntar del código que tengo para buscar es que significa la línea:

if Indice <> -1

Exactamente, ¿qué es eso de <> - 1? Sí tiene que comprobar que coincida... ese número qué hace ahí?.

Con respecto a lo de usar variables largas o cortas, seguiré tu consejo para mi proyecto. Lo intentaré cambiar, jaja.

Referente a lo de volcar al StrinGrid y volcar del StrinGrid al Listbox, sé cuales la diferencia, pero no se cómo. Yo me imaginaba un código que sea algo así:

procedure TForm1.Button1Click(Sender: TObject);
var Indice: integer;
begin
Indice:= BuscarPaciente(Edit1.Text; BUSCAR_POR_APELLIDOS);
if Indice <> -1
then // bueno ahora yo pienso que debería encontrar la persona que tiene el apellido ese y volcar toda su información, pero cuando termine, seguir buscando hasta el final de la lista por si hay otra persona con ese mismo apellido y así volcarla.


Yo me acuerdo de haber utilizado el comando eof(f) pero para el botón de "recuperar" de mi listbox.


Con respecto a lo de utilizar otras formas de cargar/guardar cosas en el listbox estoy con mis orejas abiertas (más bien ojos) para escuchar lo que me expliques, mientras pueda explicarlo yo, puedo usarlo.

¿Que diferencia a un TListBox de un TStringGrid?
Pues yo veo a un TStringGrid como una varios TListBox horizontales, uno debajo del otro.
ListBox1: [0][1][2][3][4]
ListBox2: [0][1][2][3][4]
....
ListBoxN: [0][1][2][3][4]

No se me abía ocurrido, lo veía una cosa totalmente.... muy diferente xD.

Espero que esto te sirva de ayuda para ayudarme o intentar que yo piense :p

Saludos,gracias.

Delphius
30-05-2008, 20:51:43
Antetodo... vaya pedazo de texto... tienes que escribir muy rápido jaja. Bueno vamos al grano.

Algo. No mucho pero hago mi esfuerzo para escribir rápido. Lamentablemente no estoy demasiado acostumbrado a escribir sin mirar el teclado. Me cuesta un poco. Este texto lo escribí sin mirar.:) El truco está en usar la mayor candidad de dedos posibles, aunque,yo utilizo solamente entre 4 y 6 de los dedos cuanto mucho.


Lo de que me ves impaciente es por el tiempo que tengo. Estamos en exámenes finales en España porque es final de curso. El proyecto queda una semana y me siento agobiado por el tiempo y por todo lo que me gustaría ponerle y nose.

Un motivo de impaciencia. Y si te sientes así... pues... Prepárate para la carrera. Se que no suena agradable pero es así.


Con respecto a que no puedo usar nada de lo que no me hayan enseñado... es hasta un punto cierto. Yo puedo llevar un algoritmo "un cacho codigo, como yo lo llamo" a clase y exponerlo pero el profesor me preguntará... y bien... ¿por qué pusiste lo de inc(indice)? Al no saber la respuesta, el profesor puede que piense este chico no ha hecho el proyecto, se lo han hecho. Y no quiero que piense eso, para nada. Yo pido ayuda, pido información y comprension. Para poderle decir que:


inc(indice);



es lo mismo que

a:= indice + 1;
[DELPHI]



pero de una manera mas "correcta" creo yo.

Entendido. Pues comiezo de nuevo.

Inc() es una función. Y lo que hace es sumar a la variable que pases como parámetro cierta cantidad. Pero inc() tiene una particularidad, el segundo parámetro que recibe (la cantidad) puede ser omitido. ¿Que significa omitido? Que si no se pasa algún valor asume uno por defecto. Este valor por defecto es 1. Inc entonces se resume a esto:


variable := variable + cantidad;


De modo que si pones

inc(variable);

Obtienes lo mismo que hacer


Variable := variable + 1;


O igual a:


inc(variable,1);


Si pones 2, en vez de sumarle 1, suma 2.

¿Se entiende? Si te fijas. En una ocasión no paso el segundo parámetro, pero en los otros si. Si deseo que el incremento sea distinto a 5, entonces debo suministrar el segundo parámetro.


Una cosa que me gustaría preguntar del código que tengo para buscar es que significa la línea:


[DELPHI]if Indice <> -1



Exactamente, ¿qué es eso de <> - 1? Sí tiene que comprobar que coincida... ese número qué hace ahí?.
Para ello deberías entender el funcionamiento o la estructura de un TListBox, y otros componentes similares.
Los métodos de busqueda, por lo general devuelven un índice o una referencia sobre la posición que tienen en la lista.
Y la mayoría de estas listas comienzan a contar desde cero.

Si lees la ayuda sobre IndexOf() y/o otros métodos de busqueda notarás que se devuelve el valor -1 en caso de no encontrarse el elemento.

Por ello una vez buscado, se hace dicha comprobación para tomar las acciones necesarias en caso haberse encontrado y/o no encontrado.


Con respecto a lo de usar variables largas o cortas, seguiré tu consejo para mi proyecto. Lo intentaré cambiar, jaja.

A la larga te beficiará.


Referente a lo de volcar al StrinGrid y volcar del StrinGrid al Listbox, sé cuales la diferencia, pero no se cómo. Yo me imaginaba un código que sea algo así:


[DELPHI]procedure TForm1.Button1Click(Sender: TObject);
var Indice: integer;
begin Indice:= BuscarPaciente(Edit1.Text; BUSCAR_POR_APELLIDOS); if Indice <> -1
then // bueno ahora yo pienso que debería encontrar la persona que tiene el apellido ese y volcar toda su información, pero cuando termine, seguir buscando hasta el final de la lista por si hay otra persona con ese mismo apellido y así volcarla.


Yo me acuerdo de haber utilizado el comando eof(f) pero para el botón de "recuperar" de mi listbox.

Bueno... volvamos desde el comienzo...

Este caso de búsqueda es un tanto peculiar. Puesto los métodos de búsqueda devuelven la primera coincidencia.

Necesitamos que se recorra la lista. Eso lo sabemos... ¿Cómo?
Tu comprendes que el orden de los datos en la lista tiende a "repetirse" cada 4 lugares.
Independientemente de cual seal el campo buscado (DNI, Nombre, Apellido, Ciudad), debemos hacer "saltos" de 4 en 4. para ir hacia la información correspondiente de una persona a otra.
Si nos basamos en ello podemos hacer un algoritmo que haga lo siguiente:

Supongamos que buscamos por apellido. El primer apellido a localizar está en la posición 2. Si icrementamos 2 en 4, nos ponemos en el apellido de la segunda persona ¿No es cierto?
¿Me sigues?

Entonces, por cada salto, comparamos si en dicha posición el contenido del listBox es igual al buscado.
Si es igual entonces sabemos que dos posiciones antes (si buscamos por apellido) encontraremos el DNI. Una posición antes, el nombre, la que le sigue corresponde a ciudad.
Por tanto, esos datos son agregados.

¿Cuando termina el algoritmo? Cuando la variable que usamos para ir saltanto por los indices es mayor a la cantidad de elementos del ListBox.

Dentro de ese texto que te he redactado. Esta el algoritmo. Ve si tu lo descubres. Sino volvemos.

Ahora, ¿cual es el probema cuando volcamos estos datos?
Que cuando lo hacemos no sabemos si al final nos referimos a los datos de la primera persona (cuyos datos ocupan los 4 primeros lugares en el TListBox), de la segunda (cuyos datos ocupan los siguientes 4), o de la vigesima...
¿Porqué? Porque en ningún momento de la búsqueda guardamos en algún lugar que esta persona es la primera, es la segunda, la que sea...

¿Cómo lo planteo yo?
Fácil:
Cuando encontramos una coincidencia en el algoritmo anteriormente descripto, lo primero que guardo (en la primera columna del StringGrid) es dicha posición o índice. Por ejemplo, si encontré una condicencia en la posición 6. Guardo en la primera columna ese 6. Los demás datos van en las siguientes columnas.

Bueno... ese el volcado.
Ahora, el paso inverso.

Lo primero que hago, es leer la primera columna. Encuentro el 6.
Entonces, si el criterio de búsqueda fue por apellido, se que los demás datos de esta fila corresponden a los datos que se ubican en las posiciones 4, 5, 6 y 7.
¿De donde obtuve esos números? Fácil:
Si el 6 el dato correspondiente al apellido, entonces se que el DNI está dos lugares antes ( 6 - 2). El nombre está un lugar antes: ( 6 - 1), El apellido entonces está en 6. Y la ciudad en la siguiente posición ( 6 + 1).

Solo me queda hacer:

ListBox1.Items[4] := StringGrid1.Cells[2,1].
...
ListBox1.Items[7] := StringGrid1.Cells[5,1].

¿Porqué desde 2? Recuerda que en la primera, estabamos guardando indice del apellido asociado a dicha persona.

¿Que hago ahora?
Me desplazo a la segunda fila y repito el proceso:
Leo lo que que hay en la primera columna, y veo.... digamos que es 14. Si hacemos cuenta... se que esta es la tercera persona de la lista. Cuyo datos abarcan la posiciones 12, 13, 14 y 15.

Por tanto... me queda que:
ListBox1.Items[12] := StringGrid1.Cells[2,2];
...
ListBox1.Items[15] := StringGrid1.Cells[5,2];

Nota la diferencia... si bien en el StringGrid, estamos en la segunda fila... sabemos que en el ListBox esta es la tercera persona.

¿Cuando finaliza el algoritmo?
Cuando se ha lkegado al final del StringGrid.

Entonces, de esta manera, consigues sólo traspasar los datos de aquellas personas que estén en el StringGrid hacia el ListBox.
En realidad no interesa si sólo modificó una vocal, todos los campos... si antes decia Pepe, y no se modificó se sobrescribe con Pepe. Y si ahora dice Ana, va a decir Ana.

¿Cúal es el requisito fundalmental de todo esto?
Que no se llame al método Clear del TListBox. Porque eso borra todo, y por tanto se pierden referencia a los datos. Allí tienes una falla.

Tu algoritmo de guardar debe recorrer los elementos del ListBox e ir guardandolos. Creo que eso no te resultará un problema.

No lo llames a menos que se trate de abrir otros datos. Y si lo haces debes asegurarte de "limpiar" lo que tengas en el STringGrid porque se tratan de datos nuevos.


Con respecto a lo de utilizar otras formas de cargar/guardar cosas en el listbox estoy con mis orejas abiertas (más bien ojos) para escuchar lo que me expliques, mientras pueda explicarlo yo, puedo usarlo.


No se me abía ocurrido, lo veía una cosa totalmente.... muy diferente xD.

Espero que esto te sirva de ayuda para ayudarme o intentar que yo piense :p

Saludos,gracias.
Bueno... eso eso lo puedes ver para más adelante.

Eso es todo por el momento.


Saludos,

kbaby
30-05-2008, 22:20:47
Vale Delphius aquí estuve pensando pero creo que con tus palabras ya me das todo "machacado" aunque yo sea duro y no me entere. He hecho un nuevo código para que busque el DNI de la persona y lo pase a la tabla. Sólo busca a una persona, a la primera, pero no importa, lo que quiero hacer es que funcione el código hecho por mi. Aquí te lo pongo y me dices si tienes erratas, porque se me ejecuta el programa, pincho en el boton y ... "no hace nada :D".

---> CORRECCIÓN: Ya si me funciona y me busca a la persona !!! Bien !!! el fallo estaba en el signo > del while que antes puse < jaja.

procedure TForm1.Button12Click(Sender: TObject);
var salto:integer ;
begin
salto:=0;
while l.items.count > salto do
If edit7.text = l.Items[salto] then begin
t.cells[salto+1,1]:=l.Items[salto];
t.cells[salto+2,1]:=l.items[salto+1];
t.cells[salto+3,1]:=l.items[salto+2];
t.cells[salto+4,1]:=l.items[salto+3];
inc(salto,4);
end;



end;
end.

Ya tengo un boton de BUSCAR creado por mi jojojo :D gracias tio.

Delphius
30-05-2008, 22:45:40
Kbaby, vas entiendo.... el error está en que salto debe recibir inialmente el valor igual a la posición - 1 del campo a buscar. Es decir que:
Si estamos buscando Apellido, Salto debe valer incialmente 2.
Si estamos buscando Nombre, Salto debe valor inicialmente 1.
Si estamos buscando DNI, Salto debe valer inicialmente 0.
Si estamos buscando Ciudad, Salto debe valor inicialmente 3.

Recuerda que StrinGrid comienza en cero por ello:
[0] -> DNI
[1] -> Nombre
...
[3] -> Ciudad

el inc(salto,4) debe hacerse fuera del IF. Ten presente que por más que encuentre, o no... debe seguir recorriendo la lista.

Otro problema, estás sobreescribiendo la primera fila. Necesitas de otra variable, que se incremente en 1 sólo cuando haya una coincidencia, de modo que con Cells[salto +- ?,otra_variable] se consiga ir iterando fila a fila en cada condidencia.

Creo que con esto ya lo tienes.
Ya te lo di bastante regalado.

EDITO:
Otra cosa que veo, es que como dije antes, además de esos campos necesigas guardar el valor de salto para tener referencia e implementar el algoritmo de volcado inverso (desde el STringGrid hacia el TListBox).

Saludos,

kbaby
30-05-2008, 22:53:03
Fin del problema (no del hilo).

Aquí tengo el codigo made in kbaby para buscar a todos los que tienen el mismo DNI (o lo que sea).

procedure TForm1.Button5Click(Sender: TObject);
var salto,casilla:integer ;
begin
panel2.visible:=false;
edit3.Visible:=false;
button5.Visible:=false;
salto:=0;
casilla:=0;
while l.items.count > salto do begin
If edit3.text = l.Items[salto] then begin
t.cells[1,casilla+1]:=l.Items[salto];
t.cells[2,casilla+1]:=l.items[salto+1];
t.cells[3,casilla+1]:=l.items[salto+2];
t.cells[4,casilla+1]:=l.items[salto+3];
t.rowcount:=t.rowcount+casilla;
inc(casilla);
end;
inc(salto,4);
end;
end;

Funciona de maravilla jajaja.

He añadido al código un contador el de t.rowcount porque conforme encuentre a una persona la mesa en la tabla y aumente una fila.

Ahora lo siguiente que voy a hacer, es una vez volcado en la tabla (una persona o dos o las que sean) si la modifico, guardarla y que no se borren las otras. YeahhH!!!!

Fenareth
30-05-2008, 23:03:38
Fin del problema (no del hilo).

Aquí tengo el codigo made in kbaby para buscar a todos los que tienen el mismo DNI (o lo que sea).

Funciona de maravilla jajaja.

Ahora lo siguiente que voy a hacer, es una vez volcado en la tabla (una persona o dos o las que sean) si la modifico, guardarla y que no se borren las otras. YeahhH!!!!

Se siente bien cierto ??? :D ;)

Delphius
30-05-2008, 23:12:01
Fin del problema (no del hilo).
Aquí tengo el codigo made in kbaby para buscar a todos los que tienen el mismo DNI (o lo que sea).
(...)

Un momentito... ¿solo son créditos tuyos? made in kabby, powered by Delphius. :D:D:D

Se siente bien cierto ??? :D ;)
Si... se siente... bien...
Veo que mi alumnito está aprendiendo.;):):D

Saludos,

kbaby
30-05-2008, 23:19:37
:rolleyes: Que haría yo sin tí jajaja ;)

Ya le hice unos retoques al código. Bueno me voy a dormir, mañana ya miro el paso inverso:

TStringGrid -> TListBox


Buenas noches :cool:
y....


gracias

kbaby
31-05-2008, 18:00:28
Bueno! Aquí regreso :rolleyes: Con una pregunta para seguir adelantando cosas...

Quisiera utilizar un form2 (por falta de espacio) donde coloque una StringGrid (donde se volcarán todos los items de mi ListBox). Una vez volcados, quisiera hacer cálculos con ellos, el porcentaje de hombres/mujeres, el porcentaje de gente de Córdoba... etc... (eso si sé).

Mi duda es la siguiente... ¿qué tengo que hacer para en el form2 utilizar el listbox que tengo en el form1?.

Gracias.

Delphius
31-05-2008, 18:36:26
A ver... ¿Tu deseas tener una copia del STtringGrid del form1 en un TStringGrid de un form2?

Si es eso, creo que el archivo que había dejado al inicio del hilo te sirve de ayuda. Debes añadir en uses la unit del otro.

Y para "copiar" los datos necesitas recorrer fila a fila y columna a columna e ir copiandolos. Es decir:

Desde fila 1 hasta Cantidad de filas - 1 hacer:
Desde columna 1 hasta Cantidad de columnas -1 hacer:
Celda de StringGrid2 (columna, fila) = celda de StringGrid1 (columna, fila)

Espero que se entienda.
Saludos,

kbaby
01-06-2008, 14:57:11
Delphius, ¿no podría utilizar mi boton volcar en mi form2? Mira el programa que hice, sería hacer otro boton similar, pero que volcara en otro StringGrid situado en form2.

kbaby
06-06-2008, 15:27:25
Aquí estoy de nuevo. El lunes, último día para entregar mi proyecto. Está fenomenal gracias!. Bueno bueno lo unico que me queda es hacer eso de que cuando vuelco a una persona al StringGrid y la modifico desde allí, guardarla en el listbox.

Como me dijiste delphius "piensa en frio" pues eso hice. Se me ocurrió hacer esto:

1. Busco a la persona por su DNI "así me aseguro que sólamente salga 1 persona".
2. Una vez tengo a la persona (con sus datos) en la rejilla, modifico los datos.
3. Hago un button que lo que haga es borrar a esa persona1 de la lista y con los nuevos datos que hay de esa persona1 en la rejilla los vuelco a edits que luego se guardarán en el listbox.

Yo creo que se puede hacer, y sería facil ya que dispongo de conocimientos para hacerlo. Sólo quiero una opinion:

¿está bien pensado?.

Bueno! Luego mas tarde me pondre a ponerlo en práctica y ya cuando lo termine, me lo traeré para que lo veais que está muy chuuuloooo!!!.
Saludos

Delphius
06-06-2008, 17:57:26
Aquí estoy de nuevo. El lunes, último día para entregar mi proyecto. Está fenomenal gracias!. Bueno bueno lo unico que me queda es hacer eso de que cuando vuelco a una persona al StringGrid y la modifico desde allí, guardarla en el listbox.

Como me dijiste delphius "piensa en frio" pues eso hice. Se me ocurrió hacer esto:

1. Busco a la persona por su DNI "así me aseguro que sólamente salga 1 persona".
2. Una vez tengo a la persona (con sus datos) en la rejilla, modifico los datos.
3. Hago un button que lo que haga es borrar a esa persona1 de la lista y con los nuevos datos que hay de esa persona1 en la rejilla los vuelco a edits que luego se guardarán en el listbox.

Yo creo que se puede hacer, y sería facil ya que dispongo de conocimientos para hacerlo. Sólo quiero una opinion:

¿está bien pensado?.

Bueno! Luego mas tarde me pondre a ponerlo en práctica y ya cuando lo termine, me lo traeré para que lo veais que está muy chuuuloooo!!!.
Saludos

Hola kbaby, no me parece demasiado indicado realizar el borrado y luego agregarlo.
¿Si se puede modificar tranquilamente sin estar borrando e insertando para que hacer esos pasos? Sobre todo lo desaconsejo si utilizas Add en vez de Insert. Puesto que Add agrega al final, e Insert en la posición indicada en su parámetro y corriendo los demás elementos.

Si puedes localizar el indice al que hace mención los datos de dicha persona, tranquilamente puedes modificar los datos de dicho indice en el TListBox.


ListBox.Items[indice] := STringGrid.Cells[x,y];

Esa línea contra estas dos:

ListBox.Items.Delete(...)
ListBox.Items.Add(...)

No tengo Delphi a mano, pero creo que se entiende la idea.

Al volcar los datos desde el TStringGrid hacia el TListBox se sobreescriben todos los datos asociados a dicha persona.
El guardado físico (en el archivo txt) no le interesa si se modificaron 1, 3, 40 datos... guardará en el orden que se encuentren en el TListBox.

Si borras y agregas estarás corriendo los datos y si bien al final en el txt se guardarán como estan representados el efecto es distinto... Los datos inicialmente estaban en cierto orden, y al final... pueden que ya no conserven dicha posición.
Puede ser "molesto" el correr los datos de lugar.
Lo mejor sería sobreescribirlos.

¿Porqué quieres borrarlos? ¿No terminaste de comprender mi idea verdad?

Saludos,

kbaby
06-06-2008, 20:55:44
¿Porqué quieres borrarlos? ¿No terminaste de comprender mi idea verdad?

Ajá y ni logro comprenderla. Y esto se debe a que el profesor no me enseño como hacerlo y hoy se lo pregunte y me dijo que buscará por internet y yo pensé esto. Si mi listbox tiene estos items:

nombre1
provincia1
telefono1
nombre2
provincia2
telefono2

Si yo busco a una persona (a la persona 1) y la vuelco en un stringgrid. Una vez alli, modifico su nombre1 (y pongo pepe). Luego borro nombre1, provincia1, telefono1. Y añado: pepe, provincia1, telefono1. Quedando:

nombre2
provincia2
telefono2
pepe
provincia1
telefono1

El orden de las personas no altera nada, siempre que los items tengan una posicion correcta por ejemplo, todos los telefonos tendran estas posiciones:

3-6-9-12...

Mientras esos órdenes no se alteren... puedo hacerlo ¿o no?

Grax

Delphius
06-06-2008, 21:05:28
Efectivamente kbaby, los datos siguen el orden.
Pero si te fijas ahora la persona que estaba primero, queda despues de una modificación en último lugar.

Y eso, puede ser molesto.

Como es de práctica lo que estás haciendo no importa mucho. Pero en situaciones reales puede marear un poco.

Lo que tu buscas se consigue en dos pasos, lo que yo digo se consigue en uno.
Si se puede sustituir en un solo paso ¿para que hacer más de la cuenta?

Te estoy preparando una demo para que veas de lo que hablo. Dame unos minutos más y te la tengo lista.

Saludos,

kbaby
06-06-2008, 22:20:40
Pues gracias. Al menos se que puedo preparar un codigo, por feo que sea, pero "pienso en frio" con papel :P

Jajaja. Gracias tio.

Delphius
06-06-2008, 23:28:12
Bueno kbaby, he terminado el ejemplo. Espero que con el ejemplo se entienda.
El ejemplo consiste en un código que guarda y abre un archivo de texto.

Puedes comprobar que funciona para uno o más datos... no importa cuandos cambios sean. Notarás que que se hacen en directo: en su posición natural. Nada de estar eliminando y agregando.

Separé el código en funciones y procedimientos a propósito para tu notaras como es que se reutiliza código y además para no darte todo regalado.
Estudia el código no pierdas esfuerzo en comprender que es un procedimiento y que es una función. Lo descubrirás a medida de veas código.

Te explico porqué funciona.
Básicamente tenemos una estructura de esta forma en el archivo:

0 - DNI
1 - NOMBRE
2 - APELLIDO
3 - CIUDAD

y se va repitiendo. Bueo imagina ahora que la primera persona tiene un valor indice 0. La segunda un indice 1, y asi sucesivamente. Entonces podemos afirmar esto:


Posicion en archivo | Indice o posición de la persona
-----------------------------------------------------------------
0 - DNI1 | 0 - Persona1
1 - Nombre1 |
2 - Apellido1 |
3 - Ciudad1 |
.................................................................
4 - DNI2 | 1 - Persona2
5 - Nombre2 |
6 - Apellido2 |
7 - Ciudad2 |
.................................................................


Si te fijas bien, el indice a cada persona incrementa sólo cuando se tienen todos los datos. Por tanto si extraemos el dato para la persona1, sus datos iran desde 0 a 3, para la segunda de 4 a 7.
¿Que tiene en común el indice con la posición de los datos?
Fácil: su división entera con 4.
Hagamos cálculos:

0 div 4 = 0
...
3 div 4 = 0
4 div 4 = 1
...
7 div 4 = 1
8 div 4 = 2

Veamos... en posición 8, quien comienza... exacto! Una nueva persona.
¿Que hago yo?
Me valgo de ese indice para tener referencia a la persona. Ese indice lo tengo que guardar en algún lado para poder recuperar los datos desde la rejilla hacia el LisBox.

Yo preferí guardar ese dato, en la columna 0 de la rejilla de modo que se impida modificarlo. En las demás celdas de dicha fila se guardan sus datos.

¿Cómo se hace entonces?
1. Leer de la fila i-ésima del StringGrid la columna 0. Guardar dicho dato en una variable. Yo la llamé indice.

indice := STringGrid1.Cells[0,i] // i: i-ésima fila

2. Teniendo ese índice puedo hacer el paso inverso:

2.1. Como en la columna 1 (j = 1) tenemos el DNI, entonces el DNI para dicha persona en el ListBox ocupa la posición k = (Indice x 4)

Entonces hacemos:

ListBox1.Items[k] := TStringGrid.Cells[1,i]

2.2. Como en la columna 2 (j = 2) tenemos el Nombre, entonces el Nombre para dicha persona en el ListNox ocupa la posición k = (Indice x 4) + 1:


ListBox1.Items[k] := TStringGrid.Cells[2,i]

2.3. Como en la columna 3 (j = 3) tenemos el Apellido, entonces el Apellido
para dicha persona en el ListBox ocupa la posición k = (Indice x 4) + 2:


ListBox1.Items[k] := TStringGrid.Cells[3,i]

En forma general se tiene que cualquier dato ocupa una posición k-ésima en el listBox en base a esta fórmula:

k := (Indice x 4) + (j - 1)

Siendo j la columna del dato que leemos.

De forma inversa, podemos afirmar que:

STringGrid1.Cells[PosDato,i] := ListBox1.Items[(Indice x 4) + (PosDato - 1)]

Siendo PosDato la posición en que vienen:
1 -> DNI
2 -> Nombre
3 -> Apellido
4 -> Ciudad

Nuevamente, aconsejo revisar el código que te paso. Haz lo siguiente, seleccona algún botón, por ejemplo el Botón "Buscar Todos". Haz doble click y verás esto:

procedure TfrmPrincipal.bBuscarTodosClick(Sender: TObject);
var cantidad: integer;
begin
LimpiarRejilla;
cantidad := BuscarYVolcar(eBuscar.Text,rgOpcion.ItemIndex);
if Cantidad = 0
then ShowMessage('No se encontraron concidencias')
else begin
sgRejilla.Enabled := true;
bVolcarAListBox.Enabled := true;
end;
end;

¿Que es ese LimpiarRejilla?
Para saber lo que hace, debes presionar Crtl y dar click en dicha línea. Notarás que mientras tengas presionada la tecla Crtl, el cursos cambiará a la forma de mano y que el código parece ser un link.

Pues eso es: te "linkea" hacia el código. En este ejemplo al código de LimpiarRejilla.
De igual manera puedes hacer con BuscarYVolcar, y cualquier código que veas.

Y nuevamente, analiza en frio y notarás como funciona el código.
Te aconsejo que primero lo compiles y pruebes el ejecutable, sin mirar código... después analiza el código.

Está correctamente escrito con comentarios para que se entienda.

Espero tus novedades.

Saludos,

kbaby
07-06-2008, 10:32:22
Bueno como aquí tenemos mucho que hablar, voy a ir botton por botton para ir diciendo que tal me parece y darte gracias.

Button abrir: ¡Que bien queda! No me imaginaba que se podía hacer eso. A mi me enseñaron el otro procedimiento para abrir un archivo y claro, utilizaré ese para mi proyecto final. Pero para mis futuros programas, el que vi que utilizaste me parece muy bueno. Es que queda profesional jajaja. Gracias.

Button Guardar: ¿Yo puedo sustituir mi código entero por el que ví en tu button?
lbArchivo.Items.SaveToFile(Ruta);

Ese código, es muy pequeño para el que tengo que poner yo para guardar.
¿En qué se diferencia cada uno? Del que uso yo, al que usas tu.
Gracias.


Button Volcar al TSringGrid:
LimpiarRejilla;
VolcarARejilla;
sgRejilla.Enabled := True;
bVolcarAListBox.Enabled := True;

¿Y ese código tan pequeño? Yo uso, como puedes ver en mi anterior subida para que veais mi proyecto... un código muy largo y que hace, exactamente lo mismo. ¿Ese código lo puedo utilizar yo o necesito tocar antes algunas opciones de algun elemento?.
Me llamó la atencion lo de "LimpiarRejilla" "VolcarARejilla". ¿Delphi entiende las palabras en español?.
Gracias.

Button Buscar: Me parece genial el código. Pero... como... yo estuve casi una tarde pensando en otro código (powered Delphius) pues... :p usaré el que estuve pensando. Jajajaja. Pero gracias.
Lo de los criterios de búsqueda creo que me va mal o no se usarlo. Si yo pincho en el criterio DNI y pongo Guadalupe en la búsqueda. Me sale el usuario Guadalupe y en realidad tendría que salir que no hay paciente con ese DNI. Pienso :P Y cuando pincho en Buscar Todos me salta error.
Gracias.

Button Volcar al TListbox: ¿Es necesario que en la columna 0 salgan los número del indice de la persona? El código lo estoy aún pensando porque "GuardarCambios" ese comando... ¿delphi lo entiende? Es un comando en español y suponía que delphi entendía solo ingles.
Gracias.

Delphius, tengo que ir a clase que empiezan a las 12.00 (españa). Luego me detendre para ver el Ejemplo y apuntarme codigos en mi libreta. Luego te cuento mas cossas que tengo en la punta de la lengua.

Muchas Gracias



-----edito---------

No me había leído lo de Pulsar CTRL para ver loq ue hace lo de LimpiarRejilla, Guardar. No respondas a esas preguntas, estoy como tu dices: "analizando el código en frio".

Delphius
07-06-2008, 18:43:33
Bueno como aquí tenemos mucho que hablar, voy a ir botton por botton para ir diciendo que tal me parece y darte gracias.

Button abrir: ¡Que bien queda! No me imaginaba que se podía hacer eso. A mi me enseñaron el otro procedimiento para abrir un archivo y claro, utilizaré ese para mi proyecto final. Pero para mis futuros programas, el que vi que utilizaste me parece muy bueno. Es que queda profesional jajaja. Gracias.

Button Guardar: ¿Yo puedo sustituir mi código entero por el que ví en tu button?lbArchivo.Items.SaveToFile(Ruta);


Ese código, es muy pequeño para el que tengo que poner yo para guardar.
¿En qué se diferencia cada uno? Del que uso yo, al que usas tu.
Gracias.


La diferencia es que tus códigos para abrir y guardar son de un nivel más bajo. trabajas en forma "directa" con el archivo. Mientras que yo, empleo la biblioteca VCL que ofrece Delphi. Como esta amplia biblioteca ya cuenta con objetos y clases que trabajan con archivos me evito el código que tu expones.

Cuando hacía mis prácticas en Pascal, cuando me iniciaba en lenguajes, debía trabajar del mismo modo que tu. Y de hecho, cuando me inicié en Delphi también lo segui haciendo. Si te resulta agradable tu método úsalo.


Button Volcar al TSringGrid:


LimpiarRejilla;
VolcarARejilla;
sgRejilla.Enabled := True;
bVolcarAListBox.Enabled := True;



¿Y ese código tan pequeño? Yo uso, como puedes ver en mi anterior subida para que veais mi proyecto... un código muy largo y que hace, exactamente lo mismo. ¿Ese código lo puedo utilizar yo o necesito tocar antes algunas opciones de algun elemento?.
Me llamó la atencion lo de "LimpiarRejilla" "VolcarARejilla". ¿Delphi entiende las palabras en español?.
Gracias.

Pues, yo me las ingenio para que Delphi entienda español;) Aunque escribí ese código en castellano para que tu entiendieras. Por lo general escribo mis códigos en inglés... Delphi entiende mejor el inglés;).

Antes de usarlo, entiende que és y que hace.


Button Buscar: Me parece genial el código. Pero... como... yo estuve casi una tarde pensando en otro código (powered Delphius) pues... :p usaré el que estuve pensando. Jajajaja. Pero gracias.
Lo de los criterios de búsqueda creo que me va mal o no se usarlo. Si yo pincho en el criterio DNI y pongo Guadalupe en la búsqueda. Me sale el usuario Guadalupe y en realidad tendría que salir que no hay paciente con ese DNI. Pienso :P Y cuando pincho en Buscar Todos me salta error.
Gracias.

Me olvidé de decirtelo.:o
Buscar trabaja en forma independiente del criterio de búsqueda. Encuentra la primera concidencia dentro del todo el TListBox. Si pones un DNI y lo encuentra muestra los datos de dicha persona; si pones una Ciudad y la encuentra... también funciona. Como dije: es independiente.

En cambio, Buscar Todos necesita del criterio. Buscará todas las coincidencias según el criterio establecido.


Button Volcar al TListbox: ¿Es necesario que en la columna 0 salgan los número del indice de la persona? El código lo estoy aún pensando porque "GuardarCambios" ese comando... ¿delphi lo entiende? Es un comando en español y suponía que delphi entendía solo ingles.
Gracias.

Pues yo preferí que liste los indices en dicha columna para impedir que se modifique. Si lo hago que lo liste en la columna 1, un error de dedo puede hacer fallar a todo el código.
Por ejemplo, supongamos que lo ponemos en la columna 1. Se vuelcan los datos... hago doble clic en la celda y borro ese indice y pongo otro...

¿A donde van a parar los cambios? A otro lugar. Y si en vez de un número pongo una letra... ¡peor! lindo error vas a obtener.

Entonces, para evitarme lios. el indice es inalterable y por ello está listado en la columna 0.

Repito... yo me las ingenio para que entienda Español, aunque si deseas... puedo probar a ver si entiende italiano.:D;)


Delphius, tengo que ir a clase que empiezan a las 12.00 (españa). Luego me detendre para ver el Ejemplo y apuntarme codigos en mi libreta. Luego te cuento mas cossas que tengo en la punta de la lengua.

Muchas Gracias



-----edito---------

No me había leído lo de Pulsar CTRL para ver loq ue hace lo de LimpiarRejilla, Guardar. No respondas a esas preguntas, estoy como tu dices: "analizando el código en frio".

Algunas cosas sería bueno que te explicara, pero a modo de pistas... para que te ayuden a combatir un poco el frio.

¿Que diferencia notas entre esto:

procedure bAbrirClick(Sender: TObject);

y

procedure GuardarCambios(Fila: integer);

Fuera del idioma. Ambas cosas son lo mismo. Si te fijas... ambos tienen una palabra rara llamada procedure. Esto significa que son procedimientos.

El primer caso significa que el procedimiento corresponde a un Click del botón bAbrir y el segundo procedure lo que hace es guardar cambios. ¿Cúando se ejecuta el procedimiento?

Cuando sea necesario. Un procedimiento puede ser llamado por otro.

Ve al procedimiento y a la función como un conjunto de lineas de código que se ejecutan en cuanto se lo solicitan.

Hay funciones y procedimientos que tienen paréntesis. Por ejemplo el procedure GuardarCambios. Dentro de ese paréntesis se listan los parámetros que requiere el procedimiento para hacer lo que debe hacer.
En este caso el parámetro es uno, y se llama Fila.
¿Que es un parámetro? una variable que puede ser usada dentro del código de GuardarCambios para hacer las operaciones necesarias.

Si tienes la oportunidad de acceder al libro de Turbo Pascal de Luis Goyanes Aguilar (No estoy seguro de si el primer apellido está bien escrito) allí está bien explicado el uso de funciones y parámetros.

¿Porqué los procedimientos y funciones? Porque eso permite que esas porciones de código se ejecuten más de una vez cuando se desee. Y me evito poner el mismo código una y otra vez.

De ese modo, cuando tu haces;

procedure TForm1.Button1Click(Sender: TObject);
begin
HazAlgo(Edit1.Text);
end;

Estás diciendo que ante la pulsación de Button1 se ejecute el código del procedimiento HazAlgo, con el valor del texto del Edit1 como parámetro.

Y si justo el procedimiento HazAlgo me sirve en otro lado ¿como hago?

Pues fácil. Lo volvemos a "llamar":

procedure TForm1.Label1Click(Sender: TObject);
begin
HazAlgo(Label1.Caption);
end;

¿Que diferencia hay? Pues que en vez de usar el texto del Edit, ahora usamos el de un Label.

Espero que esta mini ayuda te sirva para comprender porqué Delphi entiende el Español.

Me parece, según mi opinión, que el uso de procedimientos y funciones es de cátedra básica en programación. El no enseñar eso... pues... me parece una total falta.
No se como te estarán dando clases de programación, pero el no haberte enseñado esos conceptos atenta contra la enseñanza. No se puede avanzar conceptualmente sin abordar el estudio de procedimientos y funciones.

Saludos,

kbaby
09-06-2008, 20:59:10
Bueno recien me hago un hueco de estudiar integrales y estadistica para poder ver un poco el ejemplo y tu post. Pues como te dije, yo no aprendí nada de eso. A mi me enseñan las cosas pero de modo lento... porque no todos los de mi aula tenemos la experiencia de tener un ordenador en casa para poder ensayar y a otros se le da mal el aprnedizaje del codigo. Entonces tenemos un nivel muy bajo, pero estas "llamadas" yo las hago de otra manera o lo que me enseñaron a mi por llamadas es cuando estas en un código y necesitas que actue otro button, entonces pones ButtonX.Click;

De todas formas me voy a poner ahora un ratito con el delphi a ver si saco algo. Muchas gracias, a ver si acabo examenes y me pongo a "delphilar".

kbaby
09-06-2008, 21:29:49
Y bien aquí estoy. Estuve dándole vueltas a tu código hasta me dieron ganar de copiarlo :D pero nada que no encuentro que "cosa" haces para que se modifique. Así que me creé este:

procedure TForm1.Button10Click(Sender: TObject);
var y: integer;
begin
l.Items.clear; // limpio el listbox
for y:= 1 to t.rowcount-1 do begin //antes de iniciar esto, mi rejilla
// ya le volqué todas las personas
edit1.text:=t.cells[1,y];
edit2.text:=t.cells[2,y];
edit4.text:=t.cells[3,y];
edit5.text:=t.cells[4,y];
button1.click; // ejecuta el boton de añadir

end;
end;

Cosas buenas:
- Hace lo que quiero que haga (cuando una persona esta en la rejilla y le modifico o sin modificar) guarda todos los datos de la rejilla en el listbox (limpiándolo previamente).

Cosas malas:
- Las personas no estan ordenadas por ningún criterio, así que cágate (perdon xD) cuando mi "hospital" tenga 1239123947823984905 usuarios y la muchacha de recepción le de por buscar al paciente Pepito Gomez (se muere :p).

Jajaja que te parece tio :rolleyes: voy a seguir echándole un ojo a eso de hacer llamadas a tu forma que me gusto!

Delphius
10-06-2008, 04:01:45
Bueno recien me hago un hueco de estudiar integrales y estadistica para poder ver un poco el ejemplo y tu post. Pues como te dije, yo no aprendí nada de eso. A mi me enseñan las cosas pero de modo lento... porque no todos los de mi aula tenemos la experiencia de tener un ordenador en casa para poder ensayar y a otros se le da mal el aprnedizaje del codigo. Entonces tenemos un nivel muy bajo, pero estas "llamadas" yo las hago de otra manera o lo que me enseñaron a mi por llamadas es cuando estas en un código y necesitas que actue otro button, entonces pones ButtonX.Click;

De todas formas me voy a poner ahora un ratito con el delphi a ver si saco algo. Muchas gracias, a ver si acabo examenes y me pongo a "delphilar".
Me estaba temiendo de que tu no tienes equipo en casa, por como muchas veces me decías que anotabas cosas en tu libreta y te llevas los apuntes a casa.

Bueno no importa, lo importante es que continues y no te dejes vencer.
Lamento si te ha resultado duro que yo haya elejido ese modo de mostarte las cosas, pero me parece de que ese modo se consiguen mejores cosas.

Lo del "llamar" al bottonClick es una opción. Y es algo parecido a lo que hago yo... la diferencia es que tu pones el código a ejecutar en botones, mientras que yo hago que los botones llamen a ciertos procedimientos y son éstos quienes se encargan de hacer el trabajo.

Básicamente yo hago que el botón de la orden al procedimiento. Mientras que tu haces que todo el trabajo lo hagan botones. Esto no siempre es deseado. A medida que avancen tus conocimientos sobre el tema comprenderás las diferencias.

Um... lo que me dices sobre la enseñanza, pues... yo soy de opinar de que si se van a dar clases que se den bien. En otro caso que se vayan.

La enseñanza sea la que sea, debe darse correctamente y por más lenta que sea, es preferible explicar bien las cosas básicas antes que estar meses a medias.

¡Tu metele ganas!

Y bien aquí estoy. Estuve dándole vueltas a tu código hasta me dieron ganar de copiarlo :D pero nada que no encuentro que "cosa" haces para que se modifique. Así que me creé este:

Código Delphi [-] (http://www.clubdelphi.com/foros/#)procedure TForm1.Button10Click(Sender: TObject);
var y: integer;
begin l.Items.clear; // limpio el listbox
for y:= 1 to t.rowcount-1 do begin //antes de iniciar esto, mi rejilla
// ya le volqué todas las personas
edit1.text:=t.cells[1,y];
edit2.text:=t.cells[2,y];
edit4.text:=t.cells[3,y];
edit5.text:=t.cells[4,y];
button1.click; // ejecuta el boton de añadir
end;
end;


Cosas buenas:
- Hace lo que quiero que haga (cuando una persona esta en la rejilla y le modifico o sin modificar) guarda todos los datos de la rejilla en el listbox (limpiándolo previamente).

Cosas malas:
- Las personas no estan ordenadas por ningún criterio, así que cágate (perdon xD) cuando mi "hospital" tenga 1239123947823984905 usuarios y la muchacha de recepción le de por buscar al paciente Pepito Gomez (se muere :p).

Jajaja que te parece tio :rolleyes: voy a seguir echándole un ojo a eso de hacer llamadas a tu forma que me gusto!


Pue eso... sigue dandole ganas. Un truco más: Copia el código de los procedimientos y funciones que se llaman para un botón dentro del botón y notarás que igualmente funciona. Por ejemplo si yo tengo algo como esto:

procedure TForm1.Button1Click(Sender: TObject);
var Se_puede: boolean;
begin
Llamar_a_A;
Se_puede = Se_puede_hacer_B;
if Se_puede
then Llamar_a_B;
end;

Lo que hace Delphi, como para que entiendas, es hacer eso:

procedure TForm1.Button1Click(Sender: TObject);
var Se_puede: boolean;
begin
// aqui comienza el código de Llamar_a_A;
// ....
// aqui termina el código de llamar_a_A;
Se_puede = // aquí el código de Se_puede_hacer_B
if Se_puede
then begin
// aqui comienza el código de Llamar_a_B
// ...
// aqui termina el código de Llamar_a_B
end;
end;

¿Se entiende? Es como tener un código enorme al cual parto en pedacitos mas chicos. Cada parte hace algo... y lo lindo de esto es que puede que esas partes sean más o menos independientes una de otra lo cual favorece a que se evita tener que estar repitiendo código. Si justo una de esas partes me sirve aqui y hallá... en ves de copiar su código la "llamo" y solita hara su trabajo (Si recibe parámetros, quien la llama le pasa los parámetros).

Más o menos lo podemos ver como un "díalogo". Formalmente se los puede llamar como el cliente y el subordinado. O en ocasiones el maestro y el subordinado.
A ver... te voy a dar un ejemplo con algo cotidiano. Supongamos que quiero comprar dólares. ¿Quien es el cliente? Nosotros. Puesto que somos los interesados en hacer algo. ¿Quién es nuetro subordinado? El cajero puesto que cedemos algo de nuestra actividad en alguien más. Podríamos decir "Para que hacerlo yo... si hay alguien que lo sabe hacer y lo hace bien?"

Entonces quedamos en que necesitamos comprar dolares (lo que deseamos hacer). Cuando llega nuestro turno de ser atendidos soltamos una frase como la siguiente "Buenos días, quiero comprar dólares" El subordinado nos dice: "Buenos dias. Muy bien, ¿Cuanto desea?". Le informamos el monto, y el nos responde con un "Son xxx pesos. ¿Le parece bien?" Si respondemos afirmativamente, nos solicita nuestro DNI. Se lo decimos, el confirma la transacción y al minuto nos entrega los dolares correspondientes y el vuelto en caso de ser necesario.

Si te fijas, alguien para hacer si trabajo ha necesitado saber algo por parte del cliente. En este caso, el cajero necesitaba conocer de nosotros la cantidad a comprar y nuestro DNI. En programación esto se suele hacer con el paso de parámetros.

¿Te parece raro lo que te he dicho?
Pues veamoslo como podríamos resolverlo esto en forma de código:


procedure TForm1.ComprarDolaresClick(Sender: TObejct);
var pesos, dolares, vuelto: real;
DNI: integer;
confirmar: boolean;
begin
dolares := 0.0;
pesos := StrToFloat(CantidadAComprar.Text); // es un TEdit
DNI := StrToInt(DNI.Text);
confirmar := Confirmar.Checked; // es un TCheckBox
if Confirmar
then begin
dolares := pesos div 3.15 // 3.15 es la tasa de cambio
vuelto := pesos - (dolares x 3.15);
ButtonGuardarTransaccion.Click // asi lo harías tu...
end;


Se que es un ejemplo... no pretende ser totalmente gráfico y real. ¿Como se puede resolver esto?

Una alternativa que yo utilizaría es esta:


procedure TForm1.ComprarDolares(AComprar: real; var TasaCambio: real);
var Confirmar: boolean;
begin
PedirTasaCambio(TasaCambio);
Confirmar = AnalizarCompra(TasaCambio);
if Confirmar
then Comprar(AComprar);
end;


De ese modo yo hago algo como esto para llamar a ese procedimiento:


procedure TForm1.ButtonComprarDolaresClick(Sender: TObject);
begin
ComprarDolares(StrToFloat(Cantidad.Text), tasa);
//Nota como primero paso convertiendo el texto de un TEdit en float,
// tasa posiblemente sea una variable global
end;


¿Eso es todo? ¿Y aquel emborroso código inicial? ¿Donde ha quedado aquello del DNI, devolver el vuelto, darle el dinero... y demás...? Pues de eso se encarga el procedimiento Comprar.

Analicemos...
ComprarDolares es un procedimiento, no es un Button... es algo que se va a ejecutar cuando se presione el botón. Para que ComprarDolares funcione, necesita saber dos cosas:
1. La cantidad a comprar (parámetro AComprar)
2. Una tasa de cambio (parámetro por valor, TasaCambio).

¿De donde sale esa tasa de cambio? Para que la necesitamos? En realidad, cuando uno compra dolares uno va y se informa de la tasa de cambio y en base a ello decide... quien en realidad sabe de la tasa es el cajero...
Si te fijas, antes de TasaCambio: real, hay una palabra var. Esto hace que el parámetro sea por valor. Viene a ser como un parámetro de salida (que puede ser de utilidad para después).

Entonces, estamos frente a un díalogo entre los procesos y funciones y la forma de hacerlos hablar es a través de parámetros. Hay ocasiones en que no son necesarios los parámetros, otras en que si.

Nuestro botón se comunica con ComprarDolares, y éste a su vez con PedirTasaCambio, AnalizarCompra, y Comprar.

¿Quien es cliente y subordinado? Pues se trata de una cadena...
1. Primero: el procedimiento ComprarDolares es subordinado del Botón ComprarDolares. Por tanto el cliente (interesado) es el Botón.
2. Segundo: a su vez, el procedimiento ComprarDolares es cliente puesto que subordina parte del trabajo a Comprar, PedirTasaCambio, etc...
3. Posiblemente, y es de esperar que PedirTasaCambio, Comprar hagan otras cosas.... cosas que ha nosotros no nos interese saber, pero que le son necesarias para hacer su trabajo.

Por ejemplo: PedirTasaCambio, por dentro haga cosas como "VerificarConBancoCentral", "VerificarSiHayDolares", o cosas por el estilo...

El asunto es que a un problema grande, lo partimos en pedacitos chicos, que juntos hacen las cosas más grandes. Esto se conoce como el principio divide y vencerás (http://es.wikipedia.org/wiki/Algoritmo_divide_y_vencer%C3%A1s). Esto lo verás más adelante en tu cursado.

Se que posiblemente te sientas mareado por todo lo que te he dicho... es normal, al comienzo cuesta entender las cosas.

Lo más sorprendente es que tu lo aplicas, y ni siquieras te haz dado cuenta... ¿O acaso el haber hecho un Button2.Click no es parte de esa filosofía?

Saludos, kbaby... Piensa en frio.;)

kbaby
16-06-2008, 11:29:32
Hola.

Siento responder tan tarde pues estuve (estuve!!) liado con los examenes que al final he acabado y creo que muy bien. Al final ya he acabado con finales y subidas de notas así que ahora a descansar este veranito.

Tengo una buena noticia!! Le presenté mi proyecto a mi profesor de informática. Lo analizó y tal... bueno me dio la nota y me puso un 10. ¡¡Un 10!!. Sí como puedes oir, la mejor nota. Que feliz!! Bueno, es que no sabes como me ha quedado finalmente despues de todos los retoques que le hice. De todos modo ahora a las 13:30 p.m voy a la subida de nota porque la media de las 3 evaluaciones es un 9,3 ((eval1+eval2+eval3)/3). Ya que voy, le dije a mi profesor, que me llevare el pendrive para guardarme todos los trabajos que tengo en el ordenador del aula para que no se me olviden como se hacen cosas simples y así traerme el programa (ya lo verás ajaja).

Bueno estuve viendo y leyendo tu mensaje anterior jaja. Pues si que es un lio, pero un lio gordo pero creo que conforme avance se podrá ir resolviendo. Es como cuando estás por primera vez enfrete a un polinomio muy grande. En realidad son sencillas sumas, restas, multiplicaciones y divisiones que se te presentan acumuladas en una misma estructura. En ese momento te bloqueas. Conocía el principio DYV y es verdad todo lo que dice.

Intentaré aprender muchas cosas de delphi durante este verano.

Me voy a proponer un proyecto... un juego :p Bueno lo que voy a intentar hacer estos dos meses de verano será un pequeño juego que se base en un buscaminas (algo facil supongo, pero bueno..). Espero que me sea leve... (bueno leve para ti, pQ estaré aqui dando por culillo.

Y bien, voy a ir a eso y luego te comento. Muchos saludos.

PD: Antes de irme, lo que si me gustaría aprender es como usar los TCheckBox.

He buscado por google, pero las explicaciones que vienen no las entiendo porque las explican a un nivel mas avanzado y esto es lo que me pasa con todo. Jajaja

kbaby
16-06-2008, 13:51:58
Aquí vuelvo... con la mejor noticia....

En mi boletín de calificaciones tengo un 10 en informatica !!!! Siiii!!! Gracias ;)

Como dije, aquí os dejo el enlace de mi super proyecto ^^ Mola Ehh ^^

Alomejor lo veis muy grande, es que nuestros monitores son super grandes y cuando sigo super grandes, es SUPER grandes jajaja. Tambien la fonts con la que lo hice está solo en el pc de mi colegio.

Bueno.

Delphius, me traje todos los proyectos que fui haciendo (muchos) desde que aprendi a sumar 2 edits hasta hacer lo que hago.
¿Qué tal si los voy subiendo poco a poco para la gente que se inicia? Los subo e indico lo que hace cada programa. Hay mucho código que puede ser util a otros (como a mi).

Mi proyecto final 2008 -> http://rapidshare.com/files/122835209/Final.rar.html

* Comprimido con Winrar
* Dentro viene los requisitos que tenía que tener mi programa
* El nombre de mi hospital es en honor a Paula (si lo lees... que te lo pases bien este verano).

enecumene
16-06-2008, 14:27:28
Hola, muy bueno para ser el primero jeje, revisando me encontré con un problema, y es en la parte de la facturación, al darle click al botón IVA y Descuento sale el error:

---------------------------
proyectofinal1
---------------------------
'' is not a valid floating point value.
---------------------------
OK
---------------------------


Revísalo, pero todo lo demás está bien ;)

Saludos.

kbaby
16-06-2008, 14:30:37
A ver, alomejor te pasa esto. El iva y/o descuento se aplica una vez que tenemos un total "X". Así que primero elejimos los días que pasó en el hospital, el tipo de operación y luego ponemos por ejemplo:

16 -> IVA
5 -> DESCUENTO

Y verás como automaticamente el total cambia a "X+IVA-DESCUENTO".

^^

enecumene
16-06-2008, 14:45:07
Hola, yo quise decir esteticamente hablando, el mensaje no es nada agradable y poco informativo, podrías usar el Try...Except para capturar ese error y personalizar el mensaje que diga algo como:

ShowMessage('El valor que has ingresado no es válido, por favor digite el valor de la siguiente forma: bla, bla...');

Así quedaría mejor ¿no crees?, otra cosa, deberías centralizar el form principal o que cuando incies se maximize automaticamente.

Saludos.

kbaby
16-06-2008, 14:54:37
¿Me podrías explicar como usar el Try...Except?

La verdad es que no tengo ni idea y me gustaría hacer eso que me dices. Yo se usar el comando showmessage('blabla'); pero no sé hacer que cuando ponga por ejemplo en descuento "quince" salga un mensaje diciendo que sólo ponga números del 0-9.

Así quedaría mejor ¿no crees?, otra cosa, deberías centralizar el form principal o que cuando incies se maximize automaticamente.

Explica que eso me interesa :P Ya que yo lo ajusté al tamaño de la pantalla del ordenador que tengo en mi colegio, y ahora, al abrirlo en mi ordenador. paf! Se ve muy chico jajaja.

enecumene
16-06-2008, 14:59:24
procedure TForm.Button1click(sender: TObject);
begin
try
//las sentencias normales que tienes
Except
Showmessage('mensaje');
Exit; //para detener el proceso
end;
end;

Saludos ;)

kbaby
16-06-2008, 15:04:41
Mi código a quedado así:
procedure TForm1.Button16Click(Sender: TObject);
var iva,total,a:real;
begin
try
iva:=strtofloat(edit21.text);
total:=strtofloat(edit23.text);
iva:= (iva / 100)*total;
a:= total + iva;
edit23.text:=floattostr(a);
button16.enabled:=false;
except
showmessage('Introduzca un valor válido. Carácteres permitidos 0-9.');
Exit;
end;
end;

Pero ahora cuando en IVA pongo quince (en vez de 15) no me sale ese mensaje, sino el error que a ti te daba. Algo hago mal...

enecumene
16-06-2008, 15:10:05
Hola, lo que tienes que hacer es esto:

procedure TForm1.Button16Click(Sender: TObject);
var iva,total,a:real;
begin
if Edit21.Text > '9' then
Begin
ShowMessage('El Mensaje');
Exit;
end;
try
iva:=strtofloat(edit21.text);
total:=strtofloat(edit23.text);
iva:= (iva / 100)*total;
a:= total + iva;
edit23.text:=floattostr(a);
button16.enabled:=false;
except
showmessage('Introduzca un valor válido. Carácteres permitidos 0-9.');
Exit;
end;
end;

Saludos.

kbaby
16-06-2008, 15:16:17
Hola! Jajaja perdona la molestia. Puse ese código y resulta que si en edit21.text pongo (por ejemplo: pepe) me sale:
1º->
'El Mensaje'

2º->

El error de antes.

Queda feo el error que tira... ¿no se podría sustituir ese error por un mensaje que el usuario lo entienda?.

enecumene
16-06-2008, 15:25:51
Hola! Jajaja perdona la molestia. Puse ese código y resulta que si en edit21.text pongo (por ejemplo: pepe) me sale:
1º->
'El Mensaje'

2º->

El error de antes.

Queda feo el error que tira... ¿no se podría sustituir ese error por un mensaje que el usuario lo entienda?.

A ver, ¿cual fue el error feo que te tira?, y por casualidad el Edit21 no debe ser numérico? :rolleyes:

Saludos.

kbaby
16-06-2008, 15:33:49
El error que da es: '' is not a valid floating point value.

Y claro que debe ser numerico. La cadena pepe la puse como si pusieramos dieciseis u ocho en el edit. Lo que quiero que haga es que si los introducido no es un numero del 0-9 (no hay mas numero que paranoya xD) pues salga un mensaje que diga que introduzca un valor del 0-9.

enecumene
16-06-2008, 15:43:53
Vamos a ver, prueba este, no te aseguro que funcione porque lo hice al vuelo:

procedure TForm1.Button16Click(Sender: TObject);
var iva,total,a:real;
Numeros: Packed array[0..9] of integer;
Valor: Integer;
begin
Valor := SrtToInt(Edit21.text);
if Valor <> Numeros then
Begin
ShowMessagge('El Mensaje');
Exit;
end;
if Edit21.Text > '9' then
Begin
ShowMessage('El Mensaje');
Exit;
end;
try
iva:=strtofloat(edit21.text);
total:=strtofloat(edit23.text);
iva:= (iva / 100)*total;
a:= total + iva;
edit23.text:=floattostr(a);
button16.enabled:=false;
except
showmessage('Introduzca un valor válido. Carácteres permitidos 0-9.');
Exit;
end;
end;

Intenta ahora.

Saludos.

kbaby
16-06-2008, 19:43:08
Gracias, el retoque un nada y ya funciona. Pues venga muchas gracias a ver que opina mi maestro Delphius xD

enecumene
16-06-2008, 19:52:55
Gracias, el retoque un nada y ya funciona. Pues venga muchas gracias a ver que opina mi maestro Delphius xD

A ver, al estar tu de comelón te comiste algunas palabras y no entiendo :D:D, ¿cual fue el retoque? ¿lo último que te propuse funcionó? :confused::confused:

Saludos. ;)

kbaby
16-06-2008, 20:05:57
A mi me funcionó, lo que retoqué fue mi codigo, el que ya tenía :p

Delphius
18-06-2008, 01:03:31
Hola kbaby,
Estuve fuera estos últimos días. Recien vuelvo.
Me alegro de que hayas aprobado el proyecto. Se ve que tienes muchas ganas y energías. No pierdas ese entusiasmo... no es por ser malito pero puede que más adelante te haga falta.

Disculpa que no haya visto tus proyectos. Es que estas semanas ando corto de tiempo y tengo obligaciones que me van a obligar ausentarme mucho.

Veo que enecumene tomó mi lugar en la cátedra. No temas pedir ayuda a alguien más. Somos muchos los profes aqui. Y si te le animas... puedes sumartenos, aportando lo que vayas aprendiendo.

Saludos,

kbaby
18-06-2008, 14:08:17
Las obligaciones primero, yo ahora estoy liado porque estoy quedando para salir todo el rato con los amigos porque algunos se van ya del instituto y claro es una pena. Bueno ya me avisarás cuando estes menos ocupado o bueno, ya notarás mi presencia por aqui jajaja.

Que te sea todo leve... un besazo*


diego


*no pienses mal eh xD :D