Solved

Dataset size for my Crystal Report is TOO BIG for RAM

Posted on 2009-04-06
9
866 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
Major Incident Management Communications

Major incidents and IT service outages cost companies millions. Often the solution to minimizing damage is automated communication. Find out more in our Major Incident Management Communications infographic.

 
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 101

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

The Orion Papers

Are you interested in becoming an AWS Certified Solutions Architect?

Discover a new interactive way of training for the exam.

Question has a verified solution.

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

Hello everyone, Hope you find this as helpful as we did. We have on the company I work for an application built in Delphi V with Crystal Reports 8. We all know that Crystal & Delphi can be temperamental sometimes and the worst thing is, nearly…
I wrote an article (http://www.experts-exchange.com/articles/2245/Anti-rootkit-software.html) some time ago with a reference to nLite  (http://www.nliteos.com/)slipstreaming software.  I recently changed that link to point to NTLite (https://www.ntl…
Finding and deleting duplicate (picture) files can be a time consuming task. My wife and I, our three kids and their families all share one dilemma: Managing our pictures. Between desktops, laptops, phones, tablets, and cameras; over the last decade…
In this video we outline the Physical Segments view of NetCrunch network monitor. By following this brief how-to video, you will be able to learn how NetCrunch visualizes your network, how granular is the information collected, as well as where to f…

729 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