![]() |
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 |
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 |
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 |
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 :) |
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. |
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. |
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 Código:
with TForm3.Create(nil) do FormGrid.Table1.Insert; // Saludos |
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 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. |
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 :) |
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 Código:
with TForm.Create(nil) do // Saludos |
Cita:
// Saludos |
La franja horaria es GMT +2. Ahora son las 12:37:07. |
Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi