Watch, Follow, &
Connect with Us

For forums, blogs and more please visit our
Developer Tools Community.


Welcome, Guest
Guest Settings
Help

Thread: FastReport giving Access Violation error, Access Violation Error


This question is answered. Helpful answers available: 2. Correct answers available: 1.


Permlink Replies: 2 - Last Post: Mar 6, 2016 11:12 PM Last Post By: Haley Winters
Haley Winters

Posts: 13
Registered: 3/11/13
FastReport giving Access Violation error, Access Violation Error  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 4, 2016 5:21 PM
FastReport giving Access Violation error, Access Violation Error when trying to generate code based report

Hi all,

I wanted to ask if I can get some help - I asked for help on the FastReport forum but I haven't had a reply and everytime I ask here I seem to get really good help. I know this has to do with FastReport but this seems to be the only way I can print in Delphi and if they don't answer I can't move forward with this.

I have an FDQuery that gives me some results from commands that I can type. The results of the FDQuery are pulled over into an frxDBDataSet and I have two showmessages that indicate that they are populated (I think).

My code below gets up to the ShowMessage('E') and then the frxReport.ShowReport throws up an 'Access violation at address 009BB039 in module cool_program_name. read of address 000000E0'.

Are there any ideas on what might be causing this - the majority of the code is from the FastReport4 code based reports example, is there a way that I can check if the frxDBDataSet has been populated correctly?

BTW - I am writing the program in Delphi XE8 on my Dad's work laptop, everything was completely vanilla but I have updated FastReport to version 5 trial and get the same error!

Best regards,

Haley

procedure TMainForm.mnuPrint_OnExecute(Sender: TObject);

var

frxDBDataSet : TfrxDBDataSet; // Was TfrxDataSet
frxReport : TfrxReport;
//DataPage: TfrxDataPage; // This isn't actually used
Page: TfrxReportPage;
Band: TfrxBand;
DataBand: TfrxMasterData;
Memo: TfrxMemoView;

begin

frxDBDataSet:= TfrxDBDataSet.Create(frxReport.Owner); // Was TfrxDataSet
frxDBDataSet.Name:= 'UserData';
frxDBDataSet.UserName:= Name;
frxDBDataSet.DataSet:= FDQuery;

ShowMessage('Field Count = ' + inttostr(frxDBDataSet.FieldsCount)); // for the sample data this shows 10
ShowMessage('Records Count = ' + inttostr(frxDBDataSet.RecordCount)); // for the sample data this shows 9622

frxReport:= TfrxReport.Create(Self);
frxReport.Clear;

frxReport.EnabledDataSets.Add(frxDBDataSet);

//DataPage := TfrxDataPage.Create(frxReport); // No idea why this was in the example
Page := TfrxReportPage.Create(frxReport);
Page.CreateUniqueName;
Page.SetDefaults;
//Page.Orientation := poLandscape; Doesn't like anything I put in here, I don't actually have a printer

ShowMessage('A');

Band := TfrxReportTitle.Create(Page);
Band.CreateUniqueName;
Band.Top := 0;
Band.Height := 20;

ShowMessage('B');

Memo := TfrxMemoView.Create(Band);
Memo.CreateUniqueName;
Memo.Text := 'This is all the page says!';
Memo.Height := 20;
Memo.Align := baWidth;

ShowMessage('C');

DataBand := TfrxMasterData.Create(Page);
DataBand.CreateUniqueName;
DataBand.DataSet := frxDBDataSet;
DataBand.Top := 100;
DataBand.Height := 20;

ShowMessage('D');

Memo := TfrxMemoView.Create(DataBand);
Memo.CreateUniqueName;
Memo.DataSet := frxDBDataSet;
Memo.DataField := 'CustNo';
Memo.SetBounds(0, 0, 100, 20);
Memo.HAlign := haRight;

//frxReport.PrepareReport(True); // This causes the DBGrid to scroll from top to bottom
//frxReport.Report.ShowPreparedReport; // This creates a blank view - no page at all

ShowMessage('E');

frxReport.ShowReport;

end;

Lajos Juhasz

Posts: 801
Registered: 3/14/14
Re: FastReport giving Access Violation error, Access Violation Error  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 5, 2016 3:00 AM   in response to: Haley Winters in response to: Haley Winters
Haley Winters wrote:

[snip]

frxDBDataSet:= TfrxDBDataSet.Create(frxReport.Owner); // Was
TfrxDataSet frxDBDataSet.Name:= 'UserData';
frxDBDataSet.UserName:= Name;
frxDBDataSet.DataSet:= FDQuery;

ShowMessage('Field Count = ' + inttostr(frxDBDataSet.FieldsCount));
// for the sample data this shows 10 ShowMessage('Records Count = ' +
inttostr(frxDBDataSet.RecordCount)); // for the sample data this
shows 9622

frxReport:= TfrxReport.Create(Self);
frxReport.Clear;

[snip]

Unfortunately I cannot help much as I don't know Fastreport however in
your code you have:

frxDBDataSet:= TfrxDBDataSet.Create(frxReport.Owner);

Here frxReport is still uninitialized. You should create the frxReport
before acessing its owner.

Here:

Memo := TfrxMemoView.Create(Band);
Memo.CreateUniqueName;
Memo.Text := 'This is all the page says!';
Memo.Height := 20;
Memo.Align := baWidth;


you're creating the Memo object but doesn't place it anywhere. Does it
automatically place it on owner? In VCL you have to place it by
assigning it's parent property. Never worked with FR so have no clue.
You wrote frxReport.Report.ShowPreparedReport creates a blank you this
can be due to the fact that you didn't placed the memo on the Band?
Haley Winters

Posts: 13
Registered: 3/11/13
Re: FastReport giving Access Violation error, Access Violation Error  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Mar 6, 2016 11:10 PM   in response to: Lajos Juhasz in response to: Lajos Juhasz
Hi Lajos,

Thanks for your reply - your response got me to think and that got me to find where I made an error from the example but also I now understand the actual FastReport control better.

Below I have posted a copy of the altered code where it not only works - but it reports all the fields properly as well. There are lots of refinements but this actually works!

I couldn't find an example like this anywhere so I hope this helps someone else.

Once again thanks Lajos for pointing me in the right direction.

Best regards,

Haley

The below code assumes that you have an DBGrid that is linked to a SQLDataSource that is linked to an FDQuery. The DBGrid shows results from the FDQuery and so I am using the FDGrid's widths. I don't know yet how to get the field names from frxDBDataSet so I get them directly from FDQuery - not that elegant but also not bad for code written between a gym session and other homework.

procedure TMainForm.mnuPrint_OnExecute(Sender: TObject);

var

FieldCounter, Horizontal : Integer;

frxReport : TfrxReport;
frxDBDataSet : TfrxDBDataSet; // Was TfrxDataSet many moons ago
DataPage: TfrxDataPage;
Page: TfrxReportPage;
Band: TfrxBand;
DataBand: TfrxMasterData;
Memo: TfrxMemoView;

begin

if (FDQuery.RecordCount > 0) then
begin

try

// Create an instance of the Report Control

frxReport:= TfrxReport.Create(Self);
frxReport.Clear;

// Create an instance of the Dataset and link it to the FDQuery

frxDBDataSet:= TfrxDBDataSet.Create(frxReport.Owner); // Was TfrxDataSet
frxDBDataSet.Name:= 'UserData';
frxDBDataSet.UserName:= Name;
frxDBDataSet.DataSet:= FDQuery;

// Link the Report to the Dataset

frxReport.DataSets.Add(frxDBDataSet);

// Add a Datapage

DataPage := TfrxDataPage.Create(frxReport);

// Add a Page

Page := TfrxReportPage.Create(frxReport);
Page.CreateUniqueName;
Page.SetDefaults;
Page.Orientation:= TPrinterOrientation.poPortrait; //.poLandscape;
Page.PaperSize:= DMPAPER_A4;

// Add a report title Band

Band := TfrxReportTitle.Create(Page);
Band.CreateUniqueName;
Band.Top := 0;
Band.Height := 20;

// Add object to report title band

Memo := TfrxMemoView.Create(Band);
Memo.CreateUniqueName;
Memo.Text := 'Report Title';
Memo.Font.Height:= 30;
Memo.Font.Style:= [fsBold];
Memo.Height := 30;
Memo.Align := baWidth; //baWidth;

// Add masterdata band

DataBand := TfrxMasterData.Create(Page);
DataBand.CreateUniqueName;
DataBand.DataSet := frxDBDataSet;

// “Top” should be greater than previously added band’s top + height

DataBand.Top := 100;
DataBand.Height := 20;

Horizontal:= 0;

for FieldCounter := 0 to frxDBDataSet.FieldsCount - 1 do
begin

// add the fields one by one

Memo := TfrxMemoView.Create(DataBand); // Existed
Memo.CreateUniqueName;

// connect the object to dataset

Memo.DataSet := frxDBDataSet;
Memo.DataField := FDQuery.Fields[FieldCounter].FieldName; // This should be from frxDBDataSet
Memo.SetBounds(Horizontal, 0, SQL_DBGrid.Columns[FieldCounter].Width, 20); // Where else do you get widths from
Horizontal:= Horizontal + SQL_DBGrid.Columns[FieldCounter].Width + 10; // Add the widths and a buffer
Memo.HAlign := haLeft; // haRight, bacenter;

end;

// show the report

frxReport.ShowReport;

finally

// Once we have finished free up the controls

frxDBDataSet.Free;
frxReport.Free;

end;

end;

end;

Edited by: Haley Winters on Mar 7, 2016 6:11 PM

Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02