Solved

Dataset size for my Crystal Report is TOO BIG for RAM

Posted on 2009-04-06
9
855 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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

 

Author Comment

by:tgr2000
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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

Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

Join & Write a Comment

More often than not, we developers are confronted with a need: a need to make some kind of magic happen via code. Whether it is for a client, for the boss, or for our own personal projects, the need must be satisfied. Most of the time, the Framework…
Storage devices are generally used to save the data or sometime transfer the data from one computer system to another system. However, sometimes user accidentally erased their important data from the Storage devices. Users have to know how data reco…
Here's a very brief overview of the methods PRTG Network Monitor (https://www.paessler.com/prtg) offers for monitoring bandwidth, to help you decide which methods you´d like to investigate in more detail.  The methods are covered in more detail in o…
This video demonstrates how to create an example email signature rule for a department in a company using CodeTwo Exchange Rules. The signature will be inserted beneath users' latest emails in conversations and will be displayed in users' Sent Items…

771 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

16 Experts available now in Live!

Get 1:1 Help Now