Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   OOP (https://www.clubdelphi.com/foros/forumdisplay.php?f=5)
-   -   Decidir que Form abre primero en una aplicación (https://www.clubdelphi.com/foros/showthread.php?t=89596)

ZiriusB 21-12-2015 03:46:35

Decidir que Form abre primero en una aplicación
 
Buenas noches, estoy realizando una aplicación en la que me abre un form de "Apertura de Caja" en la que coloco el monto inicial de la caja, luego al hacer clic en aceptar me abre el form principal en donde tengo el menú y esas cosas...

El form de "Apertura de caja" debe salir solo al inicio del día, es decir una vez que el usuario haya introducido la cantidad, el cliente puede cerrar la aplicación y volver a abrirla y ya no debería salir mas el Form "Apertura de Caja" sino pasar directamente al Form principal...


¿Hay alguna forma de hacerlo?

AgustinOrtu 21-12-2015 04:22:57

El framework VCL necesita:

1. Se setee el "MainForm" de la aplicacion. Este debe ser una variable global definida en la seccion interface de la unidad del form
2. El form se inicializa no con su constructor Create, sino mediante Application.CreateForm
3. Cuando el MainForm es cerrado, la aplicacion termina

Esta implementacion no la podes cambiar

Yo creo que la opcion mas sana es, dejar el que tenes como "menu principal" como MainForm; luego realizar la validacion "si no introdujo la cantidad para hoy" --> crear y mostrar form caja, caso contrario, seguir con el principal

Ejemplo trivial

Código Delphi [-]
function IntrodujoCantidad: Boolean;
begin
  Result := False;
end;

var
  FormCaja: TForm3;
begin
  Application.Initialize;
  Application.MainFormOnTaskbar := True;
  Application.CreateForm(TForm2, Form2);
  if not IntrodujoCantidad then
  begin
    FormCaja := TForm3.Create(NIL);
    try
      FormCaja.ShowModal;
    finally
      FormCaja.Free;
    end;
  end;

  Application.Run;
end.

ecfisa 21-12-2015 07:32:27

Hola ZiriusB.
Cita:

Empezado por ZiriusB (Mensaje 500691)
...
El form de "Apertura de caja" debe salir solo al inicio del día, es decir una vez que el usuario haya introducido la cantidad, el cliente puede cerrar la aplicación y volver a abrirla y ya no debería salir mas el Form "Apertura de Caja" sino pasar directamente al Form principal...

Para que se ejecute una vez por día (la primera vez que se abra la aplicación) podes hacer:
Código Delphi [-]
program Project1;

uses
  Forms, Windows, SysUtils, Registry,
  Unit1 in 'Unit1.pas' {frmMain},
  Unit2 in 'Unit2.pas' {frmDailyCashBox};

{$R *.res}

function isSetDailyCashBox: Boolean;
const
  KNAME = 'SoftWare\Your_App_Name\DailyCashBox';
  VNAME = 'LastUpdate';
var
  rg: TRegistry;
  dt: TDateTime;
begin
  rg         := TRegistry.Create;
  rg.RootKey := HKEY_CURRENT_USER;
  dt         := 0;
  rg.OpenKey(KNAME, True);
  try   
    if not rg.ValueExists(VNAME) then
      rg.WriteDate(VNAME, dt);
    dt     := rg.ReadDate(VNAME);
    Result := dt = Date;
    rg.WriteDate(VNAME, Date);
  finally
    rg.CloseKey;
  end;
end;

begin
  Application.Initialize;
  Application.CreateForm(TfrmMain, frmMain);
  Application.ShowMainForm := False;

  if not isSetDailyCashBox then
  begin
    frmDailyCashBox := TfrmDailyCashBox.Create(nil);
    try
      frmDailyCashBox.ShowModal;
    finally
      frmDailyCashBox.Free;
    end;
  end;

  Application.ShowMainForm := True;
  Application.Run;
end.

Saludos :)

ZiriusB 21-12-2015 17:19:22

Cita:

Empezado por ecfisa (Mensaje 500696)
Hola ZiriusB.


Código Delphi [-]
program Project1;

uses
  Forms, Windows, SysUtils, Registry,
  Unit1 in 'Unit1.pas' {frmMain},
  Unit2 in 'Unit2.pas' {frmDailyCashBox};

{$R *.res}

function isSetDailyCashBox: Boolean;
const
  KNAME = 'SoftWare\Your_App_Name\DailyCashBox';
  VNAME = 'LastUpdate';
var
  rg: TRegistry;
  dt: TDateTime;
begin
  rg         := TRegistry.Create;
  rg.RootKey := HKEY_CURRENT_USER;
  dt         := 0;
  rg.OpenKey(KNAME, True);
  try   
    if not rg.ValueExists(VNAME) then
      rg.WriteDate(VNAME, dt);
    dt     := rg.ReadDate(VNAME);
    Result := dt = Date;
    rg.WriteDate(VNAME, Date);
  finally
    rg.CloseKey;
  end;
end;

begin
  Application.Initialize;
  Application.CreateForm(TfrmMain, frmMain);
  Application.ShowMainForm := False;

  if not isSetDailyCashBox then
  begin
    frmDailyCashBox := TfrmDailyCashBox.Create(nil);
    try
      frmDailyCashBox.ShowModal;
    finally
      frmDailyCashBox.Free;
    end;
  end;

  Application.ShowMainForm := True;
  Application.Run;
end.

Saludos :)

Buenis dias, gracias por la respuesta, dos preguntas:

1.- El registro de validacion ¿donde se guarda? es decir, al abrir el programa luego de abrirlo por primera vez, donde revisa el sistema si ya se ha introducido el valor en dailycashBox...

2.- Tenia el Form de "Apertura de Caja" como principal, debo establecer el "Form1" como principal con esta funcion? (Project>>options>>forms)

AgustinOrtu 21-12-2015 17:57:46

Cita:

Empezado por ZiriusB (Mensaje 500703)
1.- El registro de validacion ¿donde se guarda? es decir, al abrir el programa luego de abrirlo por primera vez, donde revisa el sistema si ya se ha introducido el valor en dailycashBox...

2.- Tenia el Form de "Apertura de Caja" como principal, debo establecer el "Form1" como principal con esta funcion? (Project>>options>>forms)

1 - En realidad esa misma pregunta te la deberiamos hacer a vos: En algun lugar guardas la informacion? Usas alguna base de datos?


2 - Si

ecfisa 21-12-2015 17:59:06

Cita:

Empezado por ZiriusB (Mensaje 500703)
1.- El registro de validacion ¿donde se guarda? es decir, al abrir el programa luego de abrirlo por primera vez, donde revisa el sistema si ya se ha introducido el valor en dailycashBox...

Si te referis donde se guarda la última fecha de ajuste de caja en el ejemplo, es en el registro de Windows. Esta se coteja con la actual del sistema y de ser diferente indíca que el formulario inicialización no fué abierto en la fecha.

El ejemplo no contempla si fué efectiva y correctamente inicializada la caja. De esta taréa creo que debería encargarse frmDailyCashBox y desconozco la lógica que tenes pensada para ese punto, por ejemplo ignoro que es el "registro de validación".
El lugar de guardado podría ser en el registro de Windows, en tu base de datos, un archivo, etc., depende de como tengas pensado implementarlo.

Cita:

Empezado por ZiriusB (Mensaje 500703)
2.- Tenia el Form de "Apertura de Caja" como principal, debo establecer el "Form1" como principal con esta funcion? (Project>>options>>forms)

Si. Tu formulario principal será el primero que se cree, es decir el que figura encabezando la lista en la ventana Project->Options->Forms->Auto-create forms.
O, mirando el código del proyecto, es el primero en crearse; ejemplos:
Código Delphi [-]
...
begin
  Application.Initialize;
  Application.CreateForm(TfrmMain, frmMain); // frmMain es el principal
Código Delphi [-]
...
begin
  Application.Initialize;
  Application.CreateForm(TForm1, Form1); // Form1 es el principal

Saludos :)

Edito: No había visto la respuesta de Agustín mientras redactaba este mensaje pero coincido con él.

ZiriusB 21-12-2015 18:24:27

Cita:

Empezado por AgustinOrtu (Mensaje 500706)
1 - En realidad esa misma pregunta te la deberiamos hacer a vos: En algun lugar guardas la informacion? Usas alguna base de datos?


2 - Si

Uso una base de datos, donde guardo el monto form "apertura de caja", ese monto que guardo es el que quiero validar a la hora de abrir el form "apertura de caja" o el "Form Principal"


Cita:

Empezado por ecfisa (Mensaje 500707)
Si te referis donde se guarda la última fecha de ajuste de caja en el ejemplo, es en el registro de Windows. Esta se coteja con la actual del sistema y de ser diferente indíca que el formulario inicialización no fué abierto en la fecha.

El ejemplo no contempla si fué efectiva y correctamente inicializada. De esta taréa creo que debería encargarse frmDailyCashBox y desconozco la lógica que tenes pensada para ese punto, por ejemplo ignoro que es el "registro de validación".
El lugar de guardado podría ser en el registro de Windows, en tu base de datos, un archivo, etc., depende de como tengas pensado implementarlo.


Si. Tu formulario principal será el primero que se cree, es decir el que figura encabezando la lista en la ventana Project->Options->Forms->Auto-create forms.
O, mirando el código del proyecto, es el primero en crearse; ejemplos:
Código Delphi [-]... begin Application.Initialize; Application.CreateForm(TfrmMain, frmMain); // frmMain es el principal

Código Delphi [-]... begin Application.Initialize; Application.CreateForm(TForm1, Form1); // Form1 es el principal


Saludos :)

Edito: No había visto la respuesta de Agustín mientras redactaba este mensaje pero coincido con él.

Con "registro de validacion" me referia a lo que veo que en la funcion se estaba guardando. fue solo por ponerle un nombre, jejejeje.

ecfisa 21-12-2015 18:37:24

Hola ZiriusB.
Cita:

Empezado por ZiriusB (Mensaje 500708)
Uso una base de datos, donde guardo el monto form "apertura de caja", ese monto que guardo es el que quiero validar a la hora de abrir el form "apertura de caja" o el "Form Principal"

¿ Contra que valor debe validarse ese monto y donde se encuentra almacenado ?


Por otro lado te soy sincero, veo muy inseguro que el primer usuario en ejecutar la aplicación pueda modificar el valor de la caja... ¿ No debería realizarse esa acción de forma automática ? (Esto dicho desde la ignorancia que tengo sobre los detalles de la situación)

Saludos :)

AgustinOrtu 21-12-2015 18:38:15

Cita:

Empezado por ZiriusB (Mensaje 500708)
Uso una base de datos, donde guardo el monto form "apertura de caja", ese monto que guardo es el que quiero validar a la hora de abrir el form "apertura de caja" o el "Form Principal"

Nosotros te mostramos un ejemplo, el "esqueleto" del codigo que hace lo que preguntabas: "Si se da X, antes de mostrar principal, mostrar otro form; luego mostrar form principal"

Tenes que implementar "X": que es la funcion booleana del esqueleto

No sabemos como funciona la logica de negocio ni como se valida la cantidad.

Tampoco conocemos la estructura de la tabla en donde estas guardando la informacion

Por ejemplo, podrias tener un campo fecha y validar contra esa fecha

ZiriusB 21-12-2015 19:32:04

Cita:

Empezado por ecfisa (Mensaje 500709)
Hola ZiriusB.

¿ Contra que valor debe validarse ese monto y donde se encuentra almacenado ?

En realidad no se valida el monto, se valida la fecha en la que se introdujo el monto...

Tengo una tabla en la que se guarda ese monto:

idcaja int /// Autoincrementable
fechacaja datetime ///Fecha en la que se guarda el monto inicial
montocaja float //// el monto inicial de la caja
idusercaja int /// usuario que ingresa el monto (FK de otra tabla)




Por otro lado te soy sincero, veo muy inseguro que el primer usuario en ejecutar la aplicación pueda modificar el valor de la caja... ¿ No debería realizarse esa acción de forma automática ? (Esto dicho desde la ignorancia que tengo sobre los detalles de la situación)

No puede ser de forma automatica, el encargado del negocio llega y al abrir el sistema debe ingresar el monto inicial de la caja, es decir el dinero en efectivo que hay en la caja, gaveta, etc. al abrir el negocio.

Saludos :)

Cita:

Empezado por AgustinOrtu (Mensaje 500710)
Nosotros te mostramos un ejemplo, el "esqueleto" del codigo que hace lo que preguntabas: "Si se da X, antes de mostrar principal, mostrar otro form; luego mostrar form principal"

Tenes que implementar "X": que es la funcion booleana del esqueleto

No sabemos como funciona la logica de negocio ni como se valida la cantidad.

Tampoco conocemos la estructura de la tabla en donde estas guardando la informacion

Por ejemplo, podrias tener un campo fecha y validar contra esa fecha

Las mismas respuestas que di a ecfisa.

Agrego, el sistema es para el control de clientes de un gimnasio, ademas de el inventario y control de ventas del mismo, el motivo de ingresar el monto inicial de caja es para que al final del dia cuando se haga el "cierre de caja" el encargado pueda saber cuanto habia en la caja y que cantidad de dinero fue la ganancia del dia. (Igual esto lo puede saber si ve el historial de facturas, pero en caso de que sean varios encargados y por turno pues se lleva mejor el control.)

ecfisa 21-12-2015 19:35:52

Hola ZiriusB.
Cita:

Empezado por ZiriusB (Mensaje 500711)
En realidad no se valida el monto, se valida la fecha en la que se introdujo el monto...

Entonces el código del mensaje #3 te sirve perfectamente, sólo debes pedír el monto en el formulario al efecto y guardarlo donde corresponda.

Saludos :)

AgustinOrtu 21-12-2015 19:36:24

Entonces tenes que lanzar un query para obtener la ultima fecha de la caja

Código SQL [-]
SELECT TOP 1 * FROM Tabla
ORDER BY FechaCaja DESC

Esa fecha la comparas con la de hoy

AzidRain 21-12-2015 23:58:15

Todo esto huele a un mal diseño desde la base de datos...y la implementación igual o peor. Al ejecutar el sistema tenemos que conocer: ubicación de la caja-terminal, sucursal donde trabaja y día en que estamos. Con esos datos hay que ir a la base de datos y pedirle el saldo final del día anterior. El chiste aquí es que el corte se tiene que hacer al final de las operaciones y no al principio. Al finalizar cada día de trabajo se debe cacular y almacenar el saldo final del día (no importa en que fecha real se realice). Si la tienda o negocio permance abierto las 24 horas, se hace un cierre antes de las 24 horas y en su caso cualquier excedente corresponde al dia siguiente. El usuario no tiene por qué capturar cual es su saldo inicial pues eso se puede calcular fácilmente a partir de los datos almacenados. El hacerlo como lo planteas no solo es incorrecto sino que induce a errores, fraudes y demás pues el usuario puede poner lo que le plazca sin que sea validado por nadie.

Revisa mejor tu proceso (sin código) como lo realizan, mejóralo, asegúralo y entonces ya lo programas; de lo contrario es un barril sin fondo informático.

ZiriusB 03-01-2016 18:34:24

Cita:

Empezado por AzidRain (Mensaje 500714)
Todo esto huele a un mal diseño desde la base de datos...y la implementación igual o peor. Al ejecutar el sistema tenemos que conocer: ubicación de la caja-terminal, sucursal donde trabaja y día en que estamos. Con esos datos hay que ir a la base de datos y pedirle el saldo final del día anterior. El chiste aquí es que el corte se tiene que hacer al final de las operaciones y no al principio. Al finalizar cada día de trabajo se debe cacular y almacenar el saldo final del día (no importa en que fecha real se realice). Si la tienda o negocio permance abierto las 24 horas, se hace un cierre antes de las 24 horas y en su caso cualquier excedente corresponde al dia siguiente. El usuario no tiene por qué capturar cual es su saldo inicial pues eso se puede calcular fácilmente a partir de los datos almacenados. El hacerlo como lo planteas no solo es incorrecto sino que induce a errores, fraudes y demás pues el usuario puede poner lo que le plazca sin que sea validado por nadie.

Revisa mejor tu proceso (sin código) como lo realizan, mejóralo, asegúralo y entonces ya lo programas; de lo contrario es un barril sin fondo informático.

Buenas tardes, vi varios ejemplos en la red de sistemas en los que se pedia el monto de apertura de caja al abrir el sistema, por eso mi implementacion era así, sin embargo tome tu consejo y ahora el monto inicial de caja lo calcula automáticamente del monto que quedo del día anterior...

Ahora otro problema que planteo acá mismo ya que tiene que ver con algo parecido, tengo mi formulario de inicio de sesión donde me pide usuario y contraseña (formlogin), si el usuario y la contraseña son correctos entonces se cierra y abre el form donde están los menúes y opciones (formprincipal)

Código Delphi [-]
    Formlogin := TFormloginCreate(NIL);
    try
      Formlogin.ShowModal;
    finally
      Formlogin.Free;
    end;

Este es el codigo que tengo en el formprincipal, hasta ahi todo bien, al ejecutar la aplicacion me abre el formlogin y si la contraseña y el usuario son correcto me abre el formprincipal, el problema es que en el formlogin tengo dos botones "Ingresar" y "Cancelar", al darle click al boton cancelar me abre el formprincipal y lo cierra inmediatamente.

Asi valido en el formlogin al dar clic en el "boton aceptar":
Código Delphi [-]
    if (edtusuario.Text='') or (edtpassword.Text='') then
      begin
      ShowMessage('Rellene los campos necesarios');
      end

    else

    begin
    if (edtusuario.Text=ADOingresa.FieldByName('nombuser').asstring) and (edtpassword.Text=password) then
      begin
      Muser:= ADOingresa.FieldByName('idusuario').asinteger;
      form20.Close;
      end

    else

    begin
    ShowMessage('Datos incorrectos, verifique su usuario o contraseña');
    end;
    end;

en el boton cancelar tengo:

Código Delphi [-]
Application.terminate

¿Que estoy haciendo mal?

AzidRain 03-01-2016 22:31:42

Verifica como estás creando el form principal, si lo tienes en automático ponlo en manual y créalo tu mismo al momento del login exitoso. De esa manera si el usuario nunca se loguea el form principal nunca será creado.


La franja horaria es GMT +2. Ahora son las 10:15:57.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi