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.ReportApp Server.Com mLayer.InP rocAdapter MonitorCla ss.GetConc urrentJobC ount()
at CrystalDecisions.CrystalRe ports.Engi ne.ReportD ocument.Ge tConcurren tUsage()
at CrystalDecisions.CrystalRe ports.Engi ne.ReportD ocument.Ch eckLicense Status()
at CrystalDecisions.CrystalRe ports.Engi ne.ReportD ocument.Lo ad(String filename, OpenReportMethod openMethod, Int16 parentJob)
at CrystalDecisions.CrystalRe ports.Engi ne.ReportD ocument.Lo ad(String filename)
at ReportExecute_CR11.frmRtEx eEngine.Ru nTaskInter nal(Connec tion Conn, Boolean IsTrx) in C:\Local Projects\ReportExecute_CR1 1\frmRtExe Engine.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.CrystalRe ports.Engi ne, 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.PortableD ocFormat
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
Object reference not set to an instance of an object.
at CrystalDecisions.ReportApp
at CrystalDecisions.CrystalRe
at CrystalDecisions.CrystalRe
at CrystalDecisions.CrystalRe
at CrystalDecisions.CrystalRe
at ReportExecute_CR11.frmRtEx
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.CrystalRe
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.PortableD
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
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$\test report1.rp t"
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.adOpe nForwardOn ly, ADODB.LockTypeEnum.adLockR eadOnly)
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$\Inte rnal\" & RtFolder & RtName
End 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,
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$\Inte
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
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
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.
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
frodoman
ASKER
i've tested the return value of the getLocation function and it points to the correct files each time through.
ASKER
is there some way i need to validate licenses or something? when i check on the ReportDocument.GetConcurre ntJobUsage () 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
mlmcc
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
mlmcc
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.WaitingFor NewTasks
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_i d WHERE report_task.task_id = '" & CurrentTaskID & "'", Conn, ADODB.CursorTypeEnum.adOpe nForwardOn ly, ADODB.LockTypeEnum.adLockR eadOnly)
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_ty pe")).Trim .ToLower
Case "internal"
RunTaskInternal(Conn)
Case "external"
RunTaskExternal(Conn)
End Select
End If 'checknull(rsTasks("proces s_id")) <> ProcessStatus.Waiting
End If
rsTasks.Close()
Conn.Close()
End Sub
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.WaitingFor
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,
If Not rsTasks.EOF Then
If CheckNull(rsTasks("process
'run appropriate procedure
Select Case CheckNull(rsTasks("item_ty
Case "internal"
RunTaskInternal(Conn)
Case "external"
RunTaskExternal(Conn)
End Select
End If 'checknull(rsTasks("proces
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
If you are trying to run the reports through several subtasks you may be running into a licensing issue.
mlmcc
ASKER
it will run the reports one at a time. it will pick up one task, finish it, and then do another.
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.
- 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
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
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).
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.recordselec tionformul a 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.
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
frodoman
ASKER
yea i agree with you on that. thanks for the help guys.
ASKER
hey guys,
just wanted to keep this thread alive. was wondering if there was any luck with this?
just wanted to keep this thread alive. was wondering if there was any luck with this?
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
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
mlmcc