Thursday, June 15, 2006

Changing output created by the Crystal Report Viewer

I often use Crystal Reports to report on Lotus Notes data. (I connect using NotesSQL, although I've tried a number of other methods that weren't as effective or reliable.) Crystal Reports is a very good reporting tool and is integrated nicely into Visual Studio.

Recently I setup a Web form with a CrystalReportSource and CrystalReportViewer control on it, and set the appropriate properties to point to my report. Opening the page in the browser launches the report and it is displayed using DHTML. This all works well with the exception of a bug that appears when it renders hyperlinks in the browser.

I have a field on the report that has the hyperlink formula set to a column in my datasource. My datasource is a Notes database view, and one of the columns in that view is called NotesURL. The values in the NotesURL column have the form notes://server/database/view/document. When a user clicks on a Notes URL from within a browser, their Notes client is launched and the specified document is opened. This works much like a doclink does within Notes.

When the Crystal Web viewer control renders the field, it normally injects the correct HTML code to display the hyperlink. This works fine when the URL begins with "http://". However, the control ignores hyperlinks that begin with "notes://" or even "javascript:". As a result, only the field value appears on the report, without a hyperlink.

Thanks to the power of OOP it really wasn't that hard to fix.

First, I hardcoded the hyperlink formula to start with "http://", so the NotesURLs would appear as http://notes://server/database/view/document. Then I added the code below to modify the field's hyperlink property just before the field is rendered on the page.

This worked great and the hyperlinks appear as they should. Unfortunately there is a trade off because exporting to excel or word doesn't cause the BeforeRenderObject event to fire. As a result, the URLs appear in the http://notes:// format within Excel.

Private Sub CrystalReportViewer1_BeforeRenderObject(ByVal source As Object, ByVal e As _ CrystalDecisions.Web.HtmlReportRender.BeforeRenderObjectEvent) Handles CrystalReportViewer1.BeforeRenderObject

'Crystal Reports XI release 2 (and all other releases I've tried) does not render hyperlinks correctly

'if they begin with notes:// or javascript:


'To work around this issue, I add the http:// in the hyperlink formula on the field object from

'within Crystal Reports designer. Then just before the report viewer renders the object I remove

'the http:// from the beginning of the URL.

'Find FieldObjects

If TypeOf e.Object Is CrystalDecisions.CrystalReports.ViewerObjectModel.FieldObjectInstance Then

Dim myField As CrystalDecisions.CrystalReports.ViewerObjectModel.FieldObjectInstance = CType(e.Object, CrystalDecisions.CrystalReports.ViewerObjectModel.FieldObjectInstance)

If myField.HasHyperLink Then

If myField.HyperLink.Contains("notes://") Or myField.HyperLink.Contains("javascript:") Then

myField.HyperLink = myField.HyperLink.Substring(7) 'grab all after http://

End If

End If

End If

End Sub

No comments: