Print Page | Close Window

array

Printed From: Crystal Reports Book
Category: Crystal Reports 9 through 2020
Forum Name: Report Design
Forum Discription: The best way to design a report and problems you have encountered
URL: http://www.crystalreportsbook.com/forum/forum_posts.asp?TID=2018
Printed Date: 28 Apr 2024 at 1:06pm


Topic: array
Posted By: rptxyz
Subject: array
Date Posted: 09 Jan 2008 at 10:33pm
like to make an array from a field in a crystal 9 report using formula. like to know how many elements the array has and to access any of its elements using an index within the range. any example on how to do it?. MakeArray did not work for me.



Replies:
Posted By: Lugh
Date Posted: 10 Jan 2008 at 4:44am
Let me try to restate this a bit, to see if I understand you correctly.

You want to store all of the values for a given field into an array.  You then want to perform various array functions on this.  Correct?

This is very possible, and not even all that tricky once you know the technique.  However, you need to be aware that there are some timing issues involved.  You may need to become very familiar with WhileReadingRecords, WhilePrintingRecords, and EvaluateAfter.  Brian's book has an excellent section on these.

In order to accomplish this, you need to create a global array variable, use ReDim Preserve on each record to expand it, and then store the value of the current field.  Your formula would look something like:


Global StringVar Array X;
//You can use NumberVar or anything else, as required.

ReDim Preserve X[RecordNumber];
//ReDim Preserve establishes the size of the array, without dropping existing data.
//RecordNumber is an existing Crystal function that gives the number of the current record. 
//As you move to each new record, the RecordNumber will increment by 1.


X[RecordNumber] := {MyReport.MyField}
//This stores the current value in the new slot in the array.


You can then run any array functions on this you might need.  You should, ideally, use these functions in the report footer, to ensure that all records are read into the array.  However, you can try using WhileReadingRecords on this formula, and WhilePrintingRecords on the calculation formula, which should work.




Posted By: rptxyz
Date Posted: 10 Jan 2008 at 7:34am
so this,X[RecordNumber] := {MyReport.MyField} , is the whole array or just an element?.  how array size is determined?. your explanation was very helpful.


Posted By: Lugh
Date Posted: 10 Jan 2008 at 10:43am
It's just a single element.  The size of the array is established by the ReDim command.  Since you ReDim on every record, it will always increase the size of the array by 1 each time.  (Keep in mind that arrays can only have 1000 elements, so keep your record count as low as you can!)

And, I made the same typo here.  It should be X(RecordNumber), with parentheses, not square brackets.  Not sure where my head was this morning.  Ouch




Posted By: rptxyz
Date Posted: 10 Jan 2008 at 9:24pm

created :
formula1:
whileprintingrecords;
numbervar array crarray;
numbervar index;
// within a for loop in here
Redim Preserve crarray[index];
crarray[index] := {report.field}));
formula2:
whileprintingrecords;
numbervar array crarray[1];

added @formula1 and @formula2 to report. printPreview generates error from formula2. something like: array index must start from 1 to size of array. But, it is within.
how to explain this error?. just need to obtain array elements, regardless.



Posted By: Lugh
Date Posted: 11 Jan 2008 at 4:31am
OK, I see a few problems here.

How is index being populated in formula1?  I noticed the comment about the for loop.  What is the for loop doing?  Can you post the entire formula?

In formula2, you may need to explicitly put EvaluateAfter(@formula1).  I have a feeling that you are attempting to call the array before you initialize it.

Speaking of which, you didn't include your scope indicators in your copied text.  You are setting these as Global, yes?




Posted By: rptxyz
Date Posted: 11 Jan 2008 at 8:33am

created :
formula1:
whileprintingrecords;
numbervar array crarray;
numbervar index;
if not({report.field} in crarray) then
index : index + 1
if index <= 1000
Redim Preserve crarray[index];
crarray[index] := {report.field}));
formula2:
whileprintingrecords;
numbervar array crarray[1];

this is it. based on an exmaple. what is correct way to handle this?. yes. i set scope to global.



Posted By: Lugh
Date Posted: 11 Jan 2008 at 11:19am
Originally posted by rptxyz

created :
formula1:
whileprintingrecords;
numbervar array crarray;
numbervar index;
if not({report.field} in crarray) then
index : index + 1

This should be:

index := index + 1

if index <= 1000
Redim Preserve crarray[index];
crarray[index] := {report.field}));

Where did these parentheses come from?

formula2:
whileprintingrecords;
numbervar array crarray[1];

You probably still need to put the EvaluateAfter statement in here.




Posted By: rptxyz
Date Posted: 11 Jan 2008 at 8:12pm
got the same error when put @formula1 and @formula2 next to each other in detail section but got no error when put the @formula1 in detail but moved @formula2 to page footer. could not make it work when both were in detail section.



Print Page | Close Window