Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   demasiados access violation (https://www.clubdelphi.com/foros/showthread.php?t=35346)

ingel 07-09-2006 18:39:11

demasiados access violation
 
HOla foro .. puede que tenga un dia con el biorritmo bajo pero los access violation me estan fastidiando sobremanera ..
Todo comenzo con un simple listado igual a TODOS los demas , uso una tabla temporal , alli grabo con un SP lo que necesito imprimir , la asigno a un
QReport y relaciono un QRDBText con los campos de dicha tabla.
bueno .. en ESTE caso ..antes de hacer el .Print debo hacer el Open de la tabla .. pues me da access violation ..y no hay caso ..
he probado 'mover' el codigo en diferentes partes pero nada ..
(hago el open de la tabla desde el entorno y abre sin problema .. los datos grabados en la tablas estan correctos)

Tal vez el problema venga por otro lado .. y este haciendo algo incorrectamente..
Estoy ejecutando una ventana principal que usa 'varios' forms ..
los creo TODOS juntos hago el Showmodal de ESA ventana principal
y al salir hago el FREE de todos juntos ..

por ej..

Código:

Application.CreateForm(TFPediSeg,FPediSeg);
Application.CreateForm(TFPedDetProd,FPedDetProd);
Application.CreateForm(TFCompItems,FCompItems);
...// son 7 u 8 forms

FPediSeg.Showmodal

CONTROL /* esto es un procedimiento de control que hace un open de una tabla general del sistema..*/

FPediSeg.free
FPedDetProd.free
FCompItems.free
...

La primera duda es el ORDEN en que debo hacer los FREE?

Digo esto porque ahora simplemente voy entrando a sucesivos forms (ya creados en el principal) mostrandolos con Showmodal y simplemete SALIENDO
en cadena .. cuando salgo del tercero .. o sea ..el primero llama a un segundo y este segundo a un tercero ... saliendo simplemente de este tercero .. en cualquier instruccion que ponga luego de l showmodal .. me da error de access violation ..hasta en un simple Showmessage .. y todavia no he hecho ningun free..

bueno ..espero haya sido lo suficientemente claro ...y alguin pueda guiarme un poco...

GRACIAS ...y saludos
Ingel

Caral 07-09-2006 18:57:42

Hola
No se si esta es la duda pero para llamar a un from yo uso:

procedure TFMainForm.BitBtn10Click(Sender: TObject);
begin
FUsuarios:=TFUsuarios.Create(self);
try
FUsuarios.ShowModal;
finally
FUsuarios.Free;
end;
end;

Esto en cada from osea el que llama a otro, asi cierro el from que no necesito y ahorro memoria.
Podria ser esto.:confused:
Espero te sirva de algo.
Saludos

reina 07-09-2006 18:59:50

Hola compañero! la verdad que no entendi mucho..jaja pero como soy terca contesto igual :)
Bueno un consejo para guardar prolijidad deberias crear las ventanas cuando realmente las uses..y liberarlas cuando no las uses..
Tambien podrias proteger bloque despues de la creacion con un try... finally.
Si haces un showmodal a un form que ya esta liberado..te va a dar error..es eso lo que te pasa??
Espero te sirva mi comentario.
Salu2

LA PATRIA SERA LIBRE!

ContraVeneno 07-09-2006 19:00:11

A mi me pareció intrigante que tuvieras que crear un SP para generar una tabla para luego asignarlo a un Qreport.

Para mi lo más fácil hubiera sido utilizar un TQuery y asignarlo al QReport

reina 07-09-2006 19:00:53

Uhh Me Ganaron De Mano! Ja..coincido Con El Comentario Anterior..

Caral 07-09-2006 19:07:01

Hola denuevo
Este es un simple codigo que llama a un reporte de compras por medio de un query.

If Reporte = 'ComprasXFecha' then
begin
ShortDateFormat := '#yyyy/mm/dd#';
try
QRComprasXCliente:=TQRComprasXCliente.Create(self);
QRComprasXCliente.ADOQuery1.SQL.Add(' WHERE CxPagar.TipoTransac="FA" ');
QRComprasXCliente.ADOQuery1.SQL.Add(' AND FechaTransac >= '+DateToStr(DTP1.Date)+' AND FechaTransac <= '+DateToStr(DTP2.Date));
QRComprasXCliente.ADOQuery1.SQL.Add(' ORDER BY CodProveedor, FechaTransac;');
QRComprasXCliente.ADOQuery1.Open;
ShortDateFormat := 'dd/mm/yyyy';
QRComprasXCliente.Titulo.text := 'Compras Realizadas por Fecha';
QRComprasXCliente.QRLblDesde.Caption := DateToStr(DTP1.Date);
QRComprasXCliente.QRLblHasta.Caption := DateToStr(DTP2.Date);
If RadioGroup1.ItemIndex = 0 then QRComprasXCliente.Print
else QRComprasXCliente.Preview;
finally
QRComprasXCliente.Free;
end;

Tal vez te sirva para completar tu enlace al qreport y no te de errores
Por lo menos a mi me sirve.:) :D
Saludos

ContraVeneno 07-09-2006 19:26:17

solo como comentario apart; en la línea:
Código Delphi [-]
QRComprasXCliente.ADOQuery1.SQL.Add(' AND FechaTransac >= '+DateToStr(DTP1.Date)+' AND FechaTransac <= '+DateToStr(DTP2.Date));


creoq ue sería mejor:
Código Delphi [-]
QRComprasXCliente.ADOQuery1.SQL.Add(' AND FechaTransac between '+DateToStr(DTP1.Date)+' AND '+DateToStr(DTP2.Date)+'''');


de esta forma no tienes que validar si una fecha es mayor a la otra o no

Caral 07-09-2006 19:31:18

Gracias Contra veneno:eek:
Tu comentario lo tamare en cuenta, esto tambien servira para que el que hizo la pregunta mejore su codigo al igual que yo, para esto esta el foro, Aprender.:D :D
Saludos

ingel 07-09-2006 23:19:29

gracias a todos por responder ...
 
sobre lo de usar una Query en lugar de la tabla podria ser , lo que pasa es que ya herede el codigo asi .. y todo el sistema graba en esa tabla temporal antes de imprimir (cada estacion de trabajo) y luego los reportes toman los registros segun la estacion de trabajo que manda el reporte ..hace el open e imprime.
Pero estimo ,sin probarlo :p , que daria el mismo error en el open de la query ..
porque creo que los problemas no son del componente ..aunque en realidad no se cual es el problema ;)
No comprendo porque puede dar aveces access violation el open de una tabla cuando esa tabla esta en un form que fue creado y no liberado de memoria aun....
Lo de abrir y liberar todos los forms juntos lo hago justamente (luego de deliberar bon otros programadores, se supone mas experimentados que yo)
para evitar que estando en un form que usa varios otros form 'permanentemente' este creando y liberando cosas de la memoria..
me explico ? .. imaginense un form principal y 20 botones que cada uno abre un form diferente ..y se esta trabajando 'siempre' sobre el form principal presionando los 20 botones ...
pero .... quizas no sea lo optimo... no? y si lo sea abrir y liberar CADA vez que se usa cada form ...:(

bueno gracias por los consejos ..
como dice Les Luthiers (argentinos comprenderan) ..
" ya no se si soy de mi o si soy de ti "... :D
sigo en mi lucha contra las violaciones ..
Saludos
gracias

ContraVeneno 07-09-2006 23:38:13

pues utilizando un query como mínimo te ahorras todo el SP para grabar los datos en la tabla temporal. ¿no es eso motivo suficiente?

Ahora, si multiplicas eso por el número máximo de usuarios activos, pues te incrementaría el tiempo y la carga en el servidor.

Pero en fin, fue solo mi simple comentario. :D

Caral 08-09-2006 00:07:54

Hola
En realidad Contra veneno tiene razon y de peso, tal vez en medio de la desesperacion no se ven las cosas bien, hay que tomarse un cafe, ver el ordenador de reojo, pensar, pensar con calma y veras que te dicen las cosas por algo.
Si heredas un codigo y este es habierto es tuyo puedes cambiar todo lo que quieras, El table= datos fijos, el query= lo que quieras, de eso se trata, de simplificar las cosas no de complicarlas, haz caso a Contra Veneno y otros de por aqui que te servira de mucho.
Saludos

Saludos

ingel 08-09-2006 00:24:06

probare con la Query ..
 
y mañana les comento.
(...y de paso les comento el porque de la tabla .. (o al menos eso interpreto yo) .. los datos estan en un StringGrid (se generan a partir de varios procesos) .. para imprimir eso , se vuelca el stringgrid a la tabla temporal de impresion y luego se hace el reporte enlazandolo con la tabla , hacer una query para representar ese stringgrid seria estimo bastante tedioso al menos )

Muchas gracias a todos.

ingel 08-09-2006 15:28:22

buendia ..
 
siguiendo con mi tema de las violaciones .. (siguen apareciendo) la pregunta
concreta seria : Hay algun ORDEN para liberar los forms que se crean ?

porque por ej. creo 3 forms juntos (en realidad son 6)
entro al primero , llamo al segundo , llamo al tercero .. cuando salgo del tercero , debajo del showmodal , le puse un showmessage .. AHI me da error de violacion ... PERO si creo un CUARTO form donde se crean todos los forms PASA SIN dar error ..:confused:

Ahora tambien cuando logro pasar sin error y simplemente quiero regresar al menu principal (saliendo del primer form) debajo de la llamada al primer form me comienza a dar error de violacion en los .FREE de cada form (si anulo el primero , me da en el segundo y asi sucesivamente) ...
Help !!
gracias ...

marceloalegre 08-09-2006 15:49:54

En cuanto a lo que comentas no veo errores concretos, pero deberias preguntarte, por lo menos para este caso, cual es el "gran beneficio" de crear dinamicamente estos formularos, son muy pocos... podrias dejarlos auto create...
Igualmente para no dejar la pregunta sin respuesta, te cuento otra forma para estas cuestiones:

Código Delphi [-]
//para la creacion:
FPediSeg:=TFPediSeg.create(nil);
 
//liberar
FreeandNil(FPediSeg);

Cuenta como te fue con esto... Saludos!

ingel 08-09-2006 16:17:09

Kanvictor .. te cuento ..
 
asi quedo mi codigo ..
[codigo]
0501: begin // pedidos

{Application.CreateForm(TFEntregas,FEntregas);
Application.CreateForm(TFPedPresu,FPedPresu);
Application.CreateForm(TFBusPed,FBusPed);
Application.CreateForm(TFCargaRapida,FCargaRapida);
Application.CreateForm(TFPediSeg,FPediSeg);
Application.CreateForm(TFPedDetProd,FPedDetProd);
Application.CreateForm(TFCompItems,FCompItems);
Application.CreateForm(tform1,form1);
Application.CreateForm(TFPedidos,FPedidos);}


FPedidos := TFPedidos.create(nil);
FEntregas := TFEntregas.create(nil);
FPedPresu := TFPedPresu.create(nil);
FBusPed := TFBusPed.create(nil);
FCargaRapida:= TFCargaRapida.create(nil);
FPediSeg := TFPediSeg.create(nil);
FPedDetProd := TFPedDetProd.create(nil);
FCompItems := TFCompItems.create(nil);


with FPedidos do begin
ShowModal;
end;

// if fDatos.TDatos.FieldByName('ALERTA_PRODUCTOS').asboolean then CargoAlertasProd;


FreeandNil(FPedidos);
FreeandNil(FEntregas);
FreeandNil(FPedPresu);
FreeandNil(FBusPed);
FreeandNil(FCargaRapida);
FreeandNil(FPediSeg);
FreeandNil(FPedDetProd);
FreeandNil(FCompItems);

{ FCompItems.free;
FPedDetProd.Free;
FPediSeg.Free;
FCargaRapida.Free;
FBusPed.Free;
FPedPresu.Free;
FEntregas.Free;}

end;

[/codigo]

Lo que hago es entrar a Pedidos , luego a PedPresu y luego a CompImtems y comezar a salir de cada uno .. cuando llego a FreeandNil(FPedidos); da error
si lo comento ..el error lo da el siguiente ...FreeandNil(FEntregas);
Revise y en esos form no tengo FREE de ninguno de estos forms ...
la verdad estoy .. :( :(
gracias por tu Rta..

(voy a tratar de crear cada form en el momento que lo uso ..) porque la verdad ni idea por donde viene el problema..

ingel 08-09-2006 17:13:39

ya descubri el problema ...
 
bueno ... en definitiva lo que me ocasionaba estos access violation era
el componente XStringGrid (puesto en el TERCER form que llamaba) ,porque
al quitarlo (luego de probar llamar un form VACIO y que NO diera el error)
dejo de dar el error y el programa funciono como siempre....
ahora .. esto me causa algun problemita porque me venia MUY bien todas las
propiedades del Xstringgrid y ya habia programado todo en base a este componente.. peeero ... supongo que no sera facil encontrarle un porque y menos aun una solucion ... :(
bueno GRACIAS A TODOS
Saludos

ContraVeneno 08-09-2006 17:17:11

en tu post donde esta tu código... edítalo y donde donde dice [Codigo] cámbialo por ['delphi] y [ '/ delphi]

y se verá mucho mejor ;)

AzidRain 20-09-2006 03:53:25

Solo por añadir...

usar freeandnil no tiene caso si el puntero del objeto ya no se va utilizar. Por otro lado siempre será recomendable ir creando las forms de forma dinámica pues con ello optimizamos más memoria que si las dejamos en autocreate. Claro que si se trata de una o dos sencillas no habrá mucha diferencia. Una buena práctica es usar la estructura: try...finally que por ahi ya comentaron, además de eso, el constructor de las form acepta por default un owner que en el caso de una ventana normal debe ser siempre nil.. en www.about.com en la seccion de delphi hay varios artículos muy bien explicados al respecto.

Por otro lado lo de las violations a mie me sucedia antes mucho y aprendí que en un 90% de los casos se trata de algun acceso a un objeto que no esta inicializado, como por ejemplo querer darle Form1.ShowModal sin antes crear la forma, o acceder a alguno de sus métodos. Muchas veces cosas tan obvias se olvidan. De hecho tengo como regla general revisar todas las asignaciones a objetos cuando me sale ese error,.


La franja horaria es GMT +2. Ahora son las 16:39:18.

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