47,549 Members
6 added today
482,686 Resources
1,228 added today

All Devdex   All Gurus  

Crystal Reports 8.5 automatic runtime report creation and data insertion (Web or VB6).
Author: Matt Burnett
Rating:
Visits: 14323

Discuss in Newsgroups

This function is fantastic with crystal reports. It takes 2 parameters, the crystal app object, and a recordset. It returns a report object that can be veiwed or printed. It does not require a existing report format (.rpt file) or data file (.ttx). The function can be used in VBScript or VB6.

I made some assumptions at the top to allow groups to be added and different saveAs paths, but essentially its all dynamic crystal 8.5. If you need subreports email me at burnettm@hotmail.com

The code below is VBScript, to use in VB, modify the following lines:

'////// ADD ADO RECORDSET TO THE NEW REPORT ///
Add: Set oRs = new ADODB.Recordset
Set Session("oRs") = adoMainRS
Modify: Set oRs = adoMainRs
Call Database.Tables.Add("",,Session("oRs"),,"P2smon.dll")
Modify: Call Database.Tables.Add("",,oRs,,"P2smon.dll")

Public Function getSimpleDynamicCRPT(byRef oApp, byVal adoMainRs)  
 '==============================================================================
 ' WORKING WITH THE REPORT DESIGNER COMPONENT AND ASP TO DYNAMICALLY CREATE A REPORT,
 ' ADD A RECORDSET, ADD GROUPS, AND ADD SECTIONS
 '
 'THIS REPORT AS NO SUBREPORT, ITS IS A SIMPLE REPORT
 '==============================================================================
 'This file uses a Crystal Application Object to create a New Report Object.
 'Set session("oApp") = Server.CreateObject("CrystalRuntime.Application")
 '
 'The new reports data is contained in the ADO recordsets passed into this function.
 'The ADO recordset also contains 'Formating Fields' information regarding:
 ' SysID, SortOrder
 ' blnUseExistingReport  = true/false, if true, then we are in the incorrect function
 ' blnSaveReport    = true/false
 ' blnReplaceExistingReport = true/false
 ' rptPath      = "" Original path
 ' rptName      = "" Original name
 ' rptSavePath     = "" New path to save a report but not replace the original
 ' rptDisplayTitle    = "" Report Title
 ' rptGroupFieldOrdinalReferences = "" 'A coma delimited string of integers that represent
 '         the Ordinal references of the data fields to be grouped
 'Formating value are repeating on all rows of the rs. A consideration may be given to passing
 'another rs into the function which contains the formating fields.
 ' 
 'GENERAL EXECUTION
 '
 'DEFINING THE FORMAT
 'The design of this function is based around the adoMainRs recordset and results in a HORIZONTAL
 'split of the recordset into 2 parts. The LEFT side contains 'Formating' fields list above.
 'The RIGHT side contain fields to be displayed into the report. It is assumed that once development is finished
 'The Ordine Reference of the 1st Data Field would be constant (with above format fields, its 9).
 'The variable 'intStart_Position' should be set to Ordine Reference of the 1st Data Field.
 'NOTE: All inserted values are set in the 'Define the format' code section immediately following the declarations.
 'NOTE: Height, font, color, size, bold and alignment are pre-set conditions of a generic report.
 '
 'POSITIONING Crystal(object,left,top)
 'The HORIZONTAL LEFT positioning used is based on the number of data fields to be displayed. Currently, adoMainRs
 'has 2 (sysid, sortorder) fields not used for data, therefore, the intStart_Position is 3 (hardcoded).
 'The TOP to Bottom positioning is relative to the top of the rtp.SECTION in which the object is placed.
 '
 'To create a positioning system based on coordinates inputed in a recordset.
 'the adoMainRs would contain LEFT and TOP coordinates in twips (inches can be convert to twips):
 'adoMainRs (might look like this and 250 is as left as you can go, zero, 0 , will not print)
 '| sysid | sortorder | datafield1 | fieldPositionLEFT1 | fieldPositionTOP1 | datafield2 | fieldPositionLEFT2 | fieldPositionTOP2 |
 '| 22222 | 2         | matt       | 250  (twips)       | 250               | doug       | 2000               | 250
 '| 33333 | 2         | jim        | 250                | 3000              | tom        | 2000               | 3000
 '
 'The same loop might be used in the column headers and field objects to insert the Crystal Data.
 'Example: note its STEPPING
 ' For i = intStart_Position to intNumber_Of_Columns STEP 3 'STEP 3 will use every 3 as data field.
 '  Set crxColHeader = crxHeadSection.AddTextObject(adoMainRS(i).Name, int(adoMainRS(i+1).value), int(adoMainRS(i+2).value))
 '
 '12240 twip width of 8 1/2 inches, the lenght is 15840 twips of 11 inches OR 1440 twips per inch.
 'Variable blnAddGroupLine insures there is a line under the column heads regardless of groups added.
 'Set the Crystal Object WIDTH property to the entire width of page to get the horizontal alignment correct.
 '
 'SECTIONS
 'The default Crystal sections are referenced by KEY not INDEX. This insures that after GROUPS and SUBREPORTS are
 'added the correct references can be obtained.
 '
 'GROUPS
 'rs("rptGroupFieldOrdinalReference") contains a string of ordinal fields references representing the fields
 'in the recordset to group the report data.
 'The Section INDEX of 3 is a constant starting position for any groups added.
 'If you have a date field as a group, this will error. Change the constant CRanyValue = 14 to a valid date constant
 'like CRDay or CRMonth.
 'Each GROUP has two parts of header and footer. The footer is located below the Detail section.
 '
 'SESSIONS
 'In VB, set Session values of oApp, oRpt to variables with proper scope and there are no problems.
 'In VB6 this Method - Call Database.Tables.Add("",,adoMainRS,,"P2smon.dll") - is used.
 'If in ASP, this Method will generate a 'type missmatch' that can only be resolved by setting the
 'recordset into a session object, then using the session variable as the parameter.
 'Clearly a frustrating error.
 'Set Session(oRs) = adoMainRS is not needed in VB.
 '
 'SAVING THE REPORT
 'Save the report parameter constant, 2048 is Crystal 8 format.

 'CRYSTAL OBJECTS: EXAMPLES
 'Set crxSetInReport = crxHeadSection.AddTextObject(adoMainRS(i).Name, 7000, 0)
 'Set crFieldObject  = crSection.AddFieldObject("{ado." & adoMainRS(4).Name & "}",5000,0)
 'Set crxSetInReport = crxReportFooter.AddTextObject(Session("oRpt").PrintDate, 250, 0)
 'crxPageFooter.AddSpecialVarFieldObject(crSvtPageNumber, 10000, 0) 'top is not needed, 'constant is 7
 '==============================================================================
 '==============================================================================

 Dim Database, Table1, intStart_Position, crxSetInReport, crFieldObject, intDataPositionOffset
 Dim crxReportHeader, crxPageHeader, crxGroupHeader1, crxDetail, crxReportFooter, crxPageFooter
 Dim intColumnPosition, intColumnSpacing, intPageWidth, i, intNumber_Of_Columns, strValue
 Dim crSection1, crSection2, aryGroups, strGroups, blnSaveReport, intTop, iCount
 Dim rptPath, rptName, rptDisplayTitle, blnReplaceExistingReport, rptSavePath, blnReportSubReport
 Dim oRpt, oRs
 Dim blnAddGroupLine
 '////// DEFINE THE FORMAT /////////////////////
 blnSaveReport    = true  'from rs, blnSaveReport
 blnReplaceExistingReport    = true  'from rs, blnReplaceExistingReport
 blnAddGroupLine    = false  'indicates a separator line between group and detail
 strGroups     = "3,4"  'from rs, rptGroupFieldOrdinalReferences
 rptPath      = "e:\temp\"  'from rs
 rptName      = "newreport.rpt" 'from rs
 rptSavePath     = "e:\matt\"  'from rs
 rptDisplayTitle    = "Dynamic Report (Simple)" 'from rs
 intStart_Position   = 3     'ss a recordset constant
 intPageWidth    = 15000   '12240 is page width, but 15000 works better
 intNumber_Of_Columns  = adoMainRs.Fields.Count - 1
 intColumnSpacing   = intPageWidth/intNumber_Of_Columns
 intColumnPosition   = 250 'if rs positioning, then from rs.
 aryGroups     = Split(strGroups,",")
 intTop      = 250
 iCount      = 0
 
 '////// CREATE THE NEW REPORT /////////////////
 Set oRpt = oApp.NewReport
 '////// ADD ADO RECORDSET TO THE NEW REPORT ///
 Set Session("oRs") = adoMainRS
 Set Database = oRpt.Database
 Call Database.Tables.Add("",,Session("oRs"),,"P2smon.dll")
 Set Table1 = Database.Tables.Item(1)

 '////// CREATE THE SECTIONS ///////////////////
 Set crxReportHeader = oRpt.Sections.Item("RH") 'Report Header
 Set crxPageHeader   = oRpt.Sections.Item("PH") 'Page Header
 Set crxDetail       = oRpt.Sections.Item("D") 'Detail
 Set crxReportFooter = oRpt.Sections.Item("RF") 'Report Footer
  crxReportFooter.PrintAtBottomOfPage = true
 Set crxPageFooter   = oRpt.Sections.Item("PF") 'Page Footer
  crxPageFooter.PrintAtBottomOfPage = true

 '////// PAGE TITLE ////////////////////////////
 Set crxSetInReport = crxReportHeader.AddTextObject(rptDisplayTitle, 0, 250)
 With crxSetInReport
  .Height = 350
  .Width = intPageWidth
  .Font.Size = 18
  .Font.Underline = false
  .Font.Bold = true
  .TextColor = vbBlack
  .HorAlignment = 2
 End With
 
 '////// COLUMN HEADERS ////////////////////////
 Set crxSetInReport = crxPageHeader.AddTextObject("Date: ", intColumnPosition, 250) 'top is not needed
 With crxSetInReport
  .Height = 225
  .Width = 2000 'intColumnSpacing
  .TextColor = vbBlack
  .Font.Bold = true
 End With
 Set crxSetInReport = crxPageHeader.AddSpecialVarFieldObject(crSvtPrintDate, intColumnPosition + 750, 250) '4
 With crxSetInReport
  .Height = 225
  .Width = 2000 'intColumnSpacing
  .TextColor = vbBlack
  .Font.Bold = true
 End With
 
 For i = intStart_Position to intNumber_Of_Columns
  Set crxSetInReport = crxPageHeader.AddTextObject(adoMainRS(i).Name, intColumnPosition, 750)
  With crxSetInReport
   .Height = 225
   .Width = intColumnSpacing
   .TextColor = vbBlack
   .Font.Bold = true
  End With
  intColumnPosition = intColumnPosition + intColumnSpacing
 Next
 
 intColumnPosition = 250 'Reset the postion
 '////// ADD GROUPS ////////////////////////////
 If (strGroups <> "") then
  For i = 0 to UBound(aryGroups)
   Call oRpt.AddGroup(i,Table1.Fields(int(aryGroups(i))),14,0)
   Set crxGroupHeader1 = oRpt.Sections.Item(i+3)
   Set crFieldObject = crxGroupHeader1.AddFieldObject("{ado." & adoMainRS(int(aryGroups(i))).Name & "}",intColumnPosition,250)
   With crFieldObject
    .Height = 200
    .Width = 5000 '.Width = intColumnSpacing
    .TextColor = vbBlack
    .HorAlignment = 1
   End With
   intColumnPosition = intColumnPosition + intColumnSpacing
   If Not blnAddGroupLine then
    Set crxSetInReport = crxGroupHeader1.AddLineObject(0, 0, 12000, 0)
    crxSetInReport.LineThickness = 5
   End If
   blnAddGroupLine = true
  Next
 End If
  
 '////// FILL THE DETAIL SECTION ///////////////
 For i = intStart_Position to intNumber_Of_Columns
  If Not(getAryValue(i,aryGroups)) then
   Set crFieldObject = crxDetail.AddFieldObject("{ado." & adoMainRS(i).Name & "}",intColumnPosition,250)
   With crFieldObject
    .Height = 200
    .Width = intColumnSpacing
    .TextColor = vbBlue
    .HorAlignment = 1
   End With
   intColumnPosition = intColumnPosition + intColumnSpacing
   If Not blnAddGroupLine then
    Set crxSetInReport = crxDetail.AddLineObject(0, 0, 12000, 0)
    crxSetInReport.LineThickness = 5
   End If
   blnAddGroupLine = true
  End If
 Next

 '////// PAGE AND REPORT FOOTER ////////////////
 Set crxSetInReport = crxPageFooter.AddSpecialVarFieldObject(crSvtPageNumber, 10000, 0)
 '////// SAVE THE NEW REPORT ///////////////////
 If (blnSaveReport And blnReplaceExistingReport) then
  Call oRpt.SaveAs(rptPath & rptName,2048)  'Replace
 ElseIf (blnSaveReport) then
  Call oRpt.SaveAs(rptSavePath & rptName,2048) 'New RPT, same name, different path
 End If
 '////// END AND RETURN THE REPORT OBJECT //////
 Set getSimpleDynamicCRPT = oRpt
End Function

Private Function getAryValue(ByVal strItemName, ByVal aryItems)
    Dim q 'Assumes a single column array of values, returns true if strItemName is in the array.
    getAryValue = false
    For q = 0 To UBound(aryItems)
        If (UCase(aryItems(q)) = UCase(strItemName)) Then
            getAryValue = true
            Exit For
        End If
    Next
End Function


Visit my guru profile

Visitor Comments

Jon Kaminsky Nice work on automating Crystal, which can be a ma...

 

Rate this Code Sample






	
	
	



Credit Card Payment Control
Supports over 25 companies
Managed ASP.NET Solution
Direct Processor Support

ASP ArticlesThis category has been added to your weekly newsletter
ASP Web Sites
ADSI & WSH BooksThis category has been added to your weekly newsletter
FREE ComponentsThis category has been added to your weekly newsletter
ASP EventsThis category has been added to your weekly newsletter
ASP HeadlinesThis category has been added to your weekly newsletter

CSharp ArticlesThis category has been added to your weekly newsletter
C# Web SitesThis category has been added to your weekly newsletter

SQL ArticlesThis category has been added to your weekly newsletter
SQL Events
SQL HeadlinesThis category has been added to your weekly newsletter
SQL Jobs

Jobs in CaliforniaThis category has been added to your weekly newsletter

XML ArticlesThis category has been added to your weekly newsletter
XML BooksThis category has been added to your weekly newsletter
XML Web Sites
XML Tutorials

free asp host

"Alex Homer"This search has been added to your weekly newsletter

Edit My Favorites Edit Profile & Favorites

Web Programming

 




Developersdex Home | ASP | C# | SQL | VB | XML | Gurus
Add Your Link | Add Your Code | FAQ | Advertise | Link To Us | Contact Us |
Copyright © 2009 Developersdex™. All rights reserved.