Ir al contenido


Foto

Ayuda con una pequeña función


  • Por favor identifícate para responder
19 respuestas en este tema

#1 enecumene

enecumene

    Webmaster

  • Administrador
  • 7.409 mensajes
  • LocationRepública Dominicana

Escrito 29 diciembre 2008 - 08:53

Hola amigos pues eso, estoy creando una pequeña función para abrir todos los TTables de un formulario, he estado haciendo lo siguiente:



delphi
  1. {*** FUNCION PARA ABRIR TODAS LAS TABLAS DE UN FORM (ZTABLE) ***}
  2. procedure AbrirTablas(Forma: TForm);
  3. var nIdx: Integer;
  4. begin
  5.   for nIdx := 0 to Forma.ComponentCount - 1 do
  6.   begin
  7.       if Forma.Components[nIdx] is ZTable then
  8.         ZTable(Forma.Components[nIdx]).Open;
  9.   end;
  10. end;



Pues como ya sabrán no me funciona, es por el parámetro Forma, el objetivo es que lo pueda usar de este modo:



delphi
  1. AbrirTablas(Aquí el nombre del formulario);



Sí lo sé es una tontería de código :(

Saludos.
  • 0

#2 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.256 mensajes
  • LocationMéxico

Escrito 29 diciembre 2008 - 08:55

Amigo, y porque no usas frames para este asunto.

Salud OS

  • 0

#3 enecumene

enecumene

    Webmaster

  • Administrador
  • 7.409 mensajes
  • LocationRepública Dominicana

Escrito 29 diciembre 2008 - 08:59

Amigo, y porque no usas frames para este asunto.

Salud OS


Porque así me ahorro un choclo de códigos, ya que cada Formulario tiene x cantidad de Datasets y así creo que me es más practico que llamarlo a cada uno de esta forma:



delphi
  1. Form1.Tabla1.Open;
  2. ...
  3. Form1.Tabla10.open;



Saludos.
  • 0

#4 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.256 mensajes
  • LocationMéxico

Escrito 29 diciembre 2008 - 09:00

Amigo, puedes hacer un frame por cada dataset que quieras crear en tiempo de ejecución :D

Dejame preparar un ejemplo.

Salud OS

  • 0

#5 enecumene

enecumene

    Webmaster

  • Administrador
  • 7.409 mensajes
  • LocationRepública Dominicana

Escrito 29 diciembre 2008 - 09:21

Se me olvidó aclarar que el procedimiento está en una UNIT sin Componentes sólo para ser agregado como uses.

Saludos.
  • 0

#6 seoane

seoane

    Advanced Member

  • Moderador
  • PipPipPip
  • 1.257 mensajes
  • LocationEspaña

Escrito 30 diciembre 2008 - 07:26

Pues como ya sabrán no me funciona, es por el parámetro Forma

¿cual es el error que te da? ¿No te compila? ¿No te abre las tablas?
  • 0

#7 enecumene

enecumene

    Webmaster

  • Administrador
  • 7.409 mensajes
  • LocationRepública Dominicana

Escrito 30 diciembre 2008 - 07:40

¿cual es el error que te da? ¿No te compila? ¿No te abre las tablas?


El procedimiento funciona perfecto si lo coloco en un form (Form1), pero como se trata de una Unidad al colocar el punto luego del Parámetro Forma, me da el siguiente error:

[Pascal Error] Unit1.pas(1): Unable to invoke Code Completion due to errors in source code


Saludos.
  • 0

#8 Rolphy Reyes

Rolphy Reyes

    Advanced Member

  • Moderadores
  • PipPipPip
  • 2.092 mensajes
  • LocationRepública Dominicana

Escrito 30 diciembre 2008 - 08:52

Saludos.

No tengo los Zeos instalados pero debe ser igual, esto lo hice de un pronto y funciono adecuadamente.



delphi
  1. unit Unit2;
  2.  
  3. interface
  4.  
  5. uses Forms, DB, DBTables;
  6.  
  7.   procedure AbrirTablas(Const Frm : TForm);
  8.  
  9. implementation
  10.  
  11. procedure AbrirTablas(Const Frm : TForm);
  12. var
  13.   I : Integer;
  14. begin
  15.   for I := 0 to Frm.ComponentCount -1 do
  16.   begin
  17.     if Frm.Components[I] is TTable then
  18.     begin
  19.       TTable(Frm.Components[I]).Close;
  20.       TTable(Frm.Components[I]).Open;
  21.     end;
  22.   end;
  23. end;
  24.  
  25. end.



Y la unit1 es así:



delphi
  1. unit Unit1;
  2.  
  3. interface
  4.  
  5. uses
  6.   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  7.   Dialogs, Grids, DBGrids, DB, DBTables, StdCtrls;
  8.  
  9. type
  10.   TForm1 = class(TForm)
  11.     Button1: TButton;
  12.     Table1: TTable;
  13.     Table2: TTable;
  14.     Table3: TTable;
  15.     DataSource1: TDataSource;
  16.     DataSource2: TDataSource;
  17.     DataSource3: TDataSource;
  18.     DBGrid1: TDBGrid;
  19.     DBGrid2: TDBGrid;
  20.     DBGrid3: TDBGrid;
  21.     procedure Button1Click(Sender: TObject);
  22.   private
  23.     { Private declarations }
  24.   public
  25.     { Public declarations }
  26.   end;
  27.  
  28. var
  29.   Form1: TForm1;
  30.  
  31. implementation
  32.  
  33. uses Unit2;
  34.  
  35. {$R *.dfm}
  36.  
  37. procedure TForm1.Button1Click(Sender: TObject);
  38. begin
  39.   AbrirTablas(Form1);
  40. end;
  41.  
  42. end.



Espero que te sirva....

  • 0

#9 seoane

seoane

    Advanced Member

  • Moderador
  • PipPipPip
  • 1.257 mensajes
  • LocationEspaña

Escrito 30 diciembre 2008 - 03:41


¿cual es el error que te da? ¿No te compila? ¿No te abre las tablas?


El procedimiento funciona perfecto si lo coloco en un form (Form1), pero como se trata de una Unidad al colocar el punto luego del Parámetro Forma, me da el siguiente error:

[Pascal Error] Unit1.pas(1): Unable to invoke Code Completion due to errors in source code


Saludos.


Añade Forms a las uses
  • 0

#10 enecumene

enecumene

    Webmaster

  • Administrador
  • 7.409 mensajes
  • LocationRepública Dominicana

Escrito 31 diciembre 2008 - 11:04

Gracias Seoane, efectivamente eso era lo que me faltaba, ya me funciona, Rolphy, muchas gracias, también probé el tuyo y funciona perfecto, mejoré el código para que también se pudiera cerrar las tablas al salir de una Forma Cerrada (por si las moscas):



delphi
  1. procedure AbrirTablas(Forma: TForm; Estado: Bool);
  2. var nIdx: Integer;
  3. begin
  4.   for nIdx := 0 to Forma.ComponentCount - 1 do
  5.   begin
  6.       if Forma.Components[nIdx] is TZTable then
  7.         TZTable(Forma.Components[nIdx]).Active := Estado;
  8.   end;
  9. end;



Para abrir las tablas:



delphi
  1. AbrirTablas(Form1,True);



Y para cerrar:



delphi
  1. AbrirTablas(Form1,False);



Hasta ahora me ha funcionado perfecto, muchas gracias a todos.

Saludos.
  • 0

#11 Delphius

Delphius

    Advanced Member

  • Moderador
  • PipPipPip
  • 6.295 mensajes
  • LocationArgentina

Escrito 31 diciembre 2008 - 11:29

Me alegro de que lo hayas solucionado. Yo veía el código y me decía ¡Eso debería funcionar!
Cuando vi que posteaste el error me quedé mudo... no supe a que se podría deber...

Nomás pasaba por aquí, porque me llama un poquito la atención el nombre del procedimiento. Siento que te "desentona" un poquito. El leer AbrirTablas() me da la idea de que las abre... ahora con ese parámetro boolean, como que el nombre no representa del mejor modo el propósito.

Nomás digo... es que ando un tanto curioso. No se... tal vez...



delphi
  1. ActivarTablas(Form: TForm; Habilitar: boolean)



Es que Abrir y Cerrar dan la idea de que las abre y cierra, pero el tener un AbrirTablas y leer ese parámetro como que es contrario a la idea. Es decir: Abrir y Estado = False... es como decir "Cerrar". Suena más "neutro" Activar.
O tal vez...



delphi
  1. PuedeAbrirTablas(Form: TForm; Abrir: boolean)



Pero ese nombre me suena a que es una función y no un procedimiento. Y si es una función ¿que regresa? Parecería que true o false... pero entonces... si decimos "Puede" da la idea de que intenta... y por tanto True en caso de que las abre a todas, False en otro caso...

No se, se que hice un lío y no aporto mucho... me quedé pensando... ¿cual puede ser el nombre adecuado al procedimiento? :s

Saludos,
  • 0

#12 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.256 mensajes
  • LocationMéxico

Escrito 31 diciembre 2008 - 11:32

Yo voto por......



delphi
  1. procedure QueHagoConLaTabla(Forma: TForm; Estado: Bool);
  2. begin
  3. end;



:D :D :D

Salud OS
  • 0

#13 enecumene

enecumene

    Webmaster

  • Administrador
  • 7.409 mensajes
  • LocationRepública Dominicana

Escrito 31 diciembre 2008 - 11:54

Yo voto por......



delphi
  1. procedure QueHagoConLaTabla(Forma: TForm; Estado: Bool);
  2. begin
  3. end;



:D :D :D

Salud OS


jajaja, ¿qué haremos contigo? :D :D, pues sí Delphius tienes razón en cuanto al nombre, el de ActivarTablas queda mejor. Gracias ;).

Saludos.
  • 0

#14 Delphius

Delphius

    Advanced Member

  • Moderador
  • PipPipPip
  • 6.295 mensajes
  • LocationArgentina

Escrito 31 diciembre 2008 - 12:05

Amigo, no cambies el nombre porque un burro filósofo se pone curiosear en el trabajo de uno.
Si a te sienta bien el nombre AbrirTablas, déjalo. Uno debe sentirse a cómodo con su código, no porque otro le dice algo debe necesariamente cambiar.
Lo principal cuando uno escribe código es tenerlo legible, de acuerdo a su percepción del todo (en caso de que sea un trabajo en grupo, se supone que se mantiene fiel a los objetivos generales de todo el grupo)

Nomás es que ando en modo filósofo :p.

Saludos,
  • 0

#15 enecumene

enecumene

    Webmaster

  • Administrador
  • 7.409 mensajes
  • LocationRepública Dominicana

Escrito 31 diciembre 2008 - 12:09

No hombre, no lo hago porque quieres que sea así, sino, que en realidad ese nombre va mejor :D, y además tengo pensado recopilar una buena cantidad de funciones y procedimientos útiles en una Unidad para luego aportarlo aquí en el foro, y si eso es lo que deseo es bueno tenerlo legible como bien dices, para todos el que lo necesite.

Saludos.
  • 0

#16 eduarcol

eduarcol

    Advanced Member

  • Moderador
  • PipPipPip
  • 4.483 mensajes
  • LocationVenezuela

Escrito 31 diciembre 2008 - 05:48

Solo una recomendacion, NO UTILIZES ZTABLE  8o|...
jejeje, en serio te recomendaria que utilizes query con filtro, eso mejoraria mucho el rendimiento de tu programa
  • 0

#17 Al González

Al González

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 99 mensajes

Escrito 01 enero 2009 - 04:55

¡Hola a todos!

Esto me recuerda a un caso similar de GH Freebrary.  Básicamente lo que tengo es una clase llamada TghForm, derivada de TForm, y la razón de ello es contar con características adicionales para todos mis formularios, entre ellas un método llamado OpenDataSources, que es similar a la útil función que plantea Fernando, sólo que lo hace a través de las fuentes de datos (data sources) que contenga el formulario, sirviendo así, ya sea para los casos donde tengamos los conjuntos de datos (tablas y consultas) en el propio formulario o bien en un módulo de datos (queda abierto a ambos casos).  Claro está, debe haber un DataSource asociado a cada conjunto de datos para que éste sea abierto.

Entonces cuando creo un nuevo formulario, sólo cambio la cabecera


delphi
  1. TForm1 = class(TForm)


por


delphi
  1. TForm1 = class(TghForm)



Con lo cual, cuando quiero abrir los conjuntos de datos que usa el formulario, sólo llamo al método sin necesidad de parámetros, puesto que es parte de la nueva herencia, y todo queda más orientado a objetos:



delphi
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. begin
  3.   OpenDataSources;
  4. end;



Aclaro que este no es un caso de herencia visual (que también hay que aprovecharla cuando convenga), ya que TghForm no tiene diseño visual definido (archivo DFM), sólo es .pas, y simplemente sustituyo el nombre de la clase padre en la declaración de los nuevos formularios para hacer que estos deriven de una clase enriquecida con utilidades de uso común que he ido creando para los formularios.

Te recomiendo considerar un esquema similar (la función como método), aunque también hay que ser justos y decir que la principal ventaja de mantener la rutina como función independiente es que podrá aplicarse, sin condiciones especiales de herencia, con cualquier formulario.  Esta libertad de acción es la que me ha motivado a crear una cantidad mucho mayor de funciones que de clases, pero en un lenguaje orientado a objetos es bueno poner en la balanza a éstas últimas cada vez que se va a crear algo y tomar una decisión en base a ambos mundos (el funcional y el de los objetos).

Independientemente de lo anterior, considera la posibilidad de que tu rutina trate no sólo con componentes de un tipo específico, sino con todos los que sean derivados de TDataSet (TQuery, TZTable, TADODataSet, TIBQuery, TClientDataSet, TMDOQuery, etc.).  Aprovecha el polimorfismo:



delphi
  1. If Components [I] Is TDataSet Then
  2.   TDataSet (Components [I]).Open;



Si a alguien le interesa usar o al menos echar un vistazo a GH Freebrary, con gusto pueden descargarla de aquí.  Es freeware, aunque la haré todavía más libre cuando termine de convertirla al inglés.

Espero haber contribuido positivamente.

Un abrazo abierto.

Al González. :)
  • 0

#18 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.256 mensajes
  • LocationMéxico

Escrito 01 enero 2009 - 05:22

Siempre es muy interesante leer como a través de tu experiencia nos proporcionas tanto conocimiento, gracias Alberto, siempre es un gusto leerte.

Salud OS
  • 0

#19 enecumene

enecumene

    Webmaster

  • Administrador
  • 7.409 mensajes
  • LocationRepública Dominicana

Escrito 02 enero 2009 - 07:12

Solo una recomendacion, NO UTILIZES ZTABLE  8o|...
jejeje, en serio te recomendaria que utilizes query con filtro, eso mejoraria mucho el rendimiento de tu programa


Eduarcol, eso es sólo en este caso, el código es algo como quién dice, algo beta, la iré mejorando para que se pueda aplicar cualquier tipo de Dataset dependiendo del caso, leyendo el comentario de Al, me ha dado unas cuantas ideas, gracias Al


Saludos.
  • 0

#20 enecumene

enecumene

    Webmaster

  • Administrador
  • 7.409 mensajes
  • LocationRepública Dominicana

Escrito 02 enero 2009 - 04:10

Bueno, siguiendo en la línea del comentario de Al, y me puse a analizar, en un formulario pueden haber datasets que no se requerirán de su apertura en un determinado momento, por ejemplo, al crear o llamar un formulario, como en el caso de los Querys, hay momento en que los querys no se darán apertura, esa es una de las razones que decidí usar la clase TDataSource en vez de TDataSet o TTable, total este procedimiento sólo lo hago para cuando creo el formulario y abrir las tablas que se requieran en ese momento, aquí el arreglo:



delphi
  1. procedure ActivarTablas(Forma: TForm; Estado: Bool);
  2. var nIdx: Integer;
  3. begin
  4.   for nIdx := 0 to Forma.ComponentCount - 1 do
  5.   begin
  6.       if Forma.Components[nIdx] is TDataSource then
  7.         TDataSource(Forma.Components[nIdx]).DataSet.Active := Estado;
  8.   end;
  9. end;



Saludos.
  • 0