Link to home
Start Free TrialLog in
Avatar of jpramik
jpramik

asked on

Crystal 9 to Crystal Reports 11 Developer (with VB.net) - ReportDocument.Load/GetConncurrentJobCount Error

I recently upgraded from Crystal 9 Reports to Crystal 11 Developer. I run a series of different Crystal Reports through this application by looping through and calling a private sub procedure. The first report always runs correctly but any following reports fails with the following error:
Object reference not set to an instance of an object.
   at CrystalDecisions.ReportAppServer.CommLayer.InProcAdapterMonitorClass.GetConcurrentJobCount()
   at CrystalDecisions.CrystalReports.Engine.ReportDocument.GetConcurrentUsage()
   at CrystalDecisions.CrystalReports.Engine.ReportDocument.CheckLicenseStatus()
   at CrystalDecisions.CrystalReports.Engine.ReportDocument.Load(String filename, OpenReportMethod openMethod, Int16 parentJob)
   at CrystalDecisions.CrystalReports.Engine.ReportDocument.Load(String filename)
   at ReportExecute_CR11.frmRtExeEngine.RunTaskInternal(Connection Conn, Boolean IsTrx) in C:\Local Projects\ReportExecute_CR11\frmRtExeEngine.vb:line 932 'this is where i call reportdocument.load()

I've changed the order of the reports and still only the first report runs. I am guessing this is some kind of licensing issue, but can't figure it out, as Crystal 11 Developer says it comes with 5 concurrent licenses. The DLL's I reference are CrystalDecisions.CrystalReports.Engine, CrystalDecisions.Shared, and CrystalDecisions.KeyCode. I do not have Report App Server. I call the below method (which i've simplified for readability) in a loop to finish the reports. This function works correctly with Crystal 8 and 9.

    Private Sub RunTaskInternal(ByVal Conn As ADODB.Connection, Optional ByVal IsTrx As Boolean = False)
        'dim vars
        Dim Rt As New ReportDocument
        Dim rtName As String
        'OUTPUT
        Dim XFT As ExportFormatType = ExportFormatType.PortableDocFormat


            Rt.Load(GetLocation()) 'This is where the error occurs AFTER the first time i call RunTaskInternal()

            'GET PARAMS
          LoadParams()

          'Load Permissions for tables
            LoadSecurity()

            Rt.ExportToDisk(XFT, GetFileLocation())

            Rt.Dispose()
          Rt.Close()
            Rt = Nothing
 
    End Sub
Avatar of Mike McCracken
Mike McCracken

What does GetLocation do?

mlmcc
Avatar of jpramik

ASKER

it gets the file location of the specific .rpt file. its really a "GetLocation(ID as integer) As String". i pass in an Key ID for our internal table which holds the Reports Location. it looks it up and returns the file location - such as "\\theserver\reports$\testreport1.rpt"
Avatar of jpramik

ASKER

Here is the getLocation() function
 
   Private Function GetLocation(ByVal RtID As Integer, ByVal Conn As ADODB.Connection) As String
        Dim rs As New ADODB.Recordset
        Dim RtFolder As String = ""
        Dim rtName as string  = ""

        'GET FOLDER/NAME
        rs.Open("SELECT report_folder.folder_name, report_list.report_name FROM report_list INNER JOIN report_folder ON report_list.folder_id = report_folder.folder_id WHERE report_list.process_id <> 99 AND report_list.report_id = '" & RtID & "'", Conn, ADODB.CursorTypeEnum.adOpenForwardOnly, ADODB.LockTypeEnum.adLockReadOnly)
       If Not rs.eof
             RtFolder = CheckNull(rs("folder_name"))
             RtName = CheckNull(rs("report_name"))
             rs.Close()
       End If
        If RtFolder.Trim <> "" Then
            RtFolder &= "\"
        End If

        'load the crystal file
        Return "\\ourserver\reports$\Internal\" & RtFolder & RtName
    End Function
Sounds like it could be a concurrent process (licensing) issue.  Crystal doesn't always release the license immediately so you could be running into that problem.

You might want to try only creating RT once and just reloading it each time through the loop (instead of creating and destroying it over an over).  This *may* force Crystal to reuse the same licensed connection instead of creating new ones for every report.

frodoman
Avatar of jpramik

ASKER

i've tried creating "Rt" only once and just reloading it each time through and I get the same error at the same location.
Avatar of jpramik

ASKER

also, i'm running reports that were created with crystal 11.
Have you tested the results of your getlocation function?  It could be a bug that it causing that function not to execute as expected the 2nd time through (or perhaps that causes the parameters going into the function to be wrong).  That would give you the object instance error message that you're seeing.

frodoman
Avatar of jpramik

ASKER

i've tested the return value of the getLocation function and it points to the correct files each time through.
Avatar of jpramik

ASKER

is there some way i need to validate licenses or something? when i check on the ReportDocument.GetConcurrentJobUsage() value throughout the procedure, its always equal to 0 (before and after i load it, before and after i add parameters and logon info). the second time it errors out when i check on it with the same error as discussed before.
DO you need to close the recordset in the GetLocation function?

mlmcc
Avatar of jpramik

ASKER

