Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Varios
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 14-10-2003
NeWsP NeWsP is offline
Miembro
 
Registrado: oct 2003
Ubicación: Barcelona
Posts: 57
Poder: 21
NeWsP Va por buen camino
Problemas con MDI y Bases de datos

Buenas Noches, Este es mi primer Post en este foro, aunque llevo algun tiempo navegando por el, y viendo buenos resultados, asi que espero q me podais hechar una mano

Mi problema es el siguiente con el mdi:

1 - Tengo un Formulario padre , que al pulsar un boton aparece el hijo, que contiene un DBGRID entre otras cosas. Cuando en este formulario hijo pulso el boton "AÑADIR" se abre otro formulario ( NORMAL , ni hijo ni nada ) con una serie de campos para introducir los datos en la base de datos. cuando le doy al boton de INSERTAR DATOS , me da un error de memoria, el boton esta puesto asi

Form2.dbgrid1.ReadOnly := false;
Form2.table1.insert;
Form2.table1.FieldByName('Talleres').assString := Edit1.Text
Form2.table1.post;
Form2.dbgrid1.ReadOnly := true;

lo que no entiendo es pq si hago esa misma aplicacion sin formularios hijos ni padres, y estando el dbgrid en el Form1 si que funciona

Espero que me podais ayudar, estoy un poco desesperado ya.

Muchas Gracias

NeWsP
Responder Con Cita
  #2  
Antiguo 14-10-2003
__cadetill __cadetill is offline
Miembro
 
Registrado: may 2003
Posts: 3.387
Poder: 25
__cadetill Va por buen camino
Si debugeas la aplicación, en que linea exacta te salta la excepción? Qué clase de excepción es?

Un apunte. No son necesarias las lineas de ReadOnly a true/false
Otro apunte. Es mejor tener los Datasets en un DataModule para facilitar el acceso a ellos desde cualquier formulario y tenerlos bien localizados y agrupados
Responder Con Cita
  #3  
Antiguo 14-10-2003
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
Me suena a que Form2 es el formulario que te da Delphi por default y no el que creas en código. Posiblemente Form2 no esté en el "Autocreate" y de ahí que no puedas acceder a él. Asegúrate de que en INSERTAR DATOS te refieras no al formulario que te da Delphi sino al que tú mismo creas.

// Saludos
Responder Con Cita
  #4  
Antiguo 14-10-2003
NeWsP NeWsP is offline
Miembro
 
Registrado: oct 2003
Ubicación: Barcelona
Posts: 57
Poder: 21
NeWsP Va por buen camino
Gracias a los dos por contestar tan pronto

cadetill el error me lo da en todas las lineas del form3 ( el de insertar datos ) q tienen referencia al form2 y me da error de memoria violation adrees .....

roman , io el formulario hijo lo creo asi :

procedure Tform1.CrearHijo()
var
hijo : TForm2;
begin
hijo:= TForm2.Create(Application);
end;

CrearHijo();

asi es como creo el hijo.

E comprado sustituyendo el form2 de las lineas de antes por 'hijo' pero me dice q no esta declarado

alguna sugerencia please
Responder Con Cita
  #5  
Antiguo 14-10-2003
Avatar de guillotmarc
guillotmarc guillotmarc is offline
Miembro
 
Registrado: may 2003
Ubicación: Huelva
Posts: 2.638
Poder: 24
guillotmarc Va por buen camino
Hola.

Al crear los formularios de esta forma no puedes usar las variables Form1, Form2, ... (Además esas variables no son nada recomendables en aplicaciones como las MDI en que puedes tener más de un formulario del mismo tipo cargados en pantalla).

El problema de utilizar la variable Hijo es que donde la has declarado, solo existe durante la ejecución de CrearHijo.

Deberías declarar la variable en un ámbito superior, para que se pueda usar en cualquier lugar del ámbito. Por ejemplo, en la sección Private del formulario que lo llama, o directamente en el modulo del Formulario, ...

Aunque personalmente no me gustan mucho este tipo de variables pseudo-globales, y solo las utilizo cuando són estrictamente imprescindibles.

En tu caso, por ejemplo, si el código que da el error está en el mismo formulario, no hace falta que especifiques el formulario (se asume por defecto la instancia que se está ejecutando).

Es decir cambia el código por :

dbgrid1.ReadOnly := false;
table1.insert;
table1.FieldByName('Talleres').assString := Edit1.Text
table1.post;
dbgrid1.ReadOnly := true;

Saludos.
__________________
Marc Guillot (Hi ha 10 tipus de persones, els que saben binari i els que no).
Responder Con Cita
  #6  
Antiguo 14-10-2003
NeWsP NeWsP is offline
Miembro
 
Registrado: oct 2003
Ubicación: Barcelona
Posts: 57
Poder: 21
NeWsP Va por buen camino
Ok, Gracias

Ahora probare , la funciona la tengo declarada tb en privare , pero no la variable.

Espero tener suerte.

por cierto si q tengo q poner el nombre del form donde esta pq es diferente el form donde se introducen los datos y donde esta la table

gracias por todo.
Responder Con Cita
  #7  
Antiguo 14-10-2003
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
Además de lo que ya te explicó marcguillot yo pensaría en la siguiente solución:

En Form3 declaras una propiedad pública de tipo TForm2:

Código:
type
  TForm3 = class
  public
    GridForm: TForm2;
  end;
En Form2, en el botón de "AÑADIR", muestras Form3 así:

Código:
  with TForm3.Create(nil) do
    GridForm := Self;
    ShowModal;
    Free;
  end;
y las referencias al formulario con el grid dentro de Form3 las haces con FormGrid, p. ej:

FormGrid.Table1.Insert;

// Saludos
Responder Con Cita
  #8  
Antiguo 14-10-2003
Avatar de guillotmarc
guillotmarc guillotmarc is offline
Miembro
 
Registrado: may 2003
Ubicación: Huelva
Posts: 2.638
Poder: 24
guillotmarc Va por buen camino
Hola.

La verdad es que siempre me ha parecido increible que los componentes de un formulario esten declarados en una sección pública que permite a otros formularios acceder a ellos.

En mi opinión un formulario nunca deberia poder acceder a los componentes de otros (quizá en algún caso muy concreto pueda ser adecuado, pero no se me ocurre ninguno).

Lo correcto, a mi modo de ver, es declarar una función Insertar en el formulario, y que los otros formularios accedan a esa función y no a los componentes.

Código:
type
  TForm2 = class(TForm)
  ...
  ...
  public
    procedure AnadirValor(Texto: String);
  ...
  ...

implementation
  
  procedure TForm2.AnadirValor(Texto: String);
  begin
    dbgrid1.ReadOnly := false;
    table1.insert;
    table1.FieldByName('Talleres').assString := Edit1.Text
    table1.post;
    dbgrid1.ReadOnly := true;
  end;
Ahora para ejecutar esa acción, podemos hacer desde otro Formulario :

Hijo.AnadirValor(Edit1.Text);

Aunque si vas a utilizar una variable Hijo, ten en cuenta que ocurrirá cuando tengas abiertas dos veces un formulario de ese tipo. La variable Hijo solo te apuntará a una de ellas. (¿ cual será ?, ¿ la ultima abierta ?, debes tenerlo controlado). La propuesta de Roman, es un buen ejemplo en el que se tiene controlado el formulario hijo, aunque puede haber varios de ellos.

Saludos.
__________________
Marc Guillot (Hi ha 10 tipus de persones, els que saben binari i els que no).

Última edición por guillotmarc fecha: 14-10-2003 a las 21:49:58.
Responder Con Cita
  #9  
Antiguo 14-10-2003
NeWsP NeWsP is offline
Miembro
 
Registrado: oct 2003
Ubicación: Barcelona
Posts: 57
Poder: 21
NeWsP Va por buen camino
Gracias otra vez a los dos.

Solo tengo un problemilla mas ( es de tontos ... ) pero no me entra... , al escribir esto :

type
TForm3 = class
public
GridForm: TForm2;
end

me dice q TForm2 no esta declarado, en cambio si q le digo q use el Unit2 pero se lo digo mas tarde...

aunque la forma de Guillotmarc tb la veo muy interesante, sera question de probarla
Responder Con Cita
  #10  
Antiguo 14-10-2003
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
En realidad lo que dice guillotmarc acerca de la "publicidad" de las componentes de un formulario es completamente cierto y sólo lleva a malas prácticas de programación que posteriormente dan dolores e cabeza.

Si un formulario tiene un Edit edtTalleres, la propiedad pública debiera ser el texto del control y no el control mismo.

En el caso concreto que nos ocupa entiendo lo siguiente:

Un formulario contiene una rejilla para visualizar los datos pero en lugar de editar éstos en la misma rejilla se desea abrir un formulario de captura, situación por demás normal ya que en muchas ocasiones la rejillasólo muestra unos cuantos de los campos a fin de que el usuario los pueda identificar.

Ahora bien, "normalmente", el forumulario de captura de datos contiene componente TDBEdit en lugar de simples TEdit (como en el presente caso) y dichos TDBEdit (u otros controles DB) están ligados a componentes DataSource localizados en un módulo de datos, como indica cadetill

Aunque de alguna manera también así accedemos a los controles de otro módulo (el datasource), en este caso, un módulo de datos, me parece apropiado y hasta necesario (¿de qué otra forma hacemos el enlace?)

Pero si por las razones que fueren, se insiste o se deben utilizar TEdits normales entonces lo más correcto, desde mi punto de vsta, sería, como mencioné arriba, publicar el texto de dichos controles:

Código:
type
  TForm3 = class(TForm)
  private
    function GetTalleres: String;
    procedure SetTalleres(Value: String);
  public
    property Talleres: String read GetTalleres write SetTalleres;
  end;

implementation
  function TForm3.GetTalleres: String;
  begin
    Result :=edtTalleres.Text;
  end;

  procedure TForm3.SetTalleres(Value: String);
  begin
    edtTalleres.Text := Value;
  end;
end.
De esta forma, cuando desde el formulario con la rejilla deseemos editar los datos de un registro pondríamos:

Código:
with TForm.Create(nil) do
begin
  Talleres := Table1.FieldByName('Talleres').AsString;
  { Otros campos }
  
  if ShowModal = ID_OK then
  begin
    Table1.FieldByName('Talleres').AsString := Talleres;
    { Otros campos }
    Table1.Post;
  end;

  Free;
end;
Así, el formulario con la rejilla usa del formulario de datos lo único que debe saber: sus datos; y no sus controles.

// Saludos
Responder Con Cita
  #11  
Antiguo 14-10-2003
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
Cita:
Posteado originalmente por NeWsP
[...]al escribir esto :

type
TForm3 = class
public
GridForm: TForm2;
end

me dice q TForm2 no esta declarado, en cambio si q le digo q use el Unit2 pero se lo digo mas tarde[...]
Deberás poner el unit2 en la parte de la "interface" mienras que en Unit2 deberás poner el unit3 en la parte de "implementation"

// Saludos
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro


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


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
Copyright 1996-2007 Club Delphi