
aplicacion en delphi
Comenzado por
cflowers
, ago 02 2010 04:42
28 respuestas en este tema
#21
Escrito 03 agosto 2010 - 07:09
gracias! ahora tengo otra duda. si tengo que crear un archivo aparte .txt. todavia no me quedo claro eso
#22
Escrito 03 agosto 2010 - 08:21
delphi
Unit CPromedios; interface uses StdCtrls,SysUtils; type TPromedios=class private miArchivo: TextFile; public procedure Calcular(miArchivoF:string;var memo1:TMemo); end; implementation procedure TPromedios.Calcular(miArchivoF:string; var memo1:TMemo); var i,n1,n2,n3:byte; nombre: string[30]; prom: single; begin AssignFile(miArchivo,miArchivoF); Reset(miArchivo); while not eof(miArchivo) do begin readln(miArchivo,nombre); readln(miArchivo,n1,n2,n3); prom:=(n1+n2+n3)/3; end; end;// fin del while CloseFile(miArchivo); end; // fin del método end. // fin de la unit de diseño procedure TForm1.Button1Click(Sender: TObject); var x: TPromedios; begin if opendialog1.execute then begin x:=TPromedios.Create; x.Calcular(Opendialog1.Filename, memo1); x.Free; end; end;
TENGO LOS ALUMNOS EN UN LISTADO .TXT CON LAS TRES NOTAS DE VARIOS ALUMNOS
NO SE COMO AGREGAR LOS PROMEDIOS A LA UNIT 2 SIN LA CLASE TPROMEDIO.
#23
Escrito 03 agosto 2010 - 08:28
Bueno, lo que pasa es que en tu clase TAlumno no tienes los campos de nota 1 a 3 por lo que así no vas a poder agregarlas al archivo.
Tengo dos dudas,
1. El DNI es numérico ?, yo lo pondría como Entero o String en lugar de Double.
2. Saldo es el promedio de las notas ??
La clase yo la declararía así.
Salud OS
Tengo dos dudas,
1. El DNI es numérico ?, yo lo pondría como Entero o String en lugar de Double.
2. Saldo es el promedio de las notas ??
La clase yo la declararía así.
delphi
TAlumno = Record Apellido: string[20]; nombres: string[20]; DNI: Integer; Nota1: double; Nota2: double; Nota3: double; Saldo: double; end;
Salud OS
#24
Escrito 03 agosto 2010 - 08:39
claro, pero esta clase puede ir en la unit 2?? perdon por tantas preguntas pero soy principiante!
#25
Escrito 03 agosto 2010 - 08:49
claro, pero esta clase puede ir en la unit 2?? perdon por tantas preguntas pero soy principiante!
Todo puede estar en la misma unidad, el asunto es saber a que quieres llegar, un sistema comienza desde la elaboración de los requerimientos, de esa forma sabes que es lo que necesitas y como lo vas a estructurar, si ese análisis es incorrecto, comenzaremos con problemas, que se pueden solventar, pero es mejor hacerlo bien desde el principio.
Salud OS
#26
Escrito 03 agosto 2010 - 09:03
MI PROBLEMA ES QUE ESTOY PROGRAMANDO EN BASE A COMPONENTES VISUALES PORQUE ME PIERDO Y NO SE DONDE PONER LAS COSAS
#27
Escrito 03 agosto 2010 - 09:16
MI PROBLEMA ES QUE ESTOY PROGRAMANDO EN BASE A COMPONENTES VISUALES PORQUE ME PIERDO Y NO SE DONDE PONER LAS COSAS
Bueno, como te digo, lo primero es analizar y crear las clases que vas a utilizar para almacenar los registros, los componentes visuales es el menor de los problemas porque estos cuentan con eventos definidos de lo que quieres que hagan.
Salud OS
#28
Escrito 03 agosto 2010 - 09:25
ESTO ES LO QUE HICE EN LA UNIT 1 CON LAS CORRECIONES Y APORTES
Editado: Hola cflowers como notarás, el código se ve mejor como lo acabo de modificar, esto lo puedes hacer desde el panel del mensaje, seleccionando el código y presionando el boton de delphi
ó colocando la etiqueta de esta forma:
[NOBBC]
[/NOBBC]
delphi
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, Unit2, StdCtrls, Grids, Menus; type TForm1 = class(TForm) Button1: TButton; Button2: TButton; StringGrid1: TStringGrid; procedure FormCreate(Sender: TObject); procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); procedure ListacPromedios1Click(Sender: TObject); procedure Guardar1Click(Sender: TObject); private { Private declarations } Archivo: TArchivo; public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.FormCreate(Sender: TObject); var c:alumno; begin Archivo:=TArchivo.Create; //Se crea un archivo de ejemplo Archivo.CrearArchivo('nombres.dat'); //Se añaden alumnos a la lista c.Apellido:='Calleja'; c.nombres:='Miguel'; c.DNI:=111; c.saldo:=100; Archivo.Agregaralumno(c); c.Apellido:='Santana'; c.nombres:='Lorenzo'; c.DNI:=112; c.saldo:=200; Archivo.Agregaralumno(c); end; procedure TForm1.Button1Click(Sender: TObject); begin //El botón 1 elimina un alumno Archivo.Eliminaralumno(111); end; procedure TForm1.Button2Click(Sender: TObject); var datos: Alumno; fila, columna, i: Integer; begin //El botón 2 llena el StringGrid con los alumnos del archivo StringGrid1.FixedRows:=0; StringGrid1.FixedCols:=0; // Limpia el stringgrid for i := 0 to StringGrid1.ColCount - 1 do StringGrid1.Cols[i].Clear; Archivo.MoverAInicio; fila:=0; while Archivo.Siguiente(datos) do begin StringGrid1.Cells[0,fila] := datos.Apellido; StringGrid1.Cells[1,fila] := datos.nombres; StringGrid1.Cells[2,fila] := Format('%f',[datos.DNI]); Inc(fila); end; TAlumno = Record Apellido: string[20]; nombres: string[20]; DNI: Integer; Nota1: double; Nota2: double; Nota3: double; Saldo: double; end; var i,n1,n2,n3:byte; nombre: string[30]; prom: single; begin AssignFile(miArchivo,miArchivoF); Reset(miArchivo); while not eof(miArchivo) do begin readln(miArchivo,nombre); readln(miArchivo,n1,n2,n3); prom:=(n1+n2+n3)/3; end; end;// fin del while CloseFile(miArchivo); end; // fin del método procedure TForm1.ListacPromedios1Click(Sender: TObject); var x: TPromedios; begin if opendialog1.execute then begin x:=TPromedios.Create; x.Calcular(Opendialog1.Filename, memo1); x.Free; end; end; procedure TForm1.Guardar1Click(Sender: TObject); TALUMNO.GrabarALUMNO(c:ALUMNO; var cod:byte); begin {$I-} Seek(Archi, FileSize(archi)); {$I+}; cod:=IOResult; If cod=0 then Write(Archi,c); end; procedure TMane end; end. // fin de la unit de diseño end. procedure TForm1.Button1Click(Sender: TObject); end; end; end.
Editado: Hola cflowers como notarás, el código se ve mejor como lo acabo de modificar, esto lo puedes hacer desde el panel del mensaje, seleccionando el código y presionando el boton de delphi

[NOBBC]
delphi
//Todo el código dentro de estas etiquetas
[/NOBBC]
#29
Escrito 04 agosto 2010 - 06:56
Hola cflowers, me gustaría comentarte algunos detalles:
- Las estructuras, en Object Pascal cuando las vas a utilizar con ficheros, la guía de Programación Delphi 5 recomienda declararlas como packed record, para optimizar el manejo de memoria.
-
Aquí tienes un BufferOverflow si introduces más de 21 caracteres en "Nombres" o "Apellido". Una manera de evitarlo es utilizando la propiedad MaxLength:= 21 de los controles TEdit, o bien comprobando los caracteres con la función Length antes de meterlos en la estructura.
- DNI la estás declarando como Integer, el tipo de datos Integer toma valores positivos y negativos; como los digitos del DNI son siempre positivos yo declararía DNI como Cardinal.
- Cuando hago pequeñas chapuzas con ficheros sin tipo, empleo la clase TFileStream o TMemoryStream, las funciones de Pascal son útiles, pero te recomiendo mucho aprender a usar estas 2 clases.
Tenía un poco de tiempo libre así que modifiqué un poco tu unidad:
Para trabajar con ella...
Saludos, espero que te sirva.
- Las estructuras, en Object Pascal cuando las vas a utilizar con ficheros, la guía de Programación Delphi 5 recomienda declararlas como packed record, para optimizar el manejo de memoria.
-
delphi
Apellido, nombres: string[20];
Aquí tienes un BufferOverflow si introduces más de 21 caracteres en "Nombres" o "Apellido". Una manera de evitarlo es utilizando la propiedad MaxLength:= 21 de los controles TEdit, o bien comprobando los caracteres con la función Length antes de meterlos en la estructura.
- DNI la estás declarando como Integer, el tipo de datos Integer toma valores positivos y negativos; como los digitos del DNI son siempre positivos yo declararía DNI como Cardinal.
- Cuando hago pequeñas chapuzas con ficheros sin tipo, empleo la clase TFileStream o TMemoryStream, las funciones de Pascal son útiles, pero te recomiendo mucho aprender a usar estas 2 clases.
Tenía un poco de tiempo libre así que modifiqué un poco tu unidad:
delphi
unit BaseDatos; interface uses SysUtils, Classes; type TAlumno = packed record Nombre: String[20]; Apellido: String[20]; DNI: Cardinal; Saldo: Double; end; TAlumnosArray = array of TAlumno; TBaseDatos = class(TObject) private FFileName: String; public constructor Create(const FileName: String); reintroduce; destructor Destroy; override; function AgregarAlumno(Alumno: TAlumno): boolean; function ObtenerNumeroAlumnos: Cardinal; function ObtenerAlumnoPorIndex(const Index: Cardinal; var Alumno: TAlumno): boolean; function ObtenerAlumnoPorDNI(const DNI: Cardinal; var Alumno: TAlumno): boolean; function ObtenerAlumnos(var ListaAlumnos: TAlumnosArray): boolean; end; implementation {TBaseDatos} constructor TBaseDatos.Create(const FileName: string); begin FFileName:= FileName; inherited Create; end; destructor TBaseDatos.Destroy; begin inherited Destroy; end; function TBaseDatos.ObtenerNumeroAlumnos: Cardinal; var fsDB: TFileStream; begin if FileExists(FFileName) then begin try fsDB:= TFileStream.Create(FFileName, fmOpenRead or fmShareDenyWrite); //Abrimos el archivo en Modo Lectura o denegar la escritura if fsDB.Size > 0 then result:= fsDB.Size div SizeOf(TAlumno) else result:= 0; finally fsDB.Free; end; end else result:= 0; end; function TBaseDatos.AgregarAlumno(Alumno: TAlumno): boolean; var fsDB: TFileStream; BytesWritten: Integer; begin result:= false; try if FileExists(FFileName) then fsDB:= TFileStream.Create(FFileName, fmOpenReadWrite) else fsDB:= TFileStream.Create(FFileName, fmCreate); //Abrimos el archivo en Modo Escritura-Lectura fsDB.Seek(fsDB.Size, 0); //Nos situamos al final del archivo BytesWritten:= fsDB.Write(Alumno, SizeOf(TAlumno)); //Escribimos los datos if BytesWritten = SizeOf(TAlumno) then result:= true else result:= false; finally fsDB.Free; end; end; function TBaseDatos.ObtenerAlumnoPorIndex(const Index: Cardinal; var Alumno: TAlumno): boolean; var fsDB: TFileStream; BytesRead: Integer; begin //El Index tiene que ser menor que el número de alumnos y mayor o igual que 0 //Si tenemos 2 alumnos, podriamos establecer un Index con valor 0 o 1 if (Index < ObtenerNumeroAlumnos) and (Index >= 0) then begin try fsDB:= TFileStream.Create(FFileName, fmOpenRead or fmShareDenyWrite); fsDB.Seek(Index * SizeOf(TAlumno), 0); //Nos situamos antes del registro que queremos leer BytesRead:= fsDB.Read(Alumno, SizeOf(TAlumno)); if BytesRead = SizeOf(TAlumno) then result:= true else result:= false; finally fsDB.Free; end; end else result:= false; end; function TBaseDatos.ObtenerAlumnoPorDNI(const DNI: Cardinal; var Alumno: TAlumno): boolean; var fsDB: TFileStream; AlumnoTemp: TAlumno; BytesRead, i: integer; NumeroAlumnos: Cardinal; begin NumeroAlumnos:= ObtenerNumeroAlumnos; if (NumeroAlumnos > 0) and (DNI > 0) then begin try fsDB:= TFileStream.Create(FFileName, fmOpenRead or fmShareDenyWrite); for i := 0 to NumeroAlumnos - 1 do begin fsDB.Seek(I * SizeOf(TAlumno), 0); BytesRead:= fsDB.Read(AlumnoTemp, SizeOf(TAlumno)); if BytesRead = SizeOf(TAlumno) then if AlumnoTemp.DNI = DNI then begin result:= True; Alumno:= AlumnoTemp; break; end; end; finally fsDB.Free; end; end else result:= false; end; function TBaseDatos.ObtenerAlumnos(var ListaAlumnos: TAlumnosArray): boolean; var i, BytesRead: integer; fsDB: TFileStream; NumeroAlumnos: Cardinal; begin NumeroAlumnos:= ObtenerNumeroAlumnos; if NumeroAlumnos > 0 then begin try SetLength(ListaAlumnos, NumeroAlumnos); fsDB:= TFileStream.Create(FFileName, fmOpenRead or fmShareDenyWrite); for i := 0 to NumeroAlumnos - 1 do begin fsDB.Seek(I * SizeOf(TAlumno), 0); BytesRead:= fsDB.Read(ListaAlumnos[i], SizeOf(TAlumno)); if BytesRead <> SizeOf(TAlumno) then begin ListaAlumnos:= nil; result:= false; break; end; end; if ListaAlumnos <> nil then result:= True; finally fsDB.Free; end; end else result:= false; end; end.
Para trabajar con ella...
delphi
var Form1: TForm1; DB: TBaseDatos; implementation {$R *.dfm} procedure TForm1.VerAlumnosClick(Sender: TObject); var i: integer; ListItem: TListItem; ListaAlumnos: TAlumnosArray; begin ListView1.Clear; If DB.ObtenerAlumnos(ListaAlumnos) then begin for i := low(ListaAlumnos) to High(ListaAlumnos) do begin ListItem:= ListView1.Items.Add; ListItem.Caption:= ListaAlumnos[i].Nombre; ListItem.SubItems.Add(ListaAlumnos[i].Apellido); ListItem.SubItems.Add(IntToStr(ListaAlumnos[i].DNI)); ListItem.SubItems.Add(FloatToStr(ListaAlumnos[i].Saldo)); end; ListaAlumnos:= nil; end; end; procedure TForm1.AgregarAlumnosClick(Sender: TObject); var Alumno: TAlumno; begin Alumno.Nombre:= Edit1.Text; Alumno.Apellido:= Edit2.Text; Alumno.DNI:= StrToInt(Edit3.Text); Alumno.Saldo:= StrToFloat(Edit4.Text); If DB.AgregarAlumno(Alumno) then showmessage('Alumno agregado con éxito') else showmessage('Fallo!'); end; procedure TForm1.FormCreate(Sender: TObject); begin DB:= TBaseDatos.Create('datos.dat'); end; procedure TForm1.FormDestroy(Sender: TObject); begin DB.Free; end;
Saludos, espero que te sirva.