Solved

Dataset size for my Crystal Report is TOO BIG for RAM

Posted on 2009-04-06
9
856 Views
Last Modified: 2013-12-01
I am using VS2008, VB.NET.  Created a simple Windows application that finds a list of JPG files in a specified Folder, loads the names of the JPG files into an XML file.  I use that XML file to read the JPG file names and load the actual JPG into a Byte() array in my Dataset.  That Dataset is then the DataSource for my Crystal Report that simply has two JPGs on each page.

PROBLEM: THe list of JPGs may be as many as 200, which then makes the Byte() Array very large and too large to pull into the Dataset in RAM.

QUESTION: How can I get the Crystal Report to maybe load JPG photos direct from the file names or from another XML file whcih has the Byte() array of the JPG data?
0
Comment
Question by:tgr2000
  • 6
  • 2
9 Comments
 
LVL 15

Assisted Solution

by:oobayly
oobayly earned 200 total points
ID: 24081917
Instead of using a dataset, you could try using a BindingList<>.
You would have to create a property for each column that's contained in the report. This way you can create a readonly property that provides the Image data by reading the data from the filename only when it's needed. You may get this to work as garbage collection may clear up the byte arrays once they're no longer needed.

As you see, I've been able to bind a BindingList<Foo> to a DataGridView. To be quite honest, I'm not sure if this will even work with Crystal reports, but it's worth a try.

Of course, creating a class may be quite tedious if there are to be a lot of properties. I quite often use OpenOffice (saves the Excel license) to create the private fields & the respective public properties.
public void CreateData(){

      BindingList<Foo> foo = new BindingList<Foo>();

      foo.Add(new Foo() { ImagePath = @"D:\Image1.JPG" });

      foo.Add(new Foo() { ImagePath = @"D:\Image2.JPG" });

      foo.Add(new Foo() { ImagePath = @"D:\Image3.JPG" });

      dataGridView1.DataSource = foo;

}
 

  public class Foo{

    private string imagePath;
 

    public string ImagePath {

      get { return imagePath; }

      set { imagePath = value; }

    }
 

    public byte[] ImageData {

      get {

        // Read the Image data into a byte array

        System.IO.FileStream fs = new System.IO.FileStream(imagePath,

          System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.Read);

        byte[] data = new byte[fs.Length];

        fs.Read(data, 0, data.Length);
 

        fs.Close();

        return data;

      }

    }

  }

Open in new window

0
 

Author Comment

by:tgr2000
ID: 24081978
BindingList, that sounds like something to try.  Any idea where the "List" is mantained? I think it may be maintained in RAM just as the Dataset is but I am not sure.  I'll certainly look into it.
0
 

Author Comment

by:tgr2000
ID: 24082010
I would like to do soemthing like...
Dim xCrystal as New CrystalReport1
xCrystal.SetDataSource("c:\MyPhotos\Photos.xml")

Then open the report.
Photos.xml has 3 columns...
JPGFileName (eg Photo_001.jpg)
JPGDescription (some text)
JPGByte (Image Data)
0
 
LVL 15

Expert Comment

by:oobayly
ID: 24082048
The list will definately be kept in RAM as a dataset would be, I'm also presuming the ImageData is the largest component in terms of size.
If Crystal Reports enumerates throught the list the way I'd hope, the ImageData property will only be requested when the item is being written to the report. Once it's been written, there should be no more references to it remaining and the byte array should be garbage collected.

The difference in doing it this way that total size of the List should never be that large as the ImageData should on be in memory when it's being used.
0
DevOps Toolchain Recommendations

Read this Gartner Research Note and discover how your IT organization can automate and optimize DevOps processes using a toolchain architecture.

 

Author Comment

by:tgr2000
ID: 24082069
OK, I understand what you are saying and I can see how that would possibly work.  Let me try to figure out how to get the Crystal Report bound to the BindingList and I will get back to you on my results.  Thanks for the idea.
0
 
LVL 100

Accepted Solution

by:
mlmcc earned 300 total points
ID: 24083740
Can you put the images into a database and run the report against the database rather than an in memory dataset?

mlmcc
0
 

Author Comment

by:tgr2000
ID: 24087140
Yes, that is a good option and is exactly why I was trying to XML as the "database".  I need a file based database so chose XML.  I don't want to keep the Image Data in a centralized DB as this app needs to float around with the JPGs and be used on laptops and other areas.  The trick is the user will copy the FOLDER (JPGs and DB) to the repository once thye are done creating the report.  I am currently creating a TEM PXML file that includes the ImageData, trying to open a Crystal report against that XML file, print the report, delete the XML.
Do you have any other suggestions for what kind of local, file based, DB I could use?
0
 

Author Comment

by:tgr2000
ID: 24087659
OK, I have a possible solution using a little help from several posts and a little more research.  Need just a nit more help.
I link my Crystal Report to an XML file.   I get the data fro mthe XML to show on the report... GREAT! I just push a new XML file before opening the report and it works EXCEPT...
Ho do I place an identifier (not sure that is the correct word) in an XML file to identify the field as ByteArray or ImageData or what ever it is I need?
0
 

Author Comment

by:tgr2000
ID: 24089027
Great, I have a solution that works very well.  I keep all BUT the Image Data in XML and write the XML to local FOLDER with JPGs.  That gives me the description, JPG file name and few other TEXT fields that I need to KEEP with the JPGs.

Then, to open the report, I read the XML and add the ImageData via Stream into a LOCAL DB that I created via Visual Studio.  I empty the LOCAL DB before inserting the records each time prior to opening the Crystal Reports.  The Crystal Reports is connected to the LOCAL DB.

This Works perfect for my needs.

Thanks to both, I learned from you suggestions, combined a couple ideas, did a little more research and I now have a fully functional solution.

I would like to assign points to both parties? I'll see if that is possible.  Thanks again.
0

Featured Post

DevOps Toolchain Recommendations

Read this Gartner Research Note and discover how your IT organization can automate and optimize DevOps processes using a toolchain architecture.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

I previously wrote an article addressing the use of UBCD4WIN and SARDU. All are great, but I have always been an advocate of SARDU. Recently it was suggested that I go back and take a look at Easy2Boot in comparison.
This article shows how to deploy dynamic backgrounds to computers depending on the aspect ratio of display
This video shows how to remove a single email address from the Outlook 2010 Auto Suggestion memory. NOTE: For Outlook 2016 and 2013 perform the exact same steps. Open a new email: Click the New email button in Outlook. Start typing the address: …
The Email Laundry PDF encryption service allows companies to send confidential encrypted  emails to anybody. The PDF document can also contain attachments that are embedded in the encrypted PDF. The password is randomly generated by The Email Laundr…

932 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

8 Experts available now in Live!

Get 1:1 Help Now