Solved

Reference a string value as an ActiveReport object.

Posted on 2000-04-04
19
346 Views
Last Modified: 2012-05-04
Initial Design:
In my SQL Server 7.0 database I maintain a list of all the reports in our VB 6.0 application.  This list is presented to the end-user inside a listview on the main screen.  The user selects which report they would like to view and press a command button to display it.  The code behind this command button references the SelectedItem of the listview which is the report's name and passes that to a subroutine which displays the report:

    Call mdl_transReporting_PreviewReport(Me.lvwReports.SelectedItem)


Problem:
In my subroutine, what is being received as a parameter is the report's name in a string variable:

    mdl_transReporting_PreviewReport(myReportName as String)

What I'm currently doing is using a Select Case to evaluate the report's name and display the appropriate report:

    Dim rpt As Object
    Dim fPreview As New frmPreviewReport    'Form which contains the ActiveReport Viewer

    Select Case myReportName
        Case "rptMemberCostSummary"
            Set rpt = New rptMemberCostSummary
    End Select

    fPreview.RunReport rpt
    fPreview.Show

Isn't there some way I can directly display the report without using the Case statement?  If I change myReportName to an Object or to an ActiveReport object, I of course get a type mismatch when I make the call.  I'm fighting with the syntax here to correctly reference the SelectedItem in my listview as an object instead of a string.  Any ideas?

Thanks,
- Dean
0
Comment
Question by:Deano1121
  • 5
  • 3
  • 2
  • +6
19 Comments
 
LVL 2

Expert Comment

by:damienm
ID: 2684388
fwd
0
 
LVL 10

Expert Comment

by:caraf_g
ID: 2684403
I think so....

Where is rptMemberCostSummary defined? In a DLL perhaps?

What is puzzling is your line

Set rpt = New rptMemberCostSummary

In order to be able to do that, the class rptMemberCostSummary must be defined as a class in a DLL?

Well in that case, you could use the CreateObject syntax:

Set rpt = CreateObject("YourDLL.rptMemberCostSummary")

or in your case

Set rpt = CreateObject("YourDLL." & myReportName)

?
0
 
LVL 10

Expert Comment

by:caraf_g
ID: 2684416
BTW - Welcome to EE!
0
 

Author Comment

by:Deano1121
ID: 2684447
Thanks for the welcome!

rptMemberCostSummary is a designer within VB and not a class inside a DLL.

- Dean
0
 

Author Comment

by:Deano1121
ID: 2684450
Thanks for the welcome!

rptMemberCostSummary is a designer within VB and not a class inside a DLL.

- Dean
0
 
LVL 14

Expert Comment

by:wsh2
ID: 2684755
Deano1121 writes:

Call mdl_transReporting_PreviewReport(Me.lvwReports.SelectedItem)

SlectedItem is of ListItem type. Try:

Call mdl_transReporting_PreviewReport(Me.lvwReports.SelectedItem.Key)

-or-
 
Call mdl_transReporting_PreviewReport(Me.lvwReports.SelectedItem.Text)

Whichever you stored the Report name in.


0
 
LVL 1

Expert Comment

by:tkuppinen
ID: 2684776
These reports have a name property.  Just compare the name property of the report to your string then if it matches, show the report.
0
 
LVL 28

Expert Comment

by:AzraSound
ID: 2684799
could you add another field to the database that holds the pathname of the specified report and then upon a user selecting a report from the listview, perform a simple query that retrieves that pathname to open it?
0
 
LVL 69

Expert Comment

by:Éric Moreau
ID: 2684829
I don't think you can do this!

Even if you place your report in an ActiveX DLL, you won't be able to use the CreateObject statement since it is a designer and not a class.

Did you ask this question to the support site of Data Dynamics? If you find it, please let me know. I also use AR and it could be great to have this functionality. Tell me one more thing: where do you compile your reports?
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 

Author Comment

by:Deano1121
ID: 2684849
To AzraSound:
With this technique I would be no better off and actually worse since I would be incurring an additional hit to my database.
- Thanks, Dean


To tkuppinen:
That's what the current Select Case construct is doing.
- Thanks, Dean


To wsh2:
Perhaps I explained this in a confusing way.  I have problem obtaining the name of the report at all.  But it is in string format and holds no reference to the report object which is in my project as a designer.  The Key and Text properties of SelectedItem are no different.
- Thanks, Dean
0
 
LVL 28

Expert Comment

by:AzraSound
ID: 2684858
can you create a UDT that holds the string value and the report object?
0
 

Author Comment

by:Deano1121
ID: 2684905
To emoreau:

I'm starting to get the same feeling that it simply cannot be done.  I was hoping there may be an API call that was exposed for this general purpose.  Or perhaps an adaption of the CallByName function in VB6.  In questioning Data Dynamics I received the following:

.... wants a way to dim a new object from a string variable which as far as I know is not possible with VB classes that are in the project (such as forms and reports)

He wants:

Dim s As String
Dim x AS Object

    s = "ActiveReport1"
    Set x = New s
    ' or CreateObject(s), of course this works with external objects but not a form
    ' or a report

This has been a thorn in our side since the early development, we needed a way to call New from inside ActiveReports based on a report name so that we can link SubReports without requiring the

    Set srpt.object = New childreport

in the ReportStart event.  We talked with just about everyone we know in the VB developer group and it went all the way to their dev manager and they said it couldn't be done not even from the designer SDK that we used to write AR.  I think it is part of the compiler and it happens at compile time and there is no equivalent call for it at runtime...


This was the reply from Issam at DD so it would seem I am not going to find a solution.  The reason for my obsession to remove the Select Case is to allow us to add additional reports to our application, make an entry in the database, and never have to touch the client source code.

Thanks,
- Dean
0
 
LVL 69

Expert Comment

by:Éric Moreau
ID: 2684946
«The reason for my obsession to remove the Select Case is to allow us to add additional reports to our application, make an entry in the database, and never have to touch the client source code.»

How will your reports be compiled in your application?
0
 
LVL 14

Expert Comment

by:wsh2
ID: 2685064
As to the Data Report.. since it is NOT loaded into memory until you do your Set statement.. brute force and ignorance (ie. a Set Case) is your only recourse.. <sigh>. Give this a try.. and then we will gor from there.. <smile>.

Private Sub mdl_transReporting_PreviewReport(myReportName as String)

Dim rptSelect As DataReport
Select Case myReportName
  Case "rptMemberCostSummary"
    Set rptSelect = rptMemberCostSummary
End Select
rptSelect.Show

End Sub




0
 
LVL 28

Expert Comment

by:AzraSound
ID: 2685192
You have to excuse me as I have never worked with reports before but some input never hurt anyone right?  =)  Besides, the more wrong solutions I pump out the quicker we can resolve this...hehe

If you declare a public type

Public Type rptStruct
   rptName As String
   rptObj As Object
End Type

and declare an array for whatever length you need which will be an array of the UDT rptStruct,

Dim rptArr() As Variant


It would require some more overhead to initialize this array but once you have, is it possible to use the index of the selected item in the listview as the index of the array?  For example, a user clicks ListView(5) which corresponds to rtpArr(5) so the next thing it would do is:

Set rtpArr(5).rptObj = New rtpArr(5).rptName





0
 
LVL 15

Expert Comment

by:ameba
ID: 2686543
>without using the Case statement
>never have to touch the client source code.

You can tell your clients to add small 'cw' class per report, e.g.:
' class cwrptMemberCostSummary
' wrapper class for report rptMemberCostSummary
Option Explicit
Public Property Get Rpt() As Object
    Set Rpt = New rptMemberCostSummary
End Property


Here is a sample, with 'Data Report' designer (MS)
Start new ActiveX EXE project, start mode = Standalone
Add DataReport
'----------------------------------
' Module1 code
Option Explicit

Public Sub Main()
    Form1.Show
End Sub
'----------------------------------
' Form1 code
Option Explicit

Private Sub Form_Click()
    PreviewReport "DataReport1"
End Sub

Public Sub PreviewReport(strReportName As String)
    Dim x As Object
    Set x = CreateObject("Project1.cw" & strReportName).Rpt
    x.Show
End Sub
'----------------------------------
' class cwDataReport1, instancing=5
' wrapper class for report DataReport1
Option Explicit

Public Property Get Rpt() As Object
    Set Rpt = New DataReport1
End Property
'----------------------------------
0
 
LVL 1

Accepted Solution

by:
Argonaut earned 300 total points
ID: 2687697
Deano try this:

Create an ActiveX DLL with a Class and your report designer.  Like This:

Option Explicit

'Wrapper Class for rpt485

Public Function GetReport(custReportName As String, custWhere As String) As Object
Dim rpt As Object

    On Error GoTo ehGetReport
    Select Case custReportName
    Case "oReport"
        Screen.MousePointer = vbHourglass
        SQLWhere = custWhere
        Set rpt = New rpt485
    Case Else
        Set rpt = Nothing
    End Select

exGetReport:
    Set GetReport = rpt
    Exit Function

ehGetReport:
    Screen.MousePointer = vbNormal
    MsgBox "Error " & Err.Number & " - " & Err.Description & vbCrLf & Err.Source
    Set rpt = Nothing
    Resume exGetReport
End Function



Then in your Exe do something like this:


Option Explicit

Public objReport As Object
Dim objCustDll As Object
Dim arrReportNames()

Public Sub RunReport(rpt As Object)
    Set ARV.ReportSource = rpt
   
    ARV.Zoom = -1
    Caption = rpt.Caption
End Sub


Private Sub cboReport_Click()

    If cboReport.ListIndex > -1 Then
        On Error Resume Next
        Set objCustDll = CreateObject(CStr(arrReportNames(cboReport.ListIndex)))
        If Err.Number = 0 Then
            Set objReport = objCustDll.GetReport("oReport", G_Where)
            RunReport objReport
        End If
    Else
        MsgBox "Please Select a valid report"
    End If

End Sub


0
 

Author Comment

by:Deano1121
ID: 2690604
Perfect with the exception of having to distribute a DLL (instead of the EXE) with each report .DSR file.
0
 
LVL 15

Expert Comment

by:ameba
ID: 2691393
I think I solved it FIRST.

MY *Wrapper class* satisfies your two conditions
(>without using the Case statement,
>never have to touch the client source code)
and it is the thing that solves the problem.
0

Featured Post

What Is Threat Intelligence?

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

Join & Write a Comment

Introduction While answering a recent question (http://www.experts-exchange.com/Q_27402310.html) in the VB classic zone, I wrote some VB code in the (Office) VBA environment, rather than fire up my older PC.  I didn't post completely correct code o…
Article by: Martin
Here are a few simple, working, games that you can use as-is or as the basis for your own games. Tic-Tac-Toe This is one of the simplest of all games.   The game allows for a choice of who goes first and keeps track of the number of wins for…
Get people started with the process of using Access VBA to control Excel using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Excel. Using automation, an Access application can laun…
Get people started with the utilization of class modules. Class modules can be a powerful tool in Microsoft Access. They allow you to create self-contained objects that encapsulate functionality. They can easily hide the complexity of a process from…

757 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

20 Experts available now in Live!

Get 1:1 Help Now