good point. i've tried this to no avail though.
How are you looping through the list of reports?  The code seems to only do a single report or am I missing something?

mlmcc
Avatar of jpramik

ASKER

here is how i loop through the reports. A procedure - "Execute()" goes through a list of report-related tasks, finds if any need to be run, and then runs them. "Execute()" will call "RunTask()" when a task needs to be run. "RunTask()" will parse through the data linked to this task and run the appropriate procedure to finish the report. One of the possible procedures is RunTaskInternal() which is mentioned in the top-most post.
 
   Public Sub Execute()
        AddTasks()
        LoadLsvTask()
        Dim iSelect As Integer

        Dim t As Thread
        Do Until ContinueRunning = False
            'LoadLsvTask()
            Application.DoEvents()
            If TasksWaiting() = True Then
                AppMode = ApplicationMode.Running

                'pick new task
                iSelect = SelectTask()
                If iSelect <> -1 Then
                    CurrentTaskID = iSelect

                    'run task
                    t = New Thread(AddressOf RunTask)
                    t.Name = "Task " & CurrentTaskID
                    t.Start()
                    Do Until t.IsAlive = False
                        Thread.Sleep(100)
                        Application.DoEvents()
                    Loop
                    t.Join()
                    t = Nothing
                    OutputLine("")
                End If
            Else
                'set application notify icon to waiting
                AppMode = ApplicationMode.WaitingForNewTasks
                Exit Do
            End If
            Application.DoEvents()

        Loop
        Application.DoEvents()
    End Sub


    Public Sub RunTask()
        If CurrentTaskID = -1 Then Exit Sub
        Dim rsTasks As New ADODB.Recordset
        Dim IsInternal As Boolean
        Dim Conn As New ADODB.Connection
        Dim iP As InternalProcessor


        OpenConnection(Conn)

        rsTasks.Open("SELECT scheduled_items.item_type, report_task.process_id, scheduled_items.entry_by FROM report_task LEFT JOIN scheduled_items ON report_task.schedule_id = scheduled_items.schedule_id WHERE report_task.task_id = '" & CurrentTaskID & "'", Conn, ADODB.CursorTypeEnum.adOpenForwardOnly, ADODB.LockTypeEnum.adLockReadOnly)
        If Not rsTasks.EOF Then
            If CheckNull(rsTasks("process_id")) = ProcessStatus.Waiting Or CheckNull(rsTasks("process_id")) = ProcessStatus.NextInQueue Then
                'run appropriate procedure
                Select Case CheckNull(rsTasks("item_type")).Trim.ToLower
                    Case "internal"
                        RunTaskInternal(Conn)
                    Case "external"
                        RunTaskExternal(Conn)
                End Select
            End If 'checknull(rsTasks("process_id")) <> ProcessStatus.Waiting
        End If
        rsTasks.Close()
        Conn.Close()
    End Sub
Is this attempting to spawn tasks and run the reports simultaneously?  or is it simply waiting for a task to be needed then it runs the reports 1 at a time.

If you are trying to run the reports through several subtasks you may be running into a licensing issue.

mlmcc
Avatar of jpramik

ASKER

it will run the reports one at a time. it will pick up one task, finish it, and then do another.
Avatar of jpramik

ASKER

based on frodoman's earlier comment:
- sounds like it could be a concurrent process (licensing) issue.  Crystal doesn't always release the license immediately so you could be running into that problem.

i've tried waiting 3 minutes in between jobs as well, but it didnt help.
In an attempt to narrow this down, can you try changing this line of code:

   Rt.Load(GetLocation())

And instead of using your GetLocation function, just hardcode a specific report so it'll be process several times in sequence?  If it works we'll know that the problem centers around the function and if it doesn't we'll eliminate that as a potential root cause.

frodoman
Avatar of jpramik

ASKER

good idea. i've gotten rid of the getlocation() function and use a constant instead (and use the appropriate parameters for the report referred to in the constant when i load the parameters), and the same error is still occuring at the same location, (after the first run through finishes successfully).
Avatar of jpramik

ASKER

when i call reportdocument.load(), catch the exception, and go through its properties on the watch window it looks like it reportdocument.load() did work. i see everything looks like it loaded up: reportdocument.isloaded = true, the reportdocument.recordselectionformula is correct and so forth.

however, certain methods such as getconcurrentusage() returns the aforementioned error. and i'm not getting the "load report fails" error message which i usually get if the report isn't loaded correctly.
Okay, I think we've isolated it down to the fact that it is some type of concurrent processing problem - whether it's licensing issue or server overload, etc.  I don't have a solution for you right now but I'll do some digging when I have a chance and let you know if I can find anything that might be helpful.

frodoman
Avatar of jpramik

ASKER

yea i agree with you on that. thanks for the help guys.
Avatar of jpramik

ASKER

hey guys,
just wanted to keep this thread alive. was wondering if there was any luck with this?
Avatar of jpramik

ASKER

i have fixed this issue myself. i created a new project from scratch using almost the exact same code as before, but excluded referencing crystal's keycode.dll and i now use crystal components exclusively in a separate class.
No objection - frodoman
ASKER CERTIFIED SOLUTION
Avatar of DarthMod
DarthMod
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial