Solved

Dataset size for my Crystal Report is TOO BIG for RAM

Posted on 2009-04-06
9
858 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
3 Use Cases for Connected Systems

Our Dev teams are like yours. They’re continually cranking out code for new features/bugs fixes, testing, deploying, testing some more, responding to production monitoring events and more. It’s complex. So, we thought you’d like to see what’s working for us.

 
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
 

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

3 Use Cases for Connected Systems

Our Dev teams are like yours. They’re continually cranking out code for new features/bugs fixes, testing, deploying, testing some more, responding to production monitoring events and more. It’s complex. So, we thought you’d like to see what’s working for us.

Question has a verified solution.

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

There have always been a lot of questions related to when Crystal Reports evaluates report components (such as formulas, summaries, cross-tabs, charts, to name a few examples). Crystal Reports uses a two-pass reporting process to provide greater …
Today, still in the boom of Apple, PC's and products, nearly 50% of the computer users use Windows as graphical operating systems. If you are among those users who love windows, but are grappling to keep the system's hard drive optimized, then you s…
Two types of users will appreciate AOMEI Backupper Pro: 1 - Those with PCIe drives (and haven't found cloning software that works on them). 2 - Those who want a fast clone of their boot drive (no re-boots needed) and it can clone your drive wh…
Although Jacob Bernoulli (1654-1705) has been credited as the creator of "Binomial Distribution Table", Gottfried Leibniz (1646-1716) did his dissertation on the subject in 1666; Leibniz you may recall is the co-inventor of "Calculus" and beat Isaac…

831 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