abbarnes
asked on
Progress bar for Crystal Reports
I was wondering if anyone had any ideas on how to put a progress bar on the screen when a crystal report is generating. I have tried creating a form with a progress bar on it, but, the report takes focus and there is no event to close the form as far as I can tell. Some of our users are quite click-happy when nothing is happening on the screen, which there are some reports that take a while to run.
Thanks for your help
Thanks for your help
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
mlmcc - We are using Crystal for .Net 2.0 in Visual Studio 2005.
IdoMillet - I don't see an "IsBusy" property of the viewer.
If I could just put something in front of the Crystal Viewer for a few seconds, it would be fine - it seems to take focus no matter what. Here is a snippet of code, I was trying to run the progress form in a different thread to see if it made a difference:
......
Dim th As Thread = New Thread(AddressOf ShowProgress)
th.Start()
fr.oRpt = oRpt
fr.ShowDialog()
fr.Visible = False
...........
Private Sub ShowProgress()
If Not fg Is Nothing Then
If Not fg.IsDisposed Then
fg.BringToFront() : fg.Show()
Else
fg = New frmGenerate : fg.Show()
End If
Else
fg = New frmGenerate : fg.Show()
End If
End Sub
Public Class frmViewReport
Public oRpt As CrystalDecisions.CrystalRe ports.Engi ne.ReportD ocument
Private Sub frmViewReport_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
crv1.ReportSource = oRpt
End Sub
End Class
IdoMillet - I don't see an "IsBusy" property of the viewer.
If I could just put something in front of the Crystal Viewer for a few seconds, it would be fine - it seems to take focus no matter what. Here is a snippet of code, I was trying to run the progress form in a different thread to see if it made a difference:
......
Dim th As Thread = New Thread(AddressOf ShowProgress)
th.Start()
fr.oRpt = oRpt
fr.ShowDialog()
fr.Visible = False
...........
Private Sub ShowProgress()
If Not fg Is Nothing Then
If Not fg.IsDisposed Then
fg.BringToFront() : fg.Show()
Else
fg = New frmGenerate : fg.Show()
End If
Else
fg = New frmGenerate : fg.Show()
End If
End Sub
Public Class frmViewReport
Public oRpt As CrystalDecisions.CrystalRe
Private Sub frmViewReport_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
crv1.ReportSource = oRpt
End Sub
End Class
At least with the RDC, the code is
While CRViewer1.IsBusy
...
While CRViewer1.IsBusy
...
ASKER
The only options that I see for the crystal report viewer are IsAccessible and IsDisposed. IdoMillet are you using the crystal viewer that comes with VS 2005?
No, I'm using the RDC. I assume IsDisposed is the equivalent call in VS 2005.
Here is some helpful information that I found on the SAP Community Network that helped me come up with a work around to show that it is still working on generating my report.
The info below is what I copied from https://forums.sdn.sap.com /thread.js pa?threadI D=1112190
******** Start of copied info *******
The following sample code demonstrates how to retrieve the number of pages from your 'ReportDocument' object. Assuming that your 'ReportDocument object' is called 'crReport', use the following VB.NET code to return the number of pages in a report:
====================
NOTE:
Logon and parameter field values must be provided prior to executing this code.
====================
Dim nPages as Integer
nPages = crReport.FormatEngine.GetL astPageNum ber(New CrystalDecisions.Shared.Re portPageRe questConte xt)
******** End of copied info *******
Below is an example of my code in a vb.net application:'****** Code for frmReportViewer Class (My Windows form that contains the CrystalReportViewer1 control)******
Imports CrystalDecisions.CrystalRe ports.Engi ne
Imports CrystalDecisions.Shared
Public Class frmReportViewer
Private WithEvents rs As New clsReportStatus
Private Delegate Sub BarUpdate(ByVal val As Integer)
Private Delegate Sub ChangeCursor(ByVal myCursor As Windows.Forms.Cursor)
Private Delegate Sub ctrlVisible(ByVal meVisible As Boolean)
Private Sub Report_ProgressBarValue(By Val val As Integer) Handles rs.ProgressBarValue
Try
If Me.InvokeRequired Then
Dim bu As New BarUpdate(AddressOf Me.Report_ProgressBarValue )
Me.Invoke(bu, New Object() {val})
Else
ProgressBar1.Value = val
End If
Catch ex As Exception
MessageBox.Show(ex.Message )
End Try
End Sub
Private Sub Report_ctrlVisible(ByVal meVisible As Boolean) Handles rs.ctrlVisible
Try
If Me.InvokeRequired Then
Dim lv As New ctrlVisible(AddressOf Me.Report_ctrlVisible)
Me.Invoke(lv, New Object() {meVisible})
Else
lblWait.Visible = meVisible
ProgressBar1.Visible = meVisible
End If
Catch ex As Exception
MessageBox.Show(ex.Message )
End Try
End Sub
Private Sub Report_mCursor(ByVal myCursor As Windows.Forms.Cursor) Handles rs.mCursor
Try
If Me.InvokeRequired Then
Dim mc As New ChangeCursor(AddressOf Me.Report_mCursor)
Me.Invoke(mc, New Object() {myCursor})
Else
Cursor = myCursor
End If
Catch ex As Exception
MessageBox.Show(ex.Message )
End Try
End Sub
Private Sub frmReportViewer_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Try
If Not rs.Running Then
rs.StartThread()
End If
Application.DoEvents()
Dim nPages As Integer
Dim rep As New ReportDocument
rep = Me.CrystalReportViewer1.Re portSource
Me.Show()
Application.DoEvents()
'Here is where I inserted the line from the SAP Community Network forum
nPages = rep.FormatEngine.GetLastPa geNumber(N ew CrystalDecisions.Shared.Re portPageRe questConte xt)
rs.StopThread()
Catch ex As Exception
rs.StopThread()
MessageBox.Show(ex.Message )
End Try
End Sub
End Class
'****** Code for clsReportStatus Class ******
Public Class clsReportStatus
Public Event ProgressBarValue(ByVal val As Integer)
Public Event ctrlVisible(ByVal v As Boolean)
Public Event mCursor(ByVal myCursor As Windows.Forms.Cursor)
Private t As System.Threading.Thread
Private aborting As Boolean = True
Public ReadOnly Property Running() As Boolean
Get
Return Not aborting
End Get
End Property
Public Sub StartThread()
If aborting Then
aborting = False
t = New System.Threading.Thread(Ad dressOf ReportStatus)
t.Start()
End If
End Sub
Public Sub StopThread()
aborting = True
End Sub
Private Sub ReportStatus()
Try
Dim intPos As Integer = 0
RaiseEvent mCursor(Cursors.WaitCursor )
RaiseEvent ProgressBarValue(intPos)
RaiseEvent ctrlVisible(True)
Do Until Not Me.Running
'Do Until intPos = 100
RaiseEvent ProgressBarValue(intPos)
System.Threading.Thread.Sl eep(300)
If intPos < 100 Then
intPos = intPos + 1
Else
intPos = 1
End If
Application.DoEvents()
Loop
RaiseEvent ProgressBarValue(100)
System.Threading.Thread.Sl eep(1000)
RaiseEvent ctrlVisible(False)
RaiseEvent mCursor(Cursors.Default)
Catch ex As Exception
RaiseEvent mCursor(Cursors.Default)
MessageBox.Show(ex.Message )
RaiseEvent ctrlVisible(False)
Me.StopThread()
End Try
End Sub
End Class
The info below is what I copied from https://forums.sdn.sap.com
******** Start of copied info *******
The following sample code demonstrates how to retrieve the number of pages from your 'ReportDocument' object. Assuming that your 'ReportDocument object' is called 'crReport', use the following VB.NET code to return the number of pages in a report:
====================
NOTE:
Logon and parameter field values must be provided prior to executing this code.
====================
Dim nPages as Integer
nPages = crReport.FormatEngine.GetL
******** End of copied info *******
Below is an example of my code in a vb.net application:'****** Code for frmReportViewer Class (My Windows form that contains the CrystalReportViewer1 control)******
Imports CrystalDecisions.CrystalRe
Imports CrystalDecisions.Shared
Public Class frmReportViewer
Private WithEvents rs As New clsReportStatus
Private Delegate Sub BarUpdate(ByVal val As Integer)
Private Delegate Sub ChangeCursor(ByVal myCursor As Windows.Forms.Cursor)
Private Delegate Sub ctrlVisible(ByVal meVisible As Boolean)
Private Sub Report_ProgressBarValue(By
Try
If Me.InvokeRequired Then
Dim bu As New BarUpdate(AddressOf Me.Report_ProgressBarValue
Me.Invoke(bu, New Object() {val})
Else
ProgressBar1.Value = val
End If
Catch ex As Exception
MessageBox.Show(ex.Message
End Try
End Sub
Private Sub Report_ctrlVisible(ByVal meVisible As Boolean) Handles rs.ctrlVisible
Try
If Me.InvokeRequired Then
Dim lv As New ctrlVisible(AddressOf Me.Report_ctrlVisible)
Me.Invoke(lv, New Object() {meVisible})
Else
lblWait.Visible = meVisible
ProgressBar1.Visible = meVisible
End If
Catch ex As Exception
MessageBox.Show(ex.Message
End Try
End Sub
Private Sub Report_mCursor(ByVal myCursor As Windows.Forms.Cursor) Handles rs.mCursor
Try
If Me.InvokeRequired Then
Dim mc As New ChangeCursor(AddressOf Me.Report_mCursor)
Me.Invoke(mc, New Object() {myCursor})
Else
Cursor = myCursor
End If
Catch ex As Exception
MessageBox.Show(ex.Message
End Try
End Sub
Private Sub frmReportViewer_Load(ByVal
Try
If Not rs.Running Then
rs.StartThread()
End If
Application.DoEvents()
Dim nPages As Integer
Dim rep As New ReportDocument
rep = Me.CrystalReportViewer1.Re
Me.Show()
Application.DoEvents()
'Here is where I inserted the line from the SAP Community Network forum
nPages = rep.FormatEngine.GetLastPa
rs.StopThread()
Catch ex As Exception
rs.StopThread()
MessageBox.Show(ex.Message
End Try
End Sub
End Class
'****** Code for clsReportStatus Class ******
Public Class clsReportStatus
Public Event ProgressBarValue(ByVal val As Integer)
Public Event ctrlVisible(ByVal v As Boolean)
Public Event mCursor(ByVal myCursor As Windows.Forms.Cursor)
Private t As System.Threading.Thread
Private aborting As Boolean = True
Public ReadOnly Property Running() As Boolean
Get
Return Not aborting
End Get
End Property
Public Sub StartThread()
If aborting Then
aborting = False
t = New System.Threading.Thread(Ad
t.Start()
End If
End Sub
Public Sub StopThread()
aborting = True
End Sub
Private Sub ReportStatus()
Try
Dim intPos As Integer = 0
RaiseEvent mCursor(Cursors.WaitCursor
RaiseEvent ProgressBarValue(intPos)
RaiseEvent ctrlVisible(True)
Do Until Not Me.Running
'Do Until intPos = 100
RaiseEvent ProgressBarValue(intPos)
System.Threading.Thread.Sl
If intPos < 100 Then
intPos = intPos + 1
Else
intPos = 1
End If
Application.DoEvents()
Loop
RaiseEvent ProgressBarValue(100)
System.Threading.Thread.Sl
RaiseEvent ctrlVisible(False)
RaiseEvent mCursor(Cursors.Default)
Catch ex As Exception
RaiseEvent mCursor(Cursors.Default)
MessageBox.Show(ex.Message
RaiseEvent ctrlVisible(False)
Me.StopThread()
End Try
End Sub
End Class
What version of Crystal?
mlmcc