トップ回答者
ReportViewerで、プログラム上からPDF出力を中止するには?

質問
-
回答
-
直接出力しているということはLocalReport.RenderでPDF出力しているのでしょうか?
その場合、Renderメソッドの部分は別スレッドにしない限りキャンセルは出来ません。#しかもスレッドをAbortするしかキャンセルする方法はありません…
CancelRenderingはReportViewerコントロールの機能でレンダリングするときのみ有効です。
直接エクスポートしているならCancelRenderingは無意味です。Private Sub button1_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Button1.Click Dim exp As ExportData = New ExportData() exp.LocalReport = ReportViewer1.LocalReport exp.Path = "Test.PDF" StartExport(exp) End Sub Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click CancelExport() End Sub Private Sub StartExport(ByVal exp As ExportData) CancelExport() Dim start As New System.Threading.ParameterizedThreadStart(AddressOf ExportPDF) renderingThread = New System.Threading.Thread(start) renderingThread.IsBackground = True renderingThread.Start(exp) End Sub Private Sub CancelExport() Dim thread As System.Threading.Thread = Me.renderingThread If (thread IsNot Nothing) Then thread.Abort() thread.Join() End If Me.renderingThread = Nothing End Sub Private renderingThread As System.Threading.Thread = Nothing Friend Class ExportData Public LocalReport As Microsoft.Reporting.WinForms.LocalReport Public Path As String End Class Private Sub ExportPDF(ByVal data As Object) Dim exp As ExportData = DirectCast(data, ExportData) Try Dim warnings As Microsoft.Reporting.WinForms.Warning() = Nothing Dim bs() As Byte = exp.LocalReport.Render("PDF", String.Empty, String.Empty, String.Empty, ".pdf", Nothing, warnings) Using fs As New System.IO.FileStream(exp.Path, System.IO.FileMode.Create, System.IO.FileAccess.Write) fs.Write(bs, 0, bs.Length) End Using Catch exLP As Microsoft.Reporting.WinForms.LocalProcessingException Catch exTA As System.Threading.ThreadAbortException Finally If (System.IO.File.Exists(exp.Path)) Then System.IO.File.Delete(exp.Path) End If Me.renderingThread = Nothing End Try End Sub
- 回答としてマーク ZARAZARA 2010年8月4日 1:47
すべての返信
-
「ReportViewer、PDF、印刷、停止」といった単語で調べてみたの
ですが、見つかりませんでした。
CancelRendering で止まりませんでしたか?
ReportViewer.CancelRendering メソッド
http://msdn.microsoft.com/ja-jp/library/microsoft.reporting.winforms.reportviewer.cancelrendering(v=VS.80).aspx -
Chukiさん
返事が遅くなってすみません。
教えていただいたメゾットを元に、
1.Form1に、開始、中止ボタン(CancelRendering)
を設置
2.Form2に、ReportViewerを設置
3.Form1の開始ボタンクリックで、MDB接続、データを
抽出する。
4.ReportViewerを開き、抽出データをPDFファイルに
出力。
5.出力中、Form1の中止ボタンクリックで、PDF出力を
中止。
という流れのプログラムを作成しましたが、これだと
PDF出力が終わってから中止ボタンクリックイベントが
始まるため、意味がありません。
For ~ Next等の構文なら、途中に「Application.DoEvents()」
を入れてイベントを割り込ませることができるため、問題ないの
ですが、ReportViewerではどのように割り込ませれば良い
のでしょうか。
苦し紛れにForm2にタイマーを設置し、1秒ごとに「Application.
DoEvents()」を読むようにしてみましたが無反応でした(フォームが
違うから?)。
良い方法がございましたら、教えていただけますでしょうか。
-
実装方法に問題があるか、マルチスレッドを使うべきパターンかのいずれかだと思われますが、どういったコードを書いているか具体的に見えないため、判断できかねます。
For ~ Next等の構文なら、途中に「Application.DoEvents()」
を入れてイベントを割り込ませることができるため、問題ないの
ですがApplication.DoEvents はあくまで回避です。
たいていの場合、別のやり方で解消できるため、「問題ない」と断言しないようにしてください。苦し紛れにForm2にタイマーを設置し、1秒ごとに「Application.
DoEvents()」を読むようにしてみましたが無反応でした(フォームが
違うから?)。理由が違います。
おそらく、その印刷処理から抜けてこず、Application.DoEvents のようにメッセージを途中で処理する仕組みがないことから、それらの処理が終わるまで Tick イベントが呼び出されないのでしょう。Tick イベントや Click イベントは、メインスレッドと呼ばれるスレッドがほかの処理をしていないとき、またはメッセージを処理するための仕組みを動かしているときのみ、順番が回ってきます。(概念です。正確な表現ではありません)
現状は、処理がずっと続いているため、順番が回ってこないと考えてください。
なお、Tick イベントがくると言うことは、Application.DoEvents を改めて呼ぶ必要はありません。そのときは Click イベントもくる状態ですので。このあたりのメカニズムは、スレッドやメッセージループについて調べて学んでください。
質問スレッドで解決した場合は、解決の参考になった投稿に対して「回答としてマーク」のボタンを押すことで、同じ問題に遭遇した別のユーザが役立つ投稿を見つけやすくなります。 -
直接出力しているということはLocalReport.RenderでPDF出力しているのでしょうか?
その場合、Renderメソッドの部分は別スレッドにしない限りキャンセルは出来ません。#しかもスレッドをAbortするしかキャンセルする方法はありません…
CancelRenderingはReportViewerコントロールの機能でレンダリングするときのみ有効です。
直接エクスポートしているならCancelRenderingは無意味です。Private Sub button1_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Button1.Click Dim exp As ExportData = New ExportData() exp.LocalReport = ReportViewer1.LocalReport exp.Path = "Test.PDF" StartExport(exp) End Sub Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click CancelExport() End Sub Private Sub StartExport(ByVal exp As ExportData) CancelExport() Dim start As New System.Threading.ParameterizedThreadStart(AddressOf ExportPDF) renderingThread = New System.Threading.Thread(start) renderingThread.IsBackground = True renderingThread.Start(exp) End Sub Private Sub CancelExport() Dim thread As System.Threading.Thread = Me.renderingThread If (thread IsNot Nothing) Then thread.Abort() thread.Join() End If Me.renderingThread = Nothing End Sub Private renderingThread As System.Threading.Thread = Nothing Friend Class ExportData Public LocalReport As Microsoft.Reporting.WinForms.LocalReport Public Path As String End Class Private Sub ExportPDF(ByVal data As Object) Dim exp As ExportData = DirectCast(data, ExportData) Try Dim warnings As Microsoft.Reporting.WinForms.Warning() = Nothing Dim bs() As Byte = exp.LocalReport.Render("PDF", String.Empty, String.Empty, String.Empty, ".pdf", Nothing, warnings) Using fs As New System.IO.FileStream(exp.Path, System.IO.FileMode.Create, System.IO.FileAccess.Write) fs.Write(bs, 0, bs.Length) End Using Catch exLP As Microsoft.Reporting.WinForms.LocalProcessingException Catch exTA As System.Threading.ThreadAbortException Finally If (System.IO.File.Exists(exp.Path)) Then System.IO.File.Delete(exp.Path) End If Me.renderingThread = Nothing End Try End Sub
- 回答としてマーク ZARAZARA 2010年8月4日 1:47
-
直接出力しているということはLocalReport.RenderでPDF出力しているのでしょうか?
その場合、Renderメソッドの部分は別スレッドにしない限りキャンセルは出来ません。#しかもスレッドをAbortするしかキャンセルする方法はありません…
CancelRenderingはReportViewerコントロールの機能でレンダリングするときのみ有効です。
直接エクスポートしているならCancelRenderingは無意味です。
おっしゃるとおりで、Renderコマンドの場合ダメでした。ZARAZARAさんむだな検証時間を使わせてしまい申し訳ございませんでした。
gekkaさん、フォローありがとうございました -