Go Premium for a chance to win a PS4. Enter to Win

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1584
  • Last Modified:

Using WithEvents on Crystal Reports 8.5 sections

Hi Experts,

Below are VB6 code lines that works with crystal reports.
I got this from crystal reports site.
What is does is open a given crystal reports and when you try to preview it (using RDC),
it will then capture the value for each object (formula, fieldname, etc.) for each report section.
Display each value on a given lists box.

What I wanted is to make these into a sort of a function/procedure to work with all reports.
It will be something like a function that takes the report name as parameter and then using that one, will then grab all object for all report section.

I can't seem to make it work because of the WIthEvents keyword. It seems A WithEvents variable cannot be a generic object variable.
Because each report will have a diff'rent number of sections (some may contain as less as 5 and others will be as much as 15), I'd like to have a function that will have these declared generically.

Using WithEvents might not be the only solution so I'm hoping any of you guys can show me a way to make this work.

I can send the complete sourcecode(with the form, reports and sample database) if any of you guys wanted it. Just indicate the email address where to send to.

If this is not the right area (as I can see there are 2 sections for VB namely VB controls and VB DB, please let me know so that I can move this on the right topic area.


Thanks a lot,
jrmn


=========================================
Dim Report As CRAXDRT.Report
Dim crApplication As New CRAXDRT.Application

' these sections must be declared with events in order to grab the values
' from inside the sections
Dim WithEvents crSectionRH  As CRAXDRT.Section
Dim WithEvents crSectionPH As CRAXDRT.Section
Dim WithEvents crSectionD As CRAXDRT.Section
Dim WithEvents crSectionGF As CRAXDRT.Section


Dim crObject As Object
Dim crTextObject As CRAXDRT.TextObject
Dim crFieldObject As CRAXDRT.FieldObject

Private Sub Form_Load()
Screen.MousePointer = vbHourglass

Set Report = crApplication.OpenReport(App.Path & "\report1.rpt")

' set the all the sections
Set crSectionRH = Report.Sections("RH")
Set crSectionPH = Report.Sections("PH")
Set crSectionD = Report.Sections("D")
Set crSectionGF = Report.Sections("GF")


CRViewer1.ReportSource = Report
CRViewer1.ViewReport
Screen.MousePointer = vbDefault

End Sub

Private Sub FillListBox(ByRef crSection As CRAXDRT.Section)

' check each object in the section
For Each crObject In crSection.ReportObjects
   
    ' we are only considering two cases right now 1. if it is a text object, or if it is a field object
    Select Case crObject.Kind
        Case CRAXDRT.CRObjectKind.crTextObject:
            Set crTextObject = crObject
            ' add the name and the value to the list box so you can see what is happening
            List1.AddItem crTextObject.Name
            List1.AddItem "  " & crTextObject.Text
       
        Case CRAXDRT.CRObjectKind.crFieldObject:
            Set crFieldObject = crObject
            ' add the name and the value to the list box so you can see what is happening
            List1.AddItem crFieldObject.Name
            List1.AddItem "  " & crFieldObject.Value
       
    End Select
   
    Set crTextObject = Nothing
    Set crFieldObject = Nothing
Next

End Sub

Private Sub crSectionRH_Format(ByVal pFormattingInfo As Object)

Call FillListBox(crSectionRH)

End Sub

Private Sub crSectionGF_Format(ByVal pFormattingInfo As Object)

Call FillListBox(crSectionGF)

End Sub
Private Sub crSectionPH_Format(ByVal pFormattingInfo As Object)

Call FillListBox(crSectionPH)
End Sub


Private Sub crSectionD_Format(ByVal pFormattingInfo As Object)

Call FillListBox(crSectionD)

End Sub

Private Sub Form_Resize()
CRViewer1.Top = 0
CRViewer1.Left = List1.Left + List1.Width + 50
CRViewer1.Height = ScaleHeight
CRViewer1.Width = ScaleWidth - CRViewer1.Left

End Sub

Private Sub List1_Click()

End Sub

=======================================

0
jrmn
Asked:
jrmn
  • 2
1 Solution
 
nmcdermaidCommented:
I'm not sure I understand exactly what you want, but if you wish to raise a generic event from a number of particular events you can do this:

1. Create a class which declares your required objects Withevents
2. When handling the events, raise a generic event which has the object type as a string parameter
3. Declare the class you just created Withevents in another class
4. The class created in step 4 now receives one event even underneath it all there are a whole bunch of objects.



Some very basic example code that will give you an idea of what I am talking about:




Event GenericEvent(ByVal sType as String, ByVal sData as String)

 these sections must be declared with events in order to grab the values
' from inside the sections
Dim WithEvents crSectionRH  As CRAXDRT.Section
Dim WithEvents crSectionPH As CRAXDRT.Section
Dim WithEvents crSectionD As CRAXDRT.Section
Dim WithEvents crSectionGF As CRAXDRT.Section


Dim crObject As Object
Dim crTextObject As CRAXDRT.TextObject
Dim crFieldObject As CRAXDRT.FieldObject

' Event handlers... all specific events are redirected to one generic event.
Private Sub crSectionRH_Format(ByVal pFormattingInfo As Object)
  RaiseEvent GenericEvent("SectionRH", pFormattingInfo.Data)
End Sub

Private Sub crSectionGF_Format(ByVal pFormattingInfo As Object)
  RaiseEvent GenericEvent("SectionGF", pFormattingInfo.Data)
End Sub
0
 
jrmnAuthor Commented:
Hi nmcdermaid,

Thanks for the reply. I'd like to know if you know crystal reports so that we can discuss this as clearly as possible.

Is there a way to have the WithEvents declaration generic?
I mean for each report, assume you don't know how many sections are being use. Say detail section could be actually of 2 sections detailA and detailB.
If we are going to declare each section specifically, I guess the code will work only for few reports that has the same number of sections we declare for the WithEvents.
I'd like to have a way of having a function that will work for all reports.
Say myreport.rpt have 6 sections (RH, PH, Da(detail section A), Db(detail section B), GH and GF)

1. First we open the report.
2. Then we will check how many sections are there for this report.
3. Check what section(s) are being suppressed (as it is very possible and usually, report header and footer sections are being suppressed at designed time)
4. Then given these information, (say we know that only 4 sections are being used and we know which section (name) are these), we will then declare a WithEvents for each of these sections.
5. Each of these declared sections (WithEvents) will be use the GenericEvent we will be providing.

Is this possible?

As I have said, using WithEvents might not be the only solution. I am hoping to get another solution.

If you like, I can give you the complete source codes and other files you might need so that you can try it at your end.
Just let me know where to send it to (email).

Cheers,
jrmn
0
 
nmcdermaidCommented:
The limitation is in the parameters in the event rasied by the Crystal library.

If you are lucky, the object returned by the event will contain the section name, so you would only have to declare one section withevents, and the object event raised by it would be for all sections in the report, and the object contains the name and can be handled accordingly.


However I doubt if it works that way, so you need to make a class wrapper that forces it to work that way!!


This is the only way I can think of making that class wrapper:

1. Make a class that declares 100 sections withevents (damn ugly but you can't declare arrays with events)

2. Have a method in the class which allows you to assign section names to the internal sections object variables in the class. In the method you will need to use a big ugly case statement to pick the correct section object variable, and an index to move along the 100 object variables.

3. Have 100 event handlers for those 100 sections objects. (Ugly ugly ugly). In each event handler, raise a single event which passes the Object as well as the section name.


Then in the class you are currently working on, make one instance of the class I have just described. Use the method I described at point 2 to add sections dynamically as required. Handle the event described in point 3 to handle the sections dynamically.

Its ugly but it work (as long as you don't have more than 100 sections! ;))


Someone may have a better way to do this but basically these are the limitations which make me think that this is the only way to do wha you want.

-You can't declare an object variable withevents as an array (or collection)
-The event raised by the Crystal library is per each section object rather than one for the entire report.





0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now