Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   OOP (https://www.clubdelphi.com/foros/forumdisplay.php?f=5)
-   -   Error AccessViolation que no consigo localizar (https://www.clubdelphi.com/foros/showthread.php?t=58379)

radge 18-07-2008 11:52:02

Error AccessViolation que no consigo localizar
 
Tengo un formulario con los siguientes componentes :
-Tquery
-dataset
-dbgrid

Lo que hago es hacer una sql con la query y mostrar la en el GRID , una vez alli muestro los campos y tengo un checkbox dependiendo si lo chekeas o no hace una sql o otra.

Un formulario realmente sencillo

La cuestión es que en el gris empiezo a “toketearlo” y cada cierto número de veces que apreto en el grid , pueden ser 10..30..40 o 2… depende…. Me sale la siguiente excepción

Project Proyecto1.exe raised exception class EAccessVioaltion with message
‘Access violation at address 004032AE in module Proyecto1.exe.
Read of address FFFFFFDC’. Process stopped….


Alguna vez rara vez he visto esta otra

Exception EAccessViolation in module Comerciales.exe at 00000000.
Access violation at address 00000000. Read of Address 00000000






Os pondria el código pero sin la sql y tal no serviria de nada ;(


he debugado y debugado pero no le veo el fallo....


salu2 radge

Neftali [Germán.Estévez] 18-07-2008 12:26:57

Compila el código añadiendo opciones de Debug.
Una vez que estés ejecutando, prueba a ir a las opciones de Search/Find Error e introduce el primer número hexadecimal (address) a ver si por ahí aclaras algo.


radge 18-07-2008 12:36:15

Adjunto imagen de las opciones que tengo al compilar

http://img258.imageshack.us/my.php?i...nttulo1ue9.jpg



Con la dirección que me da la pongo dodne me has dicho y lo que me sale no se descifrarlo


gracias , radge

coso 18-07-2008 12:42:48

Hola, debes tener la informacion de debug activada (project->options->compiler->debug options) para que te indique encima de tu codigo en que linea te salta la excepción. Es mas, si pones en 'tools->debugger options->Halt on delphi exceptions', y pulsas Ctrl+F3 una vez te ha saltado la excepcion (dentro del IDE), sabras cuales han sido las funciones llamadas antes de la excepcion.

radge 18-07-2008 16:05:37

Cita:

Empezado por coso (Mensaje 301298)
Hola, debes tener la informacion de debug activada (project->options->compiler->debug options) para que te indique encima de tu codigo en que linea te salta la excepción. Es mas, si pones en 'tools->debugger options->Halt on delphi exceptions', y pulsas Ctrl+F3 una vez te ha saltado la excepcion (dentro del IDE), sabras cuales han sido las funciones llamadas antes de la excepcion.

Gracias pongo la dirección en Hex. en find/search error del delphi y siempre me sale la misma dirección 004825E7

Resulta que es código suyo propio , como arreglo esto ¿?





gracias , radge

Neftali [Germán.Estévez] 18-07-2008 16:37:14

¿Tienes la pila de llamadas de ese error?

View/Debug Windows/Call Stack

¿Puedes ponerla?

radge 18-07-2008 16:40:48

Si claro aki esta a ver k os parece.




gracias , radge

radge 18-07-2008 17:47:50

Os pongo un eskema de lo k hace mi evento FieldChanged del wwdbgrid que como vereis es muy simple


procedure formulario1.wwDBGrid1FieldChanged(Sender: TObject; Field: TField);

begin
if (condicion1) then begin
SQL1 (INSERT INTO)
SQL2 (UPDATE)
end
else begin
Creo un formulario para rellenar unos datos
y los recibo en el formulario actual

Una vez recibido los datos lo destruyo.
SQL3 (INSERT INTO)
SQL4 (UPDATE)
end;
end


gracias , radge

coso 18-07-2008 19:09:34

si el fallo seguro que no esta en esquema, sino en algun detalle. Antes del codigo en el onchange, yo pondria
Código Delphi [-]
 if not (sender as TDBEdit).Focused then exit;

radge 21-07-2008 08:11:21

Cita:

Empezado por coso (Mensaje 301432)
si el fallo seguro que no esta en esquema, sino en algun detalle. Antes del codigo en el onchange, yo pondria Código Delphi [-] if not (sender as TDBEdit).Focused then exit;


Te refieres en el onfieldchanged ? Y eso que hace exactamente ? Porque yo no tengo ningun TDBEdit.

Te referias al onchange del formulario o del dbgrid ?

gracias , radge

coso 21-07-2008 10:15:52

vaya, hubiese dicho que era dbedit. De igual manera, si, en el on fieldchange

PD : Read of address FFFFFFDC : Esto son ya las ultimas direcciones de memoria... creo que hay algo que no liberas correctamente y te va comiendo memoria.
PDD : lo que hace es que evita calculos si no esta el formulario correctamente inicializado, etc...vamos, si no tiene el foco. Para evitar actualizaciones indeseadas o incontroladas mas bien.

radge 21-07-2008 10:22:16

if not (sender as wwDBGrid1).focused then exit;

Me dice

[Error] SupVision.pas(203): Operator not applicable to this operand type



En cuanto lo de la memoria ya lo pensé yo pero lo unico que creo es un formulario que luego destruyo antes de volver a utilizarlo

salu2 radge

radge 21-07-2008 10:45:26

Casi todo el rato me apunta aquí




Es como si intentara liberar buffer o algo similar y da error ? Van x aki los tiros ?

salu2 radge

coso 21-07-2008 11:09:50

if not (sender as TDBGrid).Focused ... esto interpreta a 'sender' como de la clase DBGrid (si no lo fuera, por ejemplo si sender fuese un edit, te saltaria excepcion).

Pues en el momento que te salga la excepcion (en delphi, no en el programa) aprietas Ctrl+F3, te sale el stack. La primera linea es la ultima funcion llamada, y las siguientes las anteriores. El debugger te apunta a el codigo nativo pues es alli donde salta, aunque seguramente se haya provocado en una de las tuyas :entonces miras mediante esta lista cual de tus funciones ha sido la ultima en llamarse que ha provocado el error, y en que linea. Venga, suerte a ver si lo encuentras.

radge 21-07-2008 11:19:32

Cita:

Empezado por coso (Mensaje 301821)
if not (sender as TDBGrid).Focused ... esto interpreta a 'sender' como de la clase DBGrid (si no lo fuera, por ejemplo si sender fuese un edit, te saltaria excepcion).

Pues en el momento que te salga la excepcion (en delphi, no en el programa) aprietas Ctrl+F3, te sale el stack. La primera linea es la ultima funcion llamada, y las siguientes las anteriores. El debugger te apunta a el codigo nativo pues es alli donde salta, aunque seguramente se haya provocado en una de las tuyas :entonces miras mediante esta lista cual de tus funciones ha sido la ultima en llamarse que ha provocado el error, y en que linea. Venga, suerte a ver si lo encuentras.

Gracias , pero el problema que el onfield changes apenas tiene 50 0 60 lineas he puesto varios try catch para ver donde me salta la excepción pero no hay forma de que salte en el delphi , pero si en el programa.

Entonces por eso no se donde pillar lo , porque no se lo que o donde lo esta provocando.

salu2 radge

coso 21-07-2008 11:26:41

a eso voy... cuando te salga la excepcion, aprietas Ctrl+F3 y te sale la lista de las llamadas a funciones. Olvidandote del codigo nativo, que esta correcto, tu vas a tu funcion y veras en que linea se te ha provocado y entonces puedes deducir porque. Saludos.

Cita:

pero no hay forma de que salte en el delphi
tools->debugger options->exception->stop on delphi exceptions

esto anterior te hara saltar la excepcion en delphi aunque la tengas en un try

Cita:

apenas tiene 50 0 60 lineas
y ya son demasiadas. divide y venceras.

radge 22-07-2008 08:29:24

else if (FilaCheck = 'N') then
if (var1= var2) then begin
botoseleccionat := MessageDlg('Estas seguro que quieres borrar las unidades servidas ?',mtCustom,
[mbYes,mbNo], 0);
if botoseleccionat = mrYes then begin
cadenaSQL := 'update sql';
ModuloDatos.Ejecutar_SQL(cadenaSQL);
cadenaSQL := 'update SQL';
ModuloDatos.Ejecutar_SQL(cadenaSQL);
try
query_supvision.Close;
query_supvision.Open;
except
showmessage('Error abriendo la base de datos');
end
end
end


He debugado y debugado y uno de las veces al mirar el "call stack" me marca en esta posición , pero yo no le veo nada a esta linea de codigo.

gracias radge

coso 22-07-2008 09:27:34

debugar es fastidioso :mad:, y hacerlo online, un poco mas :confused:. Otro truquito que se hace es ir comentando lineas, probando, comentando lineas, ... hasta que no te salte. Es raro, porque esa linea de codigo no tiene nada ciertamente...a no ser que, como deciamos, ya no tengas memoria ni para llenar un TModalResult...No se si cargas un exceso de datos por algun otro lado que no liberas, alguna form que creas varias veces en tiempo de ejecucion, querys que se crean y llaman multitud de veces (ejecutar_SQL) sin luego liberarlas,bitmaps,...ni idea, deberia repasar todo el codigo. Si tienes alguna otra duda, por eso, no dudes en ponerla aqui. Venga, saludos, i sort!;)

PD : prueba de ponerlo en otro evento que no sea el OnFieldChanged, pues ahora que pienso, si modificas la misma base de datos que se mira en el DBGrid, es probable que la llames recursivamente una y otra vez. Saludos.

coso 22-07-2008 09:35:33

Si puedes, pon el codigo entero de
procedure formulario1.wwDBGrid1FieldChanged(Sender: TObject; Field: TField)

Cita:

Exception EAccessViolation in module Comerciales.exe at 00000000.
Access violation at address 00000000. Read of Address 00000000
este es otro completamente independiente, seguro

radge 22-07-2008 15:25:56

Código PHP:


procedure TfrmSupVision
.wwDBGrid1FieldChanged(SenderTObject;
  
FieldTField);
Var
   
cadenaSQL,FilaCheck,Lin_Codi,Alb_Codi,Per_Codi,accountnum,dataareaid ,
   
varDades varUnitatsRestants string;
   
Cantidad UnitatsServidesBD botoseleccionat  Integer ;
   
Marca TBookMarkStr;

begin
         Lin_Codi 
:= query_supvision.FieldbyName('LIN_Codi').AsString;
         
Alb_Codi := query_supvision.FieldbyName('ALB_Codi').AsString;
         
Per_Codi := query_supvision.FieldbyName('Per_Codi').AsString;
         
Accountnum := query_supvision.FieldbyName('accountnum').AsString;
         
Dataareaid := query_supvision.FieldbyName('dataareaid').AsString;
         
Cantidad := query_supvision.FieldbyName('Cantidad').asinteger;
         
UnitatsServidesBD := query_supvision.FieldbyName('Unitats_Servides').asinteger;


        if ((
Lin_Codi <> '') and (Dataareaid <> '') and (Alb_Codi <> '') and (Per_Codi <> '') and (Accountnum <> '') AND (inttostr(Cantidad) <> '') ) then begin
           
if (combobox1.text 'TODOS'then
               FreeAndNil
(Marca);
               
Marca := query_supvision.Bookmark;

        
FilaCheck := wwDBGrid1.GetFieldValue(7); 

        if (
FilaCheck 'S'then  begin
             
if (Cantidad 1then begin
                 cadenaSQL 
:= 'SQL XXXXXXXXXXX';
              
ModuloDatos.Ejecutar_SQL(cadenaSQL);
              
cadenaSQL := 'SQL XXXXXXXXX';
              
ModuloDatos.Ejecutar_SQL(cadenaSQL);
               try
                  
query_supvision.Close;
                  
query_supvision.Open;
               
except
                  showmessage
('Error al abrir/cerrar BD vuelve a intentar lo');
               
end;
             
end

             
else begin // Si hi ha més d'una unitat d'aquella linea de pedido ==> FORM NOU
                 
try
                   
Application.CreateForm (TfrmUnidadesPedidoVentafrmUnidadesPedidoVenta);
                 
except
                 
;
                 
end;
                   
frmUnidadesPedidoVenta.CarregaDades(Cantidad,UnitatsServidesBD);
                   if (
Cantidad 0) and (UnitatsServidesBD >=)then begin
                   frmUnidadesPedidoVenta
.ShowModal;
                   
varDades := frmUnidadesPedidoVenta.rebreDades;
                   
varUnitatsRestants := frmUnidadesPedidoVenta.rebreUnitatsRestants;
                      
cadenaSQL := 'SQL XXXXXXXXXXXXXXXXXX';
                      
ModuloDatos.Ejecutar_SQL(cadenaSQL);
                      
cadenaSQL := 'SQL XXXXXXXXXXXXXXXXXX';
                      
ModuloDatos.Ejecutar_SQL(cadenaSQL);
                      
query_supvision.Close;
                      
query_supvision.Open;
                  
end
                  
else begin
                     showmessage
('Error al recibir los datos');
                  
end;
              
end;
        
end
        
else if (FilaCheck 'N'then
             
if (Cantidad UnitatsServidesBDthen begin
                   botoseleccionat 
:= MessageDlg('Estas seguro que quieres borrar las unidades servidas ?',mtCustom,[mbYes,mbNo], 0);
                 if 
botoseleccionat mrYes then begin
                      cadenaSQL 
:= 'SQL XXXXXXXXXXXXXXXXXX';
                     
ModuloDatos.Ejecutar_SQL(cadenaSQL);
                      
cadenaSQL := 'SQL XXXXXXXXXXXXXXXXXX';
                     
ModuloDatos.Ejecutar_SQL(cadenaSQL);
                     try
                        
query_supvision.Close;
                        
query_supvision.Open;
                     
except
                        showmessage
('Error abriendo la base de datos');
                     
end
                end
                
else begin
                     query_supvision
.Cancel;  // refrescar
                
end;
                
end;
    
end
    
else begin
       showmessage
('Este cliente no tiene más albaranes por editar');
    
end;
      if (
combobox1.text 'TODOS'then
      query_supvision
.Bookmark := Marca;
  
end


coso 22-07-2008 15:44:08

puedes usar delphi y /delphi entre [], si es codigo delphi. Creas la form, pero en ningun momento la liberas. Yo lo haria asi:

Código Delphi [-]
var  
      f : TfrmUnidadesPedidoVenta;
begin
    ...
     try
           f := TfrmUnidadesPedidoVenta.Create(self); // corregido
           f.ShowModal;
           ...
           f.free;
     except
        ...

casi seguro que es eso

otra es marca, porque freeandnil si aun no se ha asignado (ni falta que hace)? TBookMarkStr solo es una string, por lo que en principio no te tienes que preocupar de su memoria. El access a nil es debido a eso seguro, pues la liberas y luego intentas trabajar con ella. Si quieres que tenga un valor nulo, simplemente haz marca := '' o marca := nil, pero no la liberes pues se queda desreferenciada en memoria. En tu caso, creo q no hace falta ni siquiera marca := '' pues a lo siguiente ya le das un valor concreto.

Tambien creo q te falta un bloque begin end en ComboBox1.Text = 'TODOS'



radge 23-07-2008 08:12:12

He cambiado lo que mas dicho del bloque begin y lo de la variable.

Pero lo del formulario lo he dejado asi

Código Delphi [-]
Application.CreateForm (TfrmUnidadesPedidoVenta, frmUnidadesPedidoVenta);
                frmUnidadesPedidoVenta.CarregaDades(Cantidad,UnitatsServidesBD);
frmUnidadesPedidoVenta.ShowModal;
varDades := frmUnidadesPedidoVenta.rebreDades;
varUnitatsRestants := frmUnidadesPedidoVenta.rebreUnitatsRestants;
frmUnidadesPedidoVenta.Free;


Pero sigue dandome error os dejo la pila. gracias radge


Como veis todas las instrucciones son de código nativa menos la 1º empezando por abajo del stack , que es la marcada en rojo.



Neftali [Germán.Estévez] 23-07-2008 10:48:10

Hay entre las llamadas del callstack algunas especiales:


Creo que eso te puede dar datos sobre el campo del error.
¿Hay algun campo en el Grid en el que esté apareciendo "N"? ¿Tal vez un booleano?
Deberías revisar si en algun momento ese campo puede no estar asignado.

Neftali [Germán.Estévez] 23-07-2008 11:01:52

Hay entre las llamadas del callstack algunas especiales:


Creo que eso te puede dar datos sobre el campo del error.
¿Hay algun campo en el Grid en el que esté apareciendo "N"? ¿Tal vez un booleano?
Deberías revisar si en algun momento ese campo puede no estar asignado.

coso 23-07-2008 12:09:48

Hola otra vez, probablemente ya tengas una instancia de TfrmUnidadesPedidoVenta con el nombre frmUnidadesPedidoVenta que se te crea de manera automatica (project->options->Forms->autocreateForms). Si es asi, al volver a usar ese nombre estas dejando toda la form anterior en memoria desreferenciada. Has probado si con el codigo anterior, tal cual esta, te salta el error? luego, al quedarse sin memoria, te puede saltar en cuqlquier momento. Tambien, query_supvision etc esta todo correcto no? en cuanto a creacion y liberacion.

coso 23-07-2008 12:13:50

Otra cosa: carregadades tambien esta todo correcto? si vas comentando bloques (por ejemplo, que no te cree el form o la parte de las consultas) te salta el error? es un metodo para localizarlo

radge 23-07-2008 12:18:27

Ok pruebo esto , de todas formas lo del formulario lo tengo en un try , me deberia saltar y no lo he visto saltar ninguna vez.


Código Delphi [-]
                   try
                   Application.CreateForm (TfrmUnidadesPedidoVenta, frmUnidadesPedidoVenta);
                   frmUnidadesPedidoVenta.CarregaDades(Cantidad,UnitatsServidesBD);
                   frmUnidadesPedidoVenta.ShowModal;
                   varDades := frmUnidadesPedidoVenta.rebreDades;
                   varUnitatsRestants := frmUnidadesPedidoVenta.rebreUnitatsRestants;
                   frmUnidadesPedidoVenta.Free;
                   except
                       on e : exception do begin
                          ShowMessage ('Clase de error: ' + e.ClassName + chr(13) + chr(13) + 'Mensaje del error: ' + e.Message);
                       end;
                   end;

coso 23-07-2008 12:25:39

Bueno, segun la direccion de memoria que te pone (FFFFFFDC), ya casi al final de todo puede que consiga la memoria suficiente para la form, pero luego ya no pueda hacer nada mas, por lo que no tendria que saltar alli ($FFFFFFFF - $FFFFFFDC = $23 = 35 bytes) Por eso que te salte a las 30 o 40 veces. Yo creo que es eso, quiza me equivoque claro esta :p. Saludos

radge 23-07-2008 12:57:06

Mira te muestro la stack , yo siempre busco la 1º función mia no nativa empezando por arriba no ???

De ser asi toi mirando esto.




coso 23-07-2008 13:06:30

si te fijas, el stack son las funciones que se han ido llamando, que se guardan en esta lista. Asi, si quieres mirar donde ha saltado el error, pues va bien para conocer en que funcion. Ahora bien, segun tu dices te pasa a la 30 o 40 vez que pulsas el click, por lo que no es un error digamos inicial, sino uno que se va arrastrando. Asi pues, el stack aunque te diga donde ha saltado, el inicio del error puede estar en cualquier parte. Como ya te he dicho, yo creo que es porque creas algo repetidas veces sin liberarlo: has probado el codigo anterior, tal cual? f variable local, creandola con el create no con el application.createform, y su free? si aun asi te da error, prueba de comentar el bloque de creacion de esa form, a ver si asi te salta. si es el caso, entonces el error debe estar en alguna de las funciones interiores, carregadades, etc...donde quiza estes cargando datos en un objeto que creas repetidas veces pero no liberas cada vez.

coso 23-07-2008 13:15:02

ten en cuenta tambien la vision de Neftali: yo estoy fijo en lo de los 30 intentos, pero segun el stack que el te muestra, el error te saltaria por algo completamente diferente.

radge 23-07-2008 14:55:36

Cita:

Empezado por coso (Mensaje 302593)
si te fijas, el stack son las funciones que se han ido llamando, que se guardan en esta lista. Asi, si quieres mirar donde ha saltado el error, pues va bien para conocer en que funcion. Ahora bien, segun tu dices te pasa a la 30 o 40 vez que pulsas el click, por lo que no es un error digamos inicial, sino uno que se va arrastrando. Asi pues, el stack aunque te diga donde ha saltado, el inicio del error puede estar en cualquier parte. Como ya te he dicho, yo creo que es porque creas algo repetidas veces sin liberarlo: has probado el codigo anterior, tal cual? f variable local, creandola con el create no con el application.createform, y su free? si aun asi te da error, prueba de comentar el bloque de creacion de esa form, a ver si asi te salta. si es el caso, entonces el error debe estar en alguna de las funciones interiores, carregadades, etc...donde quiza estes cargando datos en un objeto que creas repetidas veces pero no liberas cada vez.

Sisi probé a comentar el trozo de código que creo el form y me salta una excepción igualmente.

Y tambien probé a poner :

f := TfrmUnidadesPedidoVenta(create);

En esa linia me pone [Error] SupVision.pas(203): Not enough actual parameters

coso 23-07-2008 15:12:33

si bueno,... la sintaxis que es correcta seria -> f := TfrmUnidadesPedidoVenta.Create(nil) o (self), el argumento es el parent form, me debi liar al escribirlo. Igualmente, si al comentarlo (donde lo creas y donde la usas, claro, si es solo donde la creas tendras una excepcion mas) te sigue saltando, es que el error no esta por alla.

radge 23-07-2008 15:16:42

Cita:

Empezado por coso (Mensaje 302640)
si bueno,... la sintaxis que es correcta seria -> f := TfrmUnidadesPedidoVenta.Create(nil) o (self), me debi liar al escribirlo. Igualmente, si al comentarlo (donde lo creas y donde la usas, claro, si es solo donde la creas tendras una excepcion mas) te sigue saltando, es que el error no esta por alla.

Exacto creo que el error esta en otra parte , porque lo he comentado las 5 o 6 lineas donde lo creo , recibo los datos y lo destruyo y sigue saltando la excepción.

salu2 radge

coso 23-07-2008 15:19:53

X) pues tienes faena. saludos.

radge 23-07-2008 15:28:12

No si llevo más de 2 semanas con esto... pero es que no lo veo la verdad... me he trabado con ello.

gracias , radge

coso 23-07-2008 15:44:06

mira en el codigo inicial que pusiste, he encontrado errores de los que yo considero graves (la liberacion del string que luego usas, crear una form con un nombre de variable global, probablemente ya creada,...), por lo que, sin animo de despreciar, creo que pueden haber bastantes del mismo tipo por diferentes lugares del proyecto. Le pegaria una repasada general a todo entero teniendo en cuenta :
- no crear forms inecesarias : si solo se usan una vez, usar el autocreate (project->options). Si se han de usar varias a la vez de la misma clase (como por ejemplo seria un preview), entonces si usar el create de las forms.
- si se crean, en tiempo de ejecucion, tanto forms como otros objetos, destruirlos en la misma funcion desde donde se han llamado. Vamos, las ultimas lineas de la funcion tendrian que ser del tipo q.Free, f.Free,...(en teoria, si dentro de estas forms no creas nada en tiempo de ejecucion, no hace falta usar el free, pero no esta de mas)
- si se cargan datos, tener en cuenta que se liberen una vez usados. Si se sale de la funcion donde se ha creado y cargado, entonces usar una variable global del form directamente y en su create darles la memoria (a todos los que vayas a usar) y en el create del objeto, hacer create(self) , o sea vinculado a la form, y en el evento destroy liberar estos objetos (solo en el destroy). Asi mientras este creada la form tendras esos objetos a mano siempre.
- Lo que decia neftali, vigilar que los campos de tus query esten creados y correctamente escritos y llamados, y que se asignen valores de acuerdo a sus tipos.
- Y lo que te comente al principio: usar los breakpoints (F5) los watches (Ctrl+F5), F7,F8 , el call stack, y lo de comentar/descomentar.


Venga, haber si lo resuelves. Saludos

coso 23-07-2008 15:56:15

Otra manera es usando un administrador de memoria y ir haciendo f7s,f8s...en los momentos en los que se te carguen bloques de memoria exagerados y alla se queden, por alla tendrias el problema (siempre suponiendo q el error sea por agotamiento de memoria, claro)

radge 23-07-2008 16:29:08

Como variable global creo esta "CodiClient" que es una variable que arrastro de un combobox a distintos sitios dentro del mismo formulario.

Lo del auto-create forms solo tengo uno llamado "splash" lo que salta al inicio del programa , solo tengo ese.


El trozo este de codigo

Código Delphi [-] Application.CreateForm (TfrmUnidadesPedidoVenta, frmUnidadesPedidoVenta); frmUnidadesPedidoVenta.CarregaDades(Cantidad,UnitatsServidesBD); frmUnidadesPedidoVenta.ShowModal; varDades := frmUnidadesPedidoVenta.rebreDades; varUnitatsRestants := frmUnidadesPedidoVenta.rebreUnitatsRestants; frmUnidadesPedidoVenta.Free;



Código Delphi [-]
var
  frmUnidadesPedidoVenta: TfrmUnidadesPedidoVenta;
  unidades_restantes : integer ;
  FlagCheckSupervisado : string;
implementation

uses SupVision;

{$R *.DFM}

procedure TfrmUnidadesPedidoVenta.CarregaDades(var1,var2: integer);
begin
 UnitatsPedidoVenta := var1;
 UnitatsServidesBD := var2;
end;

function TfrmUnidadesPedidoVenta.rebreDades():String;
begin
  Result := edit1.Text;
end;

function TfrmUnidadesPedidoVenta.rebreUnitatsRestants(): string;
begin
   if (unidades_restantes = strtoint(edit1.text)) then
       FlagCheckSupervisado := 'S'
   else
       FlagCheckSupervisado := 'N';
   Result := FlagCheckSupervisado;
end;

procedure TfrmUnidadesPedidoVenta.ACTUALIZARClick(Sender: TObject);
begin

 if ( strtoint(edit1.text) = 0) then
        showmessage('No es posible añadir 0 unidades ')
 else if ( strtoint(edit1.text) > unidades_restantes) then
        showmessage('El número máximo permitido es ' + inttostr(unidades_restantes) + ' unidades ')
 else
         frmUnidadesPedidoVenta.Close;
end;

procedure TfrmUnidadesPedidoVenta.FormShow(Sender: TObject);
begin
  label3.Caption := inttostr(UnitatsPedidoVenta);
  label4.Caption := inttostr(UnitatsServidesBD);
  unidades_restantes := UnitatsPedidoVenta - UnitatsServidesBD;
  Label5.Caption := inttostr(unidades_restantes);
end;




procedure TfrmUnidadesPedidoVenta.edit1KeyPress(Sender: TObject;
  var Key: Char);
begin
  If Key = #13 then
  ACTUALIZAR.Click;
end;


end.

coso 23-07-2008 16:33:51

pues quiza lo mas correcto sea q tengas en autocreate forms todas las forms que vas a usar en el proyecto. O es que las estas creando cada vez que las vas a llamar? si ese es el caso, una vez usadas y cerradas las forms, las destruyes?? porque ten en cuenta que si creas una form y luego vuelves a crearla y llamarla con el mismo nombre de variable sin haber destruido la anterior se queda esta ultima desreferenciada por memoria.


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

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