[Lazarus-es] [***SPAM*** Score/Req: 6.1/5.0] Re: Error en formularios y lazreport

Ismael L. Donis Garcia slibre en citricos.co.cu
Mie Jul 22 19:24:35 CEST 2015


Yo lo hago medio parecido porque minimalizo mucho más:

- No inicio el formulario principal.
- No tengo una unidad para las cosas globales
- Solo inicialiso el modulo de datos y lo que tu tienes en la unidad yo lo 
incluyo en el modulo de datos

Y desde el modulo de datos inicializo el formulario de logeo y el formulario 
principal, osea no entro al formulario principal si no me logeo.

Y en el proyecto solo cargo el modulo de datos:

  Application.Initialize;
  Application.CreateForm(Tdm, dm);
  Application.Run;

Ya todo lo demás bastante igual a lo que haces.

Saludos Cordiales
========
| ISMAEL |
========
Only for the small landowners and Cubans companies
Website: www.sisconge.byethost15.com
              www.sisconge.hol.es
----- Original Message ----- 
From: "Maikel Enrique Pernia Matos" <corba en grannet.grm.sld.cu>
To: "Spanish version of Lazarus List" 
<lazarus-es en lists.lazarus.freepascal.org>
Sent: Wednesday, July 22, 2015 10:52 AM
Subject: [***SPAM*** Score/Req: 6.1/5.0] Re: [Lazarus-es] Error en 
formularios y lazreport


Colegas Ismael y Maxi:

Disculpen mi intromisión en su excelente colaboración pero quisiera
compartir con ustedes la forma en que generalmente trato de hacer estas
cosas

Supongamos que vamos a desarrollar un proyecto que tenga los siguientes
requerimientos funcionales:
0- Gestión de Base de Datos.
1- Impresión de información (reportes).
1- Multiusuario.
2- Varias interfaces de trabajo (formularios).

¿Como lo hago?
0- Los siguientes formularios son creados automaticamente por el
   proyecto:
   a) Ventana principal
   b) Modulo de datos (TDataModule)
   c) Formulario para creación de reportes si se utiliza el entorno
      gráfico del IDE para especificar sus propiedades. También utilizo
      unidades en caso que toda la generación de los reportes se
      implemente por código
   d) Una unidad en la que implemento todos los procedimientos y
      funciones de alcance general es decir que puedan ser necesarias
      en diferentes momentos.
   e) Creación y destrucción de las restantes interfaces en el momento
      que son requeridas, tengamos en cuenta que todo lo que
      inicialicemos, variables e instancias de clases consumen memoria.
   f) Según sea necesario incluyo en la clausula «uses» de las
      interfaces descritas en en el inciso «B» las correspondientes a
      los incisos: b, c, d.

Un ejemplo:

tengo un proyecto con 4 clases:
0- TForm principal
1- TForm de login
2- TDatamodule
3- Unidad de funciones


El fuente del proyecto quedaría así:
  Application.Initialize;
  Application.CreateForm(TdmDatos, dmDatos);
  Application.CreateForm(TfrmMain, frmMain);
  Application.Run;

Como ven llamo al TDataModule (dmDatos) antes del TForm principal
(frmMain),con esto garantizo cargar al menos la conexión a la BD
y las tablas: usuarios y privilegios de usuarios.

----------------------------------------------------------------

En el evento OnCreate del formulario principal llamo al form
que gestiona usuarios y aplica sus privilegios en el programa

procedure TfrmMain.FormCreate(Sender: TObject);
begin
   Application.CreateForm(TfrmLogin, frmLogin);
   frmLogin.ShowModal;
   frmLogin.Free;
end;


----------------------------------------------------------------

En la clausula uses de frmLogin incluyo la unidad que almacena mis
funciones generales y los objetos de BD :

uses module, functions;

Esto me permite llamar al la función de verificación de privilegios
implementada en la unidad «functions» y que afecta a la ventana
principal «frmMain» en el evento OnClick del botón «aceptar» en
frmLogin

procedure TfrmLogin.btnAceptClick(Sender: TObject);
begin
   {
    verificar usuario y contraseña
    si coinciden entonces llamar a la función
    que verifica privilegios y cerrar el TForm
    envío como argumento el «id» del usuario
   }
   usersConcession(id);
   frmLogin.Close;
   {
    en caso contrario notificación del error en los datos de
    inicio de sesión
   }
end;

----------------------------------------------------------------

La unidad con mis funciones generales quedaría así:
unit functions;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, Process, Forms, Controls, Dialogs, ZConnection, ...


procedure usersConcession(User : Integer);

...

implementation

uses module, main;

procedure usersConcession(User : Integer);
var
  access : Boolean;
begin
   {
    Hacer la rutina para el chequeo de privilegios
    por usuario para luego habilitar/deshabilitar
    objetos según necesidad, asignando el valor
    (True o False) a la variabnle «access».
   }
   with frmMain do
   begin
      {
       habilitando/deshabilitando un objeto del tipo
       TAction en la ventana principal, la ventaja de
       utilizar este tipo de objeto y enlazarlos con los
       TMenuItem y los TToolButton es que deshabilitando el
       TAction se inhabilitan los TMenuItem y los TToolButton
       relacionados.
       }
      ...
      actConfig.Enabled := access;
      ...
   end;
end;

----------------------------------------------------------------

Un trozo del modulo de datos, en el evento OnCreate
establezco la conexión a la Base de Datos.

...
  TdmDatos = class(TDataModule)
     connect: TZConnection;
     qryTmp: TZQuery;
...
    procedure DataModuleCreate(Sender: TObject);
...

procedure TPerpe.DataModuleCreate(Sender: TObject);
begin
   with connect do begin
      Database := '/ruta/a/base/de/datos';
      Protocol := 'sqlite-3';
      Connected := True;
   end;
end;

Saludos,
Maikel

El mar, 21-07-2015 a las 16:36 -0400, Ismael L. Donis Garcia escribió:
> Respondo entre Líneas
> ========
> | ISMAEL |
> ========
> Only for the small landowners and Cubans companies
> Website: www.sisconge.byethost15.com
>               www.sisconge.hol.es
> >----- Original Message ----- 
> >From: "Maxi" <maximiliano.duarte en gmail.com>
> >To: "Spanish version of Lazarus List"
> ><lazarus-es en lists.lazarus.freepascal.org>
> >Sent: Monday, July 20, 2015 4:25 PM
> >Subject: Re: [Lazarus-es] Error en formularios y lazreport
> >
>
> >es porque en algun momento estas llamando algo que ya se destruyó o el
> >reporte intenta acceder a algo que no puede.
> >
> >Cada formulario tiene una variable publlica con el objeto por lo que
> >si puedes llamarlo.
> >
> >Si Tdm.IniSis(); se usa para iniciar para que lo vuelves a llamar?
>
> Porque al logearte seleccionas la unidad en la que vas a trabajar, y según
> el usuario que te logees seran los permisos que tengas y a las opciones 
> del
> sistema que puedas entrar y que tengas visibles en los menus.
>
> >Te digo como hago siempre yo en mis aplicaciones
> >
> >Desde el proyecto dejo crear automaticamente:
> >Modulo de datos con conexion a DB solamente
> >->Antes del seguir valido el usuario sino cierro todo
> >Modulo de datos con tablas y consultas
> >Modulo de datos con lookups
> >Formulario principal
>
> Tengo antes un formulario de información que es el splash
> Después un formulario de logeo donde seleccionas la entidad en la que vas 
> a
> trabajar y se logea el usuario con el sistema
> Y después de logeado es que entra el formulario principal.
>
> >Despues de iniciar recien llamo al resto de cosas despues de iniciar
> >el form principal. Y uso herencia de formularios, me ahorra mucho
> >codigo y configuraciones.
>
> >Lo que noté que el splash lo creas pero no lo destruyes. y si un
> >formulario lo vas a recrear luego he visto que usan .FreeAndNil.
> >Por eso es mejor crearlo en en proyecto y destruirlo lo antes posible.
>
> Si lo destuyo lo que lo hago en otro procedimieto que no te lo havía 
> puesto
> por no considerarlo necesario:
>
>
> procedure Tdm.entrar();
> begin
>   if length(struser) = 0 then struser := 'administrador';
>   if (cnsc.Connected or cnsch.Connected or cnos.Connected) then
> FinConexServer();
>   IniConexServer;
>   Application.CreateForm(Tflogin, flogin);
>   flogin.ShowModal;
>   flogin.Free;
>   if blnend then
>     cerrarme()
>   else
>     begin
>       fconta.lblestado.Caption := 'Listo';
>       fconta.Show;
>       fsplash.Free;
>     end;
> end;
>
> >
> >cambia la creacion:
> >Application.CreateForm(Tfconta, fconta);
> >por
> >Tfconta.Create(Application);
> >
>
> No lo puedo hacer porque sino falla el siguiente procedimieto que está
> dentro del formulario "flogin" ya que no encuentra inicialzado al 
> formulario
> "fconta"
>
> procedure Tflogin.mnuother(buser: boolean);
>   begin
>     with fconta do begin
>       mnuherod.Visible := buser;
>       mnuherbh.Visible := buser;
>       mnuhercs.Visible := buser;
>       mnuherbar2.Visible := buser;
>       mnuherec.Visible := buser;
>       mnuhercp.Visible := buser;
>       mnuherbar3.Visible := buser;
>       mnuherid.Visible := buser;
>       mnuhereh.Visible := buser;
>       mnuherbar4.Visible := buser;
>   end;
> end;
>
> >Aunque insisto que eso solo sirve si deseas que el objeto Application
> >se encargue de destruir todo al cerrar la aplicacion.
> >
> >Para el splash esto:
> >begin
> >  RequireDerivedFormResource := True;
> > Application.Initialize;
> >  splash :=(TFormSplash.Create(nil);
> >  splash.update;
> >  Application.CreateForm(TForm1, Form1);
> >  Application.CreateForm(TForm2, Form2);
> >  Application.CreateForm(TForm3, Form3);
> >  ... mas formularios
> >  splash.Free;
> > Application.Run;
> >end.
>
> Para splah lo cambié por:
>   fsplash:=Tfsplash.Create(nil);
>   fsplash.Update;
>
> Como me comentaste pero sigue dando el mismo error al generar el error
> después de ejecutar el procedimiento procedure Tdm.IniSis(); por segunda
> vez.
>
> También cambie a fconta por:
>   fconta:=Tfconta.Create(nil);
>   fconta.Update;
>
> Y ejecuta igual que como lo tenía antes, pero también da el mismo error.
>
> >
> >Seguimos en contacto
> >
>
> Este día lo tove todo ocupado que recien ahora es que me puedo sentar
> delante de la PC
>
> Seguimos en contacto
>
> >El día 20 de julio de 2015, 16:49, Ismael L. Donis Garcia
> ><slibre en citricos.co.cu> escribió:
> >> Respondo entre lineas.
> >>
> >> Ante todo recuerda que nunca he trabajado con Delphi por lo que 
> >> provengo
> >> de
> >> la filosofía de Microsoft la cual de hecho me gusta mucho "me refiero 
> >> la
> >> filosofía de programación".
> >>
> >>> ----- Original Message ----- From: "Maxi" 
> >>> <maximiliano.duarte en gmail.com>
> >>> To: "Spanish version of Lazarus List"
> >>> <lazarus-es en lists.lazarus.freepascal.org>
> >>> Sent: Monday, July 20, 2015 12:54 PM
> >>> Subject: [Lazarus-es] Error en formularios y lazreport
> >>>
> >>
> >>> El día 18 de julio de 2015, 11:57, Ismael L. Donis Garcia
> >>> <slibre en citricos.co.cu> escribió:
> >>>
> >>>> En el encabezamiento del grupo das click secundario y marcas las 
> >>>> opción
> >>>> de
> >>>> Forzar Nueva Página.
> >>>>
> >>>> Respecto a Delphi ni me preguntes. Jamas en la vida lo he usado, 
> >>>> nunca
> >>>> me
> >>>> ha
> >>>> gustado. En windows siempre había trabajado con Visual Estudio.
> >>>>
> >>>> He mirado a Lazarus porque es libre y multiplataforma y como yo me he
> >>>> tirado
> >>>> ultimamente para Linux, soy el encargado en mi empresa en difundir el
> >>>> soft
> >>>> libre. De hecho el sistema operativo que uso por defecto es Jessie,
> >>>> aunque
> >>>> tengo PC virtuales con 1 millón de sistemas porque viy haciendo
> >>>> estudios
> >>>> de
> >>>> los que puedo hacerme, ahora mismo estoy mirando a Manjaro OpenRC el
> >>>> cual
> >>>> ha
> >>>> tenido una bueba aceptación.
> >>>>
> >>>> En estos momentos estoy parado en Lazarus, hoy voy a instalar la
> >>>> versión
> >>>> 1.4.2 a ver si me resuelve un problema que tengo precisamente con
> >>>> lazreport
> >>>> el cual me da una ecepción si cierro todos los formulario abiertos
> >>>> desde
> >>>> un
> >>>> modulo de datos y los vuelvo a abrir. Al volver abrir los formulario 
> >>>> y
> >>>> tratar de visualizar algo en lazreport este tira una ecepción y me
> >>>> cierra
> >>>> el
> >>>> programa la rutina que tengo para cerrar los formularios es la
> >>>> siguiente:
> >>>>
> >>>> procedure Tdm.IniSis();
> >>>> var
> >>>> f: Tforigen;
> >>>>  i: integer;
> >>>> begin
> >>>>  DecimalSeparator:='.';
> >>>>  ThousandSeparator:=',';
> >>>>  ShortDateFormat := 'dd/mm/yyyy';
> >>>>  blnend := false;
> >>>>  intciclo := 0;
> >>>>  intfilas := 0;
> >>>>  intnivel := 0;
> >>>>  lngentidad := 0;
> >>>>  struser := '';
> >>>>  strerror := '';
> >>>>  for i := Screen.FormCount - 1 downto 0 do begin
> >>>>    if Screen.Forms[i].Name <> Self.Name then begin
> >>>>      if Screen.Forms[i].Name <> 'fconta' then Screen.Forms[i].Free;
> >>>>    end;
> >>>>  end;
> >>>>  for i := Screen.FormCount - 1 downto 0 do begin
> >>>>    if Screen.Forms[i].Name <> Self.Name then Screen.Forms[i].Free;
> >>>>  end;
> >>>>  Application.CreateForm(Tfconta, fconta);
> >>>>  Application.CreateForm(Tfsplash, fsplash);
> >>>> fsplash.Show;
> >>>>  Application.ProcessMessages;
> >>>>  if datos() then
> >>>>    entrar()
> >>>>  else
> >>>>    begin
> >>>>      f:=Tforigen.Create(Self);
> >>>>      f.IniSystem:=true;
> >>>>     f.ShowModal;
> >>>>     f.Free;
> >>>>      if blnend then
> >>>>        cerrarme()
> >>>>      else if datos() then
> >>>>        begin
> >>>>          intciclo := intciclo + 1;
> >>>>         entrar()
> >>>>        end
> >>>>      else
> >>>>        cerrarme();
> >>>>    end;
> >>>> end;
> >>>>
> >>>> El error que me da es el siguiente:
> >>>> El proyecto XXXX  ha lanzado una excepción de la clase Éxternal:
> >>>> SIGSEGV'
> >>>> En
> >>>> Archivo '.\include\control.inc'en linea 3260
> >>>>
> >>>> Pero no veo cual puede ser el error porque si no cierro los 
> >>>> formularios
> >>>> con
> >>>> la rutina anterior nunca me da ese error, lo peor del caso es que a
> >>>> veces
> >>>> si
> >>>> tengo que utilizar ese procedimiento.
> >>>>
> >>>> Por ese motivo voy a instalar la versión 1.4.2 a ver si persiste el
> >>>> problema.
> >>>>
> >>>> Saludos Cordiales
> >>>> ========
> >>>> | ISMAEL |
> >>>> ========
> >>>
> >>>
> >>> Paso a otro hilo para que sirva despues.
> >>>
> >>> Creo que primero debes dejar al modulo de datos solo para datos, y
> >>> hacer las creaciones y destrucciones mas controladas.
> >>>
> >>>>  Application.CreateForm(Tfsplash, fsplash);
> >>>> fsplash.Show;
> >>>
> >>>
> >>> el splash lo creas en el proyecto
> >>
> >>
> >> Ya esta creado en el proyecto el formulario. En esas lineas lo que hace
> >> segun la filosofía de microsoft es
> >> 1.- crear una instancia del formulario
> >> 2.- mostrar la intancia
> >>
> >> Yo en las propiedades del proyecto tengo a modulo de datos solamente 
> >> para
> >> que se cree el formulario automaticamente los demás no.
> >>
> >>>
> >>>>  Application.CreateForm(Tfconta, fconta);
> >>>
> >>>
> >>> No usaria esto sino Tfconta.Create(self), aunque en tu caso usaria el
> >>> envento occlose y le pondria caFree, que lo destruye al salir del
> >>> form, con eso te olvidas de liberarlo y no usaria Self sino nil (sin
> >>> pariente)
> >>
> >>
> >> Si pongo:
> >> Tfconta.Create(self);
> >> o
> >> Tfconta.Create(nil);
> >>
> >> Despues no puedo mostrar el formulario con:
> >> fconta.Show;
> >>
> >> Ni tampoco puedo usar el siguiente procedimiento por ejemplo ''que lo 
> >> uso
> >> tal como está" lo cual tengo en otro formulario.
> >>
> >> procedure Tflogin.mnuother(buser: boolean);
> >> begin
> >>  with fconta do begin
> >>    mnuherod.Visible := buser;
> >>    mnuherbh.Visible := buser;
> >>    mnuhercs.Visible := buser;
> >>    mnuherbar2.Visible := buser;
> >>    mnuherec.Visible := buser;
> >>    mnuhercp.Visible := buser;
> >>    mnuherbar3.Visible := buser;
> >>    mnuherid.Visible := buser;
> >>    mnuhereh.Visible := buser;
> >>    mnuherbar4.Visible := buser;
> >>  end;
> >> end;
> >>
> >> Ya que no encuentra a fconta
> >>
> >>>
> >>> procedure TFormPrincipal.FormClose(Sender: TObject;  var
> >>> CloseAction:TCloseAction);
> >>> begin
> >>>  CloseAction:=caFree;
> >>> end;
> >>>
> >>
> >> Puse la declaración CloseAction:=caFree; en todo los FormClose y 
> >> persiste
> >> el
> >> problema
> >>
> >>>
> >>> Te ayudo si quieres
> >>>
> >>
> >> No estaría de más, por el contrario sería bien venida toda ayuda.
> >>
> >> Así como lo tengo todo funciona bien. Excepto los reportes que si se
> >> visualizan bien la primera vez que se use el procedimiento procedure
> >> Tdm.IniSis(); pero si lo ejecuto por segunda vez entonces es cuando me
> >> dan
> >> error los reportes.
> >>
> >> Ese procedimieto se ejecuta siempre al iniciar la apliación y ahi todo
> >> funciona bien, pero si mando a ejecutar ese procedimiento por segunda 
> >> vez
> >> los reportes dan error, pero el trabajo con los formularios no da error
> >> alguno.
> >>
> >> Saludos Reiterados
> >> ========
> >> | ISMAEL |
> >> ========
> >> Only for the small landowners and Cubans companies
> >> Website: www.sisconge.byethost15.com
> >>              www.sisconge.hol.es
>
>
>
> _______________________________________________
> Lazarus-es mailing list
> Lazarus-es en lists.lazarus.freepascal.org
> http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus-es



--
Este mensaje le ha llegado mediante el servicio de correo electronico que 
ofrece Infomed para respaldar el cumplimiento de las misiones del Sistema 
Nacional de Salud. La persona que envia este correo asume el compromiso de 
usar el servicio a tales fines y cumplir con las regulaciones establecidas

Infomed: http://www.sld.cu/


_______________________________________________
Lazarus-es mailing list
Lazarus-es en lists.lazarus.freepascal.org
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus-es






More information about the Lazarus-es mailing list