• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 564
  • Last Modified:

code causing Einvalid/access violation

Hi,
I seem to keep getting access violation or einvalid point whenever I try to close a form. I have attach the code of the form for reference. The form is used to perform a query on Access Database and it would insert the data in the query into Microsoft Excel. Everything work ok except when trying to close the form which will cause the error. Would be great if anyone could indicate what is causing the porblem.

>>>>>>>>>>>>>

unit MassMail;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, Buttons, ExtCtrls,Comobj, Gauges, OleServer,
  Excel97, ComCtrls, ADODB, Db;

type
  TMail = class(TForm)
    ProgressBar1: TProgressBar;
    ADOConnection1: TADOConnection;
    MailQuery: TADOQuery;
    Bevel1: TBevel;
    StaticText1: TStaticText;
    Gauge1: TGauge;
    Label3: TLabel;
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure FormActivate(Sender: TObject);
    procedure FormShow(Sender: TObject);

  private
    { Private declarations }
    iCount, iRowCount, iRecCount : Integer;
    sSQLSTR : String;
    SPORE : String;
    sPathName : String;
    Text : String;
  public
    { Public declarations }
  end;

var
  Mail: TMail;
  MSExcel : variant;


implementation

uses Functs;

{$R *.DFM}

procedure TMail.FormClose(Sender: TObject; var Action: TCloseAction);
begin
   FreeAndNil(Mail);
   Action := CAFree;

end;

procedure TMail.FormActivate(Sender: TObject);
begin
String:='abctext ';
Text :='Loading...';
       iRowCount := 4;

        with MailQuery do
        begin

        Close;  SQL.Clear;

                sSQLSTR := 'Select AField,BField,CField,DField,EField,FField,GField,HField from Table1';

                SQL.Add(sSQLSTR);
                open;

     if EOF then
     begin
       MessageDlg('No Data To Process .', mtInformation, [mbOk], 0);
       Abort;  Exit;
     end

     else
     begin
       iCount := MailQuery.RecordCount;
       ProgressBar1.Position := 0;
       ProgressBar1.Min := 0;
       ProgressBar1.Max := iCount;
       iRecCount := 0;
 
       while not EOF do
        begin

         Next;
         Inc(iRecCount);
         ProgressBar1.StepBy(1);
         StaticText1.Caption := IntToStr(iRecCount);
         Mail.Repaint ;

        end;
        MailQuery.First;

        MSExcel := CreateOleObject('Excel.Application');
        MSExcel.Visible := False;
        MSExcel.Workbooks.Open('C:\Excel.xls', ReadOnly:=False);
        MSExcel.WindowState := 2;

        StaticText1.Caption :=Text;
        StaticText1.Repaint ;
        Progressbar1.Hide ;
        Gauge1.Show;
        Gauge1.MaxValue :=iRecCount;

        while not EOF do
        begin


       MSEXCEL.WorkSheets[1].Range['A' + IntToStr(iRowCount)].Value := FieldByName('AField').AsString +FieldByName('BField').AsString + FieldByName('CField').AsString + FieldByName('DField').AsString;

       MSEXCEL.WorkSheets[1].Range['B' + IntToStr(iRowCount)].Value := FieldByName('EField').AsString;
      MSEXCEL.WorkSheets[1].Range['C' + IntToStr(iRowCount)].Value := FieldByName('FField').AsString;
       MSEXCEL.WorkSheets[1].Range['D' + IntToStr(iRowCount)].Value := FieldByName('GField').AsString;
       MSEXCEL.WorkSheets[1].Range['E' + IntToStr(iRowCount)].Value := String1 + FieldByName('HField').AsString;
       Next;
       Gauge1.AddProgress(1);
       Inc(iRowCount);
       StaticText1.Repaint ;
        end;
               end;
       end;

       StaticText1.Caption :='Done';
       StaticText1.Repaint ;
       MSExcel.Visible := true;
       MSExcel.WindowState := 1;
       MSExcel.WorkSheets[1].PrintOut(Preview:=True);
       StaticText1.Caption :='Done';
       StaticText1.Repaint ;


end;

procedure TMail.FormShow(Sender: TObject);
begin
Gauge1.Hide ;
Progressbar1.show;
end;

end.


<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<


Any help is appreciated. Thanks.
0
cwtang
Asked:
cwtang
3 Solutions
 
cwtangAuthor Commented:
I forgot to add that the compiler being used is Delphi 5. Any help is appreciated.

Thanks
0
 
cwtangAuthor Commented:
Realsie there was some typing error on previous code, I have updated the code.

>>>>>>>>>>>>>

unit MassMail;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, Buttons, ExtCtrls,Comobj, Gauges, OleServer,
  Excel97, ComCtrls, ADODB, Db;

type
  TMail = class(TForm)
    ProgressBar1: TProgressBar;
    ADOConnection1: TADOConnection;
    MailQuery: TADOQuery;
    Bevel1: TBevel;
    StaticText1: TStaticText;
    Gauge1: TGauge;
    Label3: TLabel;
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure FormActivate(Sender: TObject);
    procedure FormShow(Sender: TObject);

  private
    { Private declarations }
    iCount, iRowCount, iRecCount : Integer;
    sSQLSTR : String;
    String1 : String;
    sPathName : String;
    Text : String;
  public
    { Public declarations }
  end;

var
  Mail: TMail;
  MSExcel : variant;


implementation

uses Functs;

{$R *.DFM}

procedure TMail.FormClose(Sender: TObject; var Action: TCloseAction);
begin
   FreeAndNil(Mail);
   Action := CAFree;

end;

procedure TMail.FormActivate(Sender: TObject);
begin
String1:='abctext ';
Text :='Loading...';
       iRowCount := 4;

        with MailQuery do
        begin

        Close;  SQL.Clear;

                sSQLSTR := 'Select AField,BField,CField,DField,EField,FField,GField,HField from Table1';

                SQL.Add(sSQLSTR);
                open;

     if EOF then
     begin
       MessageDlg('No Data To Process .', mtInformation, [mbOk], 0);
       Abort;  Exit;
     end

     else
     begin
       iCount := MailQuery.RecordCount;
       ProgressBar1.Position := 0;
       ProgressBar1.Min := 0;
       ProgressBar1.Max := iCount;
       iRecCount := 0;
 
       while not EOF do
        begin

         Next;
         Inc(iRecCount);
         ProgressBar1.StepBy(1);
         StaticText1.Caption := IntToStr(iRecCount);
         Mail.Repaint ;

        end;
        MailQuery.First;

        MSExcel := CreateOleObject('Excel.Application');
        MSExcel.Visible := False;
        MSExcel.Workbooks.Open('C:\Excel.xls', ReadOnly:=False);
        MSExcel.WindowState := 2;

        StaticText1.Caption :=Text;
        StaticText1.Repaint ;
        Progressbar1.Hide ;
        Gauge1.Show;
        Gauge1.MaxValue :=iRecCount;

        while not EOF do
        begin


       MSEXCEL.WorkSheets[1].Range['A' + IntToStr(iRowCount)].Value := FieldByName('AField').AsString +FieldByName('BField').AsString + FieldByName('CField').AsString + FieldByName('DField').AsString;

       MSEXCEL.WorkSheets[1].Range['B' + IntToStr(iRowCount)].Value := FieldByName('EField').AsString;
      MSEXCEL.WorkSheets[1].Range['C' + IntToStr(iRowCount)].Value := FieldByName('FField').AsString;
       MSEXCEL.WorkSheets[1].Range['D' + IntToStr(iRowCount)].Value := FieldByName('GField').AsString;
       MSEXCEL.WorkSheets[1].Range['E' + IntToStr(iRowCount)].Value := String1 + FieldByName('HField').AsString;
       Next;
       Gauge1.AddProgress(1);
       Inc(iRowCount);
       StaticText1.Repaint ;
        end;
               end;
       end;

       StaticText1.Caption :='Done';
       StaticText1.Repaint ;
       MSExcel.Visible := true;
       MSExcel.WindowState := 1;
       MSExcel.WorkSheets[1].PrintOut(Preview:=True);
       StaticText1.Caption :='Done';
       StaticText1.Repaint ;


end;

procedure TMail.FormShow(Sender: TObject);
begin
Gauge1.Hide ;
Progressbar1.show;
end;

end.


<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

0
 
mikelittlewoodCommented:
Shouldnt need this

procedure TMail.FormClose(Sender: TObject; var Action: TCloseAction);
begin
   FreeAndNil(Mail);
   Action := CAFree;
end;
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
robert_marquardtCommented:
Step 1:
Get rid of "Mail: TMail;" variable. Somewhere in your code you have "Mail := TMail.Create(Self);" and a "Mail.ShowModal;".
There you place Mail as a local variable and call "Mail.Free;" after "Mail.ShowModal;".
This allows you to completely remove the TMail.FormClose method.

Step 2:
Keep in mind that both FormActivate and FormShow could be called several times.
Secure at least FormActivate that it is only executed once.
0
 
mikelittlewoodCommented:
Another way would be to use a class function/procedure to do the work for you.
Then from the calling unit just code

TMail.Execute

This will then create the unit and free it for you after use.
*************************************************************

unit MassMail;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, Buttons, ExtCtrls,Comobj, Gauges, OleServer,
  Excel97, ComCtrls, ADODB, Db;

type
  TMail = class(TForm)
    ProgressBar1: TProgressBar;
    ADOConnection1: TADOConnection;
    MailQuery: TADOQuery;
    Bevel1: TBevel;
    StaticText1: TStaticText;
    Gauge1: TGauge;
    Label3: TLabel;
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure FormActivate(Sender: TObject);
    procedure FormShow(Sender: TObject);

  private
    { Private declarations }
    iCount, iRowCount, iRecCount : Integer;
    sSQLSTR : String;
    String1 : String;
    sPathName : String;
    Text : String;
  public
    class procedure Execute;
  end;

var
  Mail: TMail;
  MSExcel : variant;


implementation

uses Functs;

{$R *.DFM}

class procedure TMail.Execute;
begin
  // create the form
  Mail := TMail.Create(Application);
  // with the new form
  with Mail do
    try
      // show the form
      ShowModal;
    finally
      // get rid of the form
      FreeAndNil(Mail)
    end;
end;

procedure TMail.FormActivate(Sender: TObject);
begin
String1:='abctext ';
Text :='Loading...';
       iRowCount := 4;

        with MailQuery do
        begin

        Close;  SQL.Clear;

                sSQLSTR := 'Select AField,BField,CField,DField,EField,FField,GField,HField from Table1';

                SQL.Add(sSQLSTR);
                open;

     if EOF then
     begin
       MessageDlg('No Data To Process .', mtInformation, [mbOk], 0);
       Abort;  Exit;
     end

     else
     begin
       iCount := MailQuery.RecordCount;
       ProgressBar1.Position := 0;
       ProgressBar1.Min := 0;
       ProgressBar1.Max := iCount;
       iRecCount := 0;
 
       while not EOF do
        begin

         Next;
         Inc(iRecCount);
         ProgressBar1.StepBy(1);
         StaticText1.Caption := IntToStr(iRecCount);
         Mail.Repaint ;

        end;
        MailQuery.First;

        MSExcel := CreateOleObject('Excel.Application');
        MSExcel.Visible := False;
        MSExcel.Workbooks.Open('C:\Excel.xls', ReadOnly:=False);
        MSExcel.WindowState := 2;

        StaticText1.Caption :=Text;
        StaticText1.Repaint ;
        Progressbar1.Hide ;
        Gauge1.Show;
        Gauge1.MaxValue :=iRecCount;

        while not EOF do
        begin


       MSEXCEL.WorkSheets[1].Range['A' + IntToStr(iRowCount)].Value := FieldByName('AField').AsString +FieldByName('BField').AsString + FieldByName('CField').AsString + FieldByName('DField').AsString;

       MSEXCEL.WorkSheets[1].Range['B' + IntToStr(iRowCount)].Value := FieldByName('EField').AsString;
      MSEXCEL.WorkSheets[1].Range['C' + IntToStr(iRowCount)].Value := FieldByName('FField').AsString;
       MSEXCEL.WorkSheets[1].Range['D' + IntToStr(iRowCount)].Value := FieldByName('GField').AsString;
       MSEXCEL.WorkSheets[1].Range['E' + IntToStr(iRowCount)].Value := String1 + FieldByName('HField').AsString;
       Next;
       Gauge1.AddProgress(1);
       Inc(iRowCount);
       StaticText1.Repaint ;
        end;
               end;
       end;

       StaticText1.Caption :='Done';
       StaticText1.Repaint ;
       MSExcel.Visible := true;
       MSExcel.WindowState := 1;
       MSExcel.WorkSheets[1].PrintOut(Preview:=True);
       StaticText1.Caption :='Done';
       StaticText1.Repaint ;


end;

procedure TMail.FormShow(Sender: TObject);
begin
Gauge1.Hide ;
Progressbar1.show;
end;

end.
0
 
pibaCommented:
If you need to free a form from within one of the buttons or events on the form you could cal release

From the delphi help.

Destroys the form and frees its associated memory.
Delphi syntax:
procedure Release;
Description
Use Release to destroy the form and free its associated memory.

Release does not destroy the form until all event handlers of the form and event handlers of components on the form have finished executing. Release also guarantees that all messages in the form's event queue are processed before the form is released. Any event handlers for the form or its children should use Release instead of Free (Delphi) or delete (C++). Failing to do so can cause a memory access error.

Note:      Release returns immediately to the caller. It does not wait for the form to be freed before returning.
0
 
cwtangAuthor Commented:
Sorry for the late reply. Was away.

Thanks to everyone. Got it solved:)
0

Featured Post

Hire Technology Freelancers with Gigs

Work with freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely, and get projects done right.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now