Monday, April 20, 2009

Deploying a vb.net Project containing Crystal Reports on a Windows 98 machine

Deploying a vb.net Project containing Crystal Reports on a Windows 98 machine

If, like me, you have been tearing your hair out trying to get a Windows application containing Crystal Reports deployed & running on Windows 98 operating system then this may be of some help. I should point out that I am not a professional programmer and so have pretty large (cavernous!) gaps in my knowledge. As a consequence, finding the solution to a problem can take time – the information is all out there, it’s just a question of knowing where to look. Hopefully the following text will pull the essential information together. Sorry if it’s a bit long winded but I’ve tried to include things which Net.Newbies, like me, may not know.

The Problem:

I had developed a Windows application within which I had embedded a couple of reports (produced using Crystal Reports). The application project ran fine on my development machine (Windows XP). I created a deployment project for this application. The application installed and ran fine on another XP machine (which also had Visual Studio installed on it). When I tried to install the application on a Windows 98 machine (which did not have Visual Studio, Crystal Reports etc. installed) all manner of problems arose. The main problem was an error which occurred each time I tried to open the report viewer – “Err: Report Load Fail”. I’ll list below the problems encountered.

Problem 1: At first I used the “Setup & deployment projects – Setup Wizard” to produce my deployment project. This produced a deployment project Ok but one which did not work (i.e. Deploy & Install) on a 98 machine.

Problem 2: Having solved problem 1 (see later!) I then had an application which deployed (installed) on a 98 machine but would not run. First reason for not running was the need to upgrade MDAC (see later!) and the second reason (which has caused the most trouble) was to modify the installation so that reports (Crystal Reports) would open and run on the 98 machine (this was the “Err: Report Load Fail”).

The Solution:

Some basic info first; I was using VB.Net (Visual Studio.net 2003) in a Windows Form. The version of Crystal Reports used was that which came bundled with Visual Studio (this appears to be 9.1.5000.0 according to the reference within VB Studio). The reports used are embedded within the project. Here’s what I did. Apologies in advance if much of this is common knowledge –but it’s usually the simplest point that if overlooked causes the whole thing to go pear shaped and fail to work.

Producing the Deployment Project:

Open Solution Explorer, right click on the “Solution Name” at the top and Add a New Project. On the window that appears, move to Setup and Deployment Projects. Click on Setup Project (not the wizard), put a name for your deployment project (make a note of the location where the folder that the deployment project will be created in) and then click OK. A File System dialog will appear – solution explorer should be displayed on the left of screen. Within solution explorer – right click over your deployment project and select Add – Project Output. Another window will appear – select Primary Output (make sure configuration is showing Active) and click OK. This will result in the detected dependencies being updated & a primary output icon appearing in the deployment project. Right click on the deployment project name again and Add – Merge Modules. Add the following modules.

Crystal_Database_Access2003.msm
Crystal_Database_Access2003_enu.msm
Crystal_Managed2003.msm
Crystal_regwiz2003.msm
VC_User_CRT71_RTL_X86_---.msm
VC_User_STL71_RTL_X86_---.msm

These were the appropriate modules for my application given that I am using VS 2003. You can check your specific needs by going to this site

click here

And finding the environment appropriate to you i.e. VB.net 2003, Full versions of Crystal Reports etc…

Right click on Crystal_regwiz2003.msm and go to its properties. Enlarge the MergeModuleProperties tree and enter the product licence key. This can be found by opening the Help menu on Visual Studio and then opening About Microsoft Development Environment. You will see the 19 character licence code for Crystal Reports in the Installed Products List.

Go onto Build – Configuration Manager . Check that the Project & Deployment Project which appear are set to “Release” and the Build check box for each is checked. Build the Project. If all is well the build should show no errors.

If this has gone according to plan you should now have (in the folder specified in the “location” window given when you added your deployment project) a debug and release folder. The release folder will contain

setup (application)
setup (config file)
an installer package.

The release folder is all that is needed to deploy the application on another machine.

Getting it to work on a 98 machine:

The client machine must have the net framework installed before you do anything.
You will have to manually install dotnetfx (this will not automatically happen, even if dotnetfx is included in the detected dependences of the deployment project). Dotnetfx is available as a free download from Microsoft.

Next install onto the client machine the latest MDAC (Microsoft Data Access Components) version (version 2.8 at the moment). This is available from Microsoft - link shown below.

click here

It should now be possible to install your application. From the client machine, find the release folder for your application (this can be anywhere – development machine, cd rom – you name it) and double click the setup (application) icon. Just follow the install wizard as it runs – decide your installation folder etc… and follow it all to the end.

Once your application has been installed you still have to do a couple of things to the client 98 machine in order to get the Crystal Reports to work.

The reason the “Err: Report Load Fail” occurred is apparently because the file “dbghelp.dll” doesn’t get installed during installation and that the following file “crqe.dll” doesn’t get registered with the 98 operating system during installation.
I found the necessary fix on the following Crystal Reports site.

click here

To sort this out do the following. Copy from your development machine “dbghelp.dll”. You will find it in Windows\System32 folder on your development machine. Paste this into the Windows\System32 folder on the client 98 machine.

Register the “crqe.dll” file with the 98 machine in the following way. Click Start then Run on the 98 machine. In the command line box that appears manually register crqe.dll by entering the path to the folder containing the file. Check on your 98 machine where the file is and enter the path. The command line should look something like this:-

Regsvr32 “c:\program files\common file\Crystal Decisions\1.0\bin\crqe.dll”

Change the bit in quotes to match your path. Then press enter. A message should come back to say the registering has been successful.

You should now be ready to rock & roll. Having carried out this procedure I found that the Crystal Reports viewer opened and displayed the reports in my application on the 98 machine – hope it works for you.

Labels:

Password Prompt when opening crystal report.Net connected to MSAccess database.

Hello reader.
Well this faq is related to a problem very frequently faced by many new Crystal Report Developers (I faced it too). But I was quiet sure of the fact that this problem has some solution bcoz problem without a solution isn't a problem.
Sometimes when we develop a report using MSAcess database we are prompted for password while viewing the report even if it hasn't got one and we go nuts trying several round abouts for this problem.

Solution:
When you start developing a new report and go to Add/Remove Database
1. DO NOT SELECT "OLE DB (ADO)" as your datasource.
2. Click "More Data Sources" then double click "Access/Excel (DAO)".
3. In "Database Name" give complete path to the database or click button next to it to browse for it.
4. In "Database Type" select "Access".
5. If your database is NOT PROTECTED by PASSWORD click "Finish".
6. Whereas if your database is PROTECTED by PASSWORD click "Secure Logon" checkbox.
7. Write your password in "Database Password" textbox.
8. Leave the other fields empty.
9. Click "Finish".

If you have a report already developed and facing this problem:

1. Right click "Database Fields" in "Field Explorer".
2. Click on "Set Location"
3. Your current database wil be selected by default.
4. In "Replace with" section repeat the above mentioned steps to access your database.
5. Select the database which you just added.
6. Click "Replace" button to replace the existing database with new one.
7. Click "Close" when database is replaced.
PS: This process wont effect the fields or designing of your report. It will just replace th database.

It worked for me and I am sure it will work for you too.

Labels:

Exporting a Crystal Report into an Excel File

After designing and finishing the report, everything may look nice and cool.
But what if the report needs to be exported to another format, say Excel.

I've tried this out, clicked on the Export Icon located at the toolbar of the
Crystal Report Viewer and saved it to an Excel file.

It works fine right? Yes, but once you open the file, you'd notice something
strange - either the columns used contains gaps or just not as what you've
expected it to be. Or certain lines are not supposed to be in that row or
column.

So, how to solve this problem is the way we've designed the report; upon
designing, think of the report as an excel file without a grid (but to make it
easier, you could format the grid to be visible and you could easily align
your report fields).
Designing the report in a way wherein we have to be precise in aligning each
field within the header, detail and footer; or even within groups.

An example is when you have a long header and 2 short details, what you should
do is to align the 2 detail fields within the header:

:----- Header -----:
:-Detail-: :-Detail-:

In this way, this will occupy the columns A & B within the excel sheet.

This is only one of the ways on how to export the Crystal Report into an excel
sheet. I'll be adding the other ways on my next coming parts.

Labels:

Insert a text on your crystal report from code

This FAQ demonstrates how you can set a textvalue in your code and show this text in your report.
The attached program shows you how to do this.

Basically we have three different scenarios:
1)Via a parameter: this is the standard communication between VB.NET and a report.
This is not my recommended way to set a text on a report. It's quite some code, and it's prone to errors. I had some strange experiences with it in the past (like a maximum text length of 254 bytes). Consult the updates and monthly fixes on the support site: http://www.businessobjects.com/services/support/default.asp


Code:Dim paramFields As ParameterFieldDefinitions
Dim paramField As ParameterFieldDefinition
Dim paramValue As ParameterValues
Dim paramDiscreteValue As New ParameterDiscreteValue

paramFields = rpt.DataDefinition.ParameterFields
SetParameter(paramFields, "PersonalCommentsParameter", Me.txtParameter.Text)

Public Sub SetParameter(ByVal paramDef As ParameterFieldDefinitions, ByVal paramName As String, ByVal paramValue As String)
Dim crParameterFieldDefinition As ParameterFieldDefinition = paramDef.Item(paramName)
Dim crParameterValues As ParameterValues = crParameterFieldDefinition.CurrentValues
Dim crParameterDiscreteValue As New ParameterDiscreteValue

crParameterDiscreteValue.Value = paramValue
crParameterValues.Add(crParameterDiscreteValue)
crParameterFieldDefinition.ApplyCurrentValues(crParameterValues)
End Sub


2)Via a text object: This is my recommended way to go: create a text object in your report, give it a clear name and drag it on your form.


Code:Dim SampleReportText As CrystalDecisions.CrystalReports.Engine.TextObject = CType(rpt.ReportDefinition.ReportObjects.Item("PersonalCommentsText"), CrystalDecisions.CrystalReports.Engine.TextObject)
SampleReportText.Text = Me.txtTextObject.Text


3)Via a formula: create a formula, give it a clear name and drag it on your form. There's no code needed inside the formula body.

Whatever way you choose: set it's 'can grow' option to true. Select the field inside your report, right click, select Format Field, and you should check the 'Can Grow' box in the common tab.

Dim crFormulas As FormulaFieldDefinitions

Code:
'formulas that will contain the field name
Dim crFormulaTextField1 As FormulaFieldDefinition

'set the Formulas collection to the current report's formula
'collection
crFormulas = rpt.DataDefinition.FormulaFields

crFormulaTextField1 = crFormulas.Item("PersonalCommentsFormula")
crFormulaTextField1.Text = "'" & Me.txtFormula.Text & "'"


Check the attachment for a full blown example!

Edit:In this thread someone pointed out a problem with multiple line text when working with the formula solution. I made a solution to it. The trick is to tell CR that there is a CR/LF in the text. This is done by adding the string "Chr(10) & Chr(13)" to your text. Note that I said "string", not "characters". CR has to interprete this string itself, and will translate that string to a CR/LF itself!!
This is also for displaying single quotes in your string.


Code:

Try
Dim crFormulas As FormulaFieldDefinitions

'formulas that will contain the field name
Dim crFormulaTextField1 As FormulaFieldDefinition

'set the Formulas collection to the current report's formula
'collection
crFormulas = rpt.DataDefinition.FormulaFields

crFormulaTextField1 = crFormulas.Item("PersonalCommentsFormula")
crFormulaTextField1.Text = TranslateStringToCRFormula(Me.txtFormula.Text)


Catch ex As Exception

End Try

Private Function TranslateStringToCRFormula(ByVal VBString As String) As String

Dim Returnstring As String = "'"

'Split the string at every LF
For Each SubString As String In VBString.Split(Chr(10))

SubString = SubString.Replace("'", "' & Chr(39) & '")

'Trim all the CR / LF characters
SubString = SubString.Trim(vbCrLf.ToCharArray)

'Form your string to the compatible CR Formula format. Chr(10) &nd Chr(13) should be inserted as a string, not as values!!
Returnstring = Returnstring & "' & Chr(10) & Chr(13) & '" & SubString

Next

Returnstring = Returnstring & "'"

Return Returnstring

End Function



Edit: One of our users, Makavelli, found a problem in this last method (it returns a new line regardless if there is one or not ). Here's his fix:


Code:Public Function TranslateStringToCRFormula(ByVal strValue As String) As String
Dim Returnstring As String = "'"
Dim i As Integer = 0

'Split the string at every LF
For Each SubString As String In strValue.Split(Chr(10))
'Trim all the CR / LF characters
SubString = SubString.Trim(vbCrLf.ToCharArray)

If i > 0 Then
Returnstring &= "' & Chr(10) & Chr(13) & '"
End If
i += 1

SubString = SubString.Replace("'", "' & Chr(39) & '")

Returnstring &= SubString

Next

Returnstring = Returnstring & "'"

Return Returnstring

End Function

Labels:

How to load an image from disk into Crystal Reports?

Introduction
One of the missing parts when it comes to reporting via .NET and Crystal Reports is the lack of support of image support.
It’s not directly possible to load an image based on a provided filepath in the report at runtime.
This feature is now available in the new Crystal Reports 11, but the bundled version of Visual Studio lack the possibility.

But Crystal Reports in Visual Studio supports datasets, and we’ll load an image in the report via a dataset!

Tools
-Visual Studio professional or Enterprise architect. You could also use any Visual Studio version with a separate Crystal Reports version (one that does support datasets!).
-10 minutes of time.
-Some general concepts about Crystal Reports and datasets

Tasks
-create a dataset that supports images
-create a report that support this dataset
-load data in the dataset
-use the dataset as datasource for the report and show the report in the viewer

In the attachment you’ll find a fully working sample. Feel free to experiment with it and spread it around the world!

Ready?

Create a new winforms project and a dataset (dsImageReport) to it. You’ll need to include 1 table (Image) with two columns:

Table Image
Name: string
Photo: base64Binary

The names of the columns don’t matter that much, it’s important that you use the base64Binary datatype for the second column! We will load the image from disk as a bytearray.

Creating the report is easy. Create a new report, when choosing the datasource go for the ADO.NET option and browse for the dsImageReport.xsd file in your project directory.

Now drag the two fields from your fieldexplorer in your report.
You’ll notice that the Photo field is of a BLOB datatype. This is exactly like we need. You don’t need to insert a picture in your report. Just drag the Photo field in the report. This field will be a square (1 inch x 1 inch). Don’t resize it but right click it and select Format Graphic. In the format editor check the ‘can grow’ checkbox. This will make it possible to load images of different sizes in the report!

We need to load the data in the dataset based on a given filepath, use that dataset as datasource for the report and show the report in the viewer.

Here’s the code:


Code:
Private Sub btnLoadImage_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles btnLoadImage.Click

Dim ofdImage As New OpenFileDialog

If ofdImage.ShowDialog = DialogResult.OK Then

Try

'Create a new instance of the dataset
Dim dsImgRpt As New dsImageReport

'Create a new instance of the report
Dim m_imagereport As New rptImage

'Create a new row in the dataset
Dim dr As dsImageReport.ImageRow = _
dsImgRpt.Image.NewImageRow

'Set the various elements of the row
dr.Name = ofdImage.FileName
'fill this field with a byte array
dr.Photo = GetImageData(ofdImage.FileName)

'Add the new row to the dataset
dsImgRpt.Image.Rows.Add(dr)

'Use the dataset as datasource for the report
m_imagereport.SetDataSource(dsImgRpt)

'Show the report in the reportviewer
Me.crystalReportViewer1.ReportSource = m_imagereport

Catch ex As Exception

MessageBox.Show("Something went wrong: " & ex.Message)

End Try

End If

End Sub

Private Function GetImageData(ByVal fileName As String) As Byte()

'Method to load an image from disk and return it as a bytestream
Dim fs As System.IO.FileStream = _
New System.IO.FileStream(fileName, _
System.IO.FileMode.Open, System.IO.FileAccess.Read)
Dim br As System.IO.BinaryReader = New System.IO.BinaryReader(fs)
Return (br.ReadBytes(Convert.ToInt32(br.BaseStream.Length)))

End Function

You see that it isn’t that difficult to load an image from file in a dataset. There are a lot of possibilities when it comes to reporting when you’re using a dataset as datasource. The biggest advantage is that you can manipulate the data in your dataset the way you want. Crystal isn’t that flexible when it comes to data manipulating but datasets are excellent for this!

Labels:

Exporting a Crystal Report into an Excel File

After designing and finishing the report, everything may look nice and cool.
But what if the report needs to be exported to another format, say Excel.

I've tried this out, clicked on the Export Icon located at the toolbar of the
Crystal Report Viewer and saved it to an Excel file.

It works fine right? Yes, but once you open the file, you'd notice something
strange - either the columns used contains gaps or just not as what you've
expected it to be. Or certain lines are not supposed to be in that row or
column.

So, how to solve this problem is the way we've designed the report; upon
designing, think of the report as an excel file without a grid (but to make it
easier, you could format the grid to be visible and you could easily align
your report fields).
Designing the report in a way wherein we have to be precise in aligning each
field within the header, detail and footer; or even within groups.

An example is when you have a long header and 2 short details, what you should
do is to align the 2 detail fields within the header:

:----- Header -----:
:-Detail-: :-Detail-:

In this way, this will occupy the columns A & B within the excel sheet.

This is only one of the ways on how to export the Crystal Report into an excel
sheet. I'll be adding the other ways on my next coming parts.

Labels:

How to load RTF and HTML into Crystal Reports?

Introduction
One of the most interesting questions I got lately in the .NET Reporting forum is how you can load RTF coded text in Crystal Reports (complete with all the layout).

Crystal Reports provides functionality to interpret text as RTF or HTML. You only need to provide the data in a correct way..

Tools
-Visual Studio professional or Enterprise architect. You could also use any Visual Studio version with a separate Crystal Reports version (one that does support datasets!).
-10 minutes of time.
-Some general concepts about Crystal Reports and datasets

Tasks
-create a dataset to load the RTF, HTML and plain text.
-create a report that support this dataset
-load data in the dataset
-use the dataset as datasource for the report and show the report in the viewer

In the attachment you’ll find a fully working sample. Feel free to experiment with it and spread it around the world!

Ready?

Create a new winforms project and a dataset (dsCodedText) to it. You’ll need to include 1 table (TextCode) with three columns:

PlainText: string
RTFText: string
HTMLText: string

Creating the report is easy. Create a new report, when choosing the datasource go for the ADO.NET option and browse for the dsCodedText.xsd file in your project directory.

Now drag the three fields from your fieldexplorer in your report.

OK, now here comes the trick!

Select the RTFText field in your report, right click and choose ‘Format Field’. Select the paragraph tab. The bottom groupbox (Text interpretation) contains one combobox. Select ‘RTF Text’ from the combobox.

Select the HTMLText field in your report, right click and choose ‘Format Field’. Select the paragraph tab. The bottom groupbox (Text interpretation) contains one combobox. Select ‘HTML Text’ from the combobox.

Select the PlainText field in your report, right click and choose ‘Format Field’. Select the paragraph tab. The bottom groupbox (Text interpretation) contains one combobox. Select ‘None’ from the combobox.

In the attached sample you’ll find three simple files (one RTF, one HTML, one plain).
You’ll need to load these files as strings in your dataset (in that way, you will have both the readable text AND the markup tags).

As a side note I can remark that you only can enable this text interpretation on text that is stored in the datasource (as a string or as a memo field). You can’t enable this text interpretation on e.g. a text field or a formula...

Labels: