トップ回答者
クリスタルレポートビューアの印刷ボタンでユーザー定義したサイズのレポートを出力したいです

質問
-
いつもお世話になっています。
今回、私では問題が解決できないため、質問されて頂きました
解決方法をご存じの方がいれば、お助け願います。開発言語:VB.Net FrameWork4.0
帳票ツール:クリスタルレポート
OS:Windouws7クラサバのシステムです。
プリンターの用紙サイズに存在しない用紙で帳票を作成するため
プリンターに横180mm 縦114mmの用紙を追加しました。
クリスタルレポートのページ設定にもユーザー定義サイズとして
上記のサイズを設定し、製造を行っております上記のレポートをプリントダイアログを経由し印刷を行った場合は
正しく印刷ができたのですが、クリスタルレポートビューアに表示
した後、ビューアにある印刷ボタンをクリックし、ユーザー定義したプリンターの詳細を確認すると、
用紙の向きは設定値が正しくセットされているのですが、
用紙サイズがLetterになってしまい定義したサイズが正しく設定されていません。どなたか解決方法をご存じないでしょうか?
ビューアを経由していないソース
Dim rpt As New CrystalReport1()
Dim pdlg As New PrintDialog
pdlg.PrinterSettings = New PrinterSettings()
pdlg.PrinterSettings.PrinterName = "ユーザー定義を追加したプリンター名"
If pdlg.ShowDialog() = DialogResult.OK Then
rpt.PrintOptions.PrinterName = pdlg.PrinterSettings.PrinterName
rpt.PrintOptions.PaperOrientation = CrystalDecisions.Shared.PaperOrientation.Landscape
rpt.PrintOptions.PaperSize = CrystalDecisions.Shared.PaperSize.DefaultPaperSize
rpt.PrintToPrinter(pdlg.PrinterSettings.Copies, True, 0, 0)
End Ifビューアを経由するソース
Dim rpt As New CrystalReport1()
Dim frmPreview1 As New frmPreview’クリスタルレポートビューアがあるフォーム
rpt.PrintOptions.PrinterName = "ユーザー定義を追加したプリンター名"
rpt.PrintOptions.PaperOrientation = CrystalDecisions.Shared.PaperOrientation.Landscape
rpt.PrintOptions.PaperSize = CrystalDecisions.Shared.PaperSize.DefaultPaperSize
'プレビューを表示(crvがクリスタルレポートビューアです)
frmPreview1.crv.ReportSource = rpt
frmPreview1.crv.Zoom(2)
frmPreview1.WindowState = FormWindowState.Maximized
frmPreview1.ShowDialog()- 編集済み Ninichi 2013年1月29日 10:56
回答
-
ビューアにある印刷ボタンを押下した時に実行されるイベントやメソッド
を調査してオーバーライド出来れば、なんとかなりそうな気がします。ビュアーからカスタム用紙を印刷するのに、印刷ボタンの機能を入れ替えてやったことがあります。
ビュアー内部のツールバーのボタンだったので、元の印刷ボタンを非表示にして別の印刷ボタンを挿入してやりました。また、カスタム用紙の選択はReportDocument.PrintOptions.PageContentHeight/Width , PageMarginsから用紙寸法を計算して、実行環境の用紙一覧から(だいたい)一致する用紙を設定してやる方法をとりました。
昔のバージョンでやったので、最新のCrystalReportでできるかはわかりませんが。
個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)
- 回答としてマーク Ninichi 2013年1月31日 0:48
-
私がやったビュアーのカスタマイズ方法が掲載されているサイトは知りません。
"defaultAnimation.gif"がありませんというエラーメッセージが
表示され、フォームにカスタマイズしたビューアを配置すること
すらできません。VS2008pro付属のだとエラーにならないのですが、Crystal Reports For .NetFramework 4.0だとエラーになりますね。
調べてみたところ、初期化時にクラスが配置されているアセンブリ内のリソースからDefaultAnimation.gifを取り出しているようです。継承した場合、継承クラスが配置されているアセンブリ内のリソースを探してしまい、存在しないためにエラーになっています。
ですから、継承したうえで回避するには、継承したクラスのアセンブリにDefaultAnimation.gifという画像ファイル(読み込み中にぐるぐる回っているgifアニメ)を「埋め込まれたリソース」として含めてやることで可能になります。
(new Bitmap(GetType(継承クラス),"DefaultAnimation.gif")でリソースが取れる状態にする)継承しなくても以下のコードで印刷ボタンを乗っ取れることは確認しました。
Imports CrystalDecisions.Shared Imports CrystalDecisions.CrystalReports.Engine Imports CrystalDecisions.Windows.Forms Public Class Form1 Sub New() ' この呼び出しはデザイナーで必要です。 InitializeComponent() ' InitializeComponent() 呼び出しの後で初期化を追加します。 crvex = New CrystalReportViewerEx(Me.CrystalReportViewer1) End Sub Private crvex As CrystalReportViewerEx End Class Public Class CrystalReportViewerEx 'Inherits CrystalReportViewer '元のCrystalReportViewerに継承できないバグがあるので 'Public Sub New() ' MyBase.New() ' ReplacePrintButton(Me) ' '以下のコードがでリソースが取れない場合は継承したクラスは使い物になりません。 ' Dim t As Type ' t = GetType(CrystalReportViewerEx) ' Dim manifestResourceStream As System.IO.Stream = t.Assembly.GetManifestResourceStream(t, "DefaultAnimation.gif") 'End Sub Public Sub New(ByVal target As CrystalReportViewer) baseCrystalReportViewer = target ReplacePrintButton(target) End Sub Private baseCrystalReportViewer As CrystalReportViewer Private basePrintButton As ToolStripItem Private thisPrintButton As ToolStripButton Private Sub ReplacePrintButton(ByVal target As CrystalReportViewer) Dim baseToolstrip As ToolStrip baseToolstrip = FindControl(Of ToolStrip)(target) If (baseToolstrip IsNot Nothing) Then For Each item As ToolStripItem In baseToolstrip.Items If (item.ToolTipText.Contains("印刷") OrElse item.ToolTipText.Contains("Print")) Then basePrintButton = item thisPrintButton = New ToolStripButton() thisPrintButton.Text = item.Text thisPrintButton.Image = item.Image thisPrintButton.Size = item.Size thisPrintButton.Padding = item.Padding thisPrintButton.Margin = item.Margin thisPrintButton.DisplayStyle = item.DisplayStyle thisPrintButton.ImageScaling = item.ImageScaling thisPrintButton.ForeColor = item.ForeColor thisPrintButton.BackColor = item.BackColor thisPrintButton.ToolTipText = item.ToolTipText thisPrintButton.AccessibleName = item.AccessibleName thisPrintButton.Tag = item.Tag AddHandler thisPrintButton.Click, AddressOf thisPrintButton_Click Dim index As Integer index = baseToolstrip.Items.IndexOf(basePrintButton) baseToolstrip.Items.Insert(index, thisPrintButton) 'baseToolstrip.Items.Remove(basePrintButton) basePrintButton.Visible = False Exit For End If Next End If End Sub Private Sub thisPrintButton_Click(ByVal sender As Object, ByVal e As EventArgs) MessageBox.Show("印刷") 'baseCrystalReportViewer.PrintReport() End Sub Private Function FindControl(Of T As Control)(ByVal ctl As Control) As T If (TypeOf ctl Is T) Then Return CType(ctl, T) End If Dim retval As T = Nothing For Each child As Control In ctl.Controls System.Diagnostics.Debug.Print(child.GetType().ToString()) retval = FindControl(Of T)(child) If (retval IsNot Nothing) Then Exit For End If Next Return retval End Function End Class
個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)
- 回答としてマーク Ninichi 2013年1月31日 4:15
すべての返信
-
プリントダイアログ経由だとWindowsがプリンターを理解しているので、正しく用紙が選べるのかもしれませんね。一方、CrystalReprotViewer経由ですと、CrystalReport内で判断しなければならず、判断するための情報が足りないのかもしれません。とりあえず、以下辺りが参考になるかもしれません。
Crystal Reports でユーザー設定用紙の印刷を行う場合。
http://garfie.weblogs.jp/life_of_dev/crystal-report-2008/Programming: Crystal report custom papersize printout
http://www.infoct.net/programming-crystal-report-custom-papersize-printout-121/custom paper size cannot be used on other machine?
http://go4answers.webhost4life.com/Example/custom-paper-size-other-machine-29071.aspx★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/
-
trapemiyaさん
返信ありがとうございますhttp://garfie.weblogs.jp/life_of_dev/crystal-report-2008/
のサイトはここに書込む前に試したのですが、用紙サイズは
Letterのままでした。
また、以前に似たような質問があり、そこでも結論として
用紙サイズの問題は解決されませんでした。もう少し、違う方法を模索してみます。
ビューアにある印刷ボタンを押下した時に実行されるイベントやメソッド
を調査してオーバーライド出来れば、なんとかなりそうな気がします。ありがとうございました
- 編集済み Ninichi 2013年1月30日 2:51
-
ビューアにある印刷ボタンを押下した時に実行されるイベントやメソッド
を調査してオーバーライド出来れば、なんとかなりそうな気がします。ビュアーからカスタム用紙を印刷するのに、印刷ボタンの機能を入れ替えてやったことがあります。
ビュアー内部のツールバーのボタンだったので、元の印刷ボタンを非表示にして別の印刷ボタンを挿入してやりました。また、カスタム用紙の選択はReportDocument.PrintOptions.PageContentHeight/Width , PageMarginsから用紙寸法を計算して、実行環境の用紙一覧から(だいたい)一致する用紙を設定してやる方法をとりました。
昔のバージョンでやったので、最新のCrystalReportでできるかはわかりませんが。
個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)
- 回答としてマーク Ninichi 2013年1月31日 0:48
-
私がやったビュアーのカスタマイズ方法が掲載されているサイトは知りません。
"defaultAnimation.gif"がありませんというエラーメッセージが
表示され、フォームにカスタマイズしたビューアを配置すること
すらできません。VS2008pro付属のだとエラーにならないのですが、Crystal Reports For .NetFramework 4.0だとエラーになりますね。
調べてみたところ、初期化時にクラスが配置されているアセンブリ内のリソースからDefaultAnimation.gifを取り出しているようです。継承した場合、継承クラスが配置されているアセンブリ内のリソースを探してしまい、存在しないためにエラーになっています。
ですから、継承したうえで回避するには、継承したクラスのアセンブリにDefaultAnimation.gifという画像ファイル(読み込み中にぐるぐる回っているgifアニメ)を「埋め込まれたリソース」として含めてやることで可能になります。
(new Bitmap(GetType(継承クラス),"DefaultAnimation.gif")でリソースが取れる状態にする)継承しなくても以下のコードで印刷ボタンを乗っ取れることは確認しました。
Imports CrystalDecisions.Shared Imports CrystalDecisions.CrystalReports.Engine Imports CrystalDecisions.Windows.Forms Public Class Form1 Sub New() ' この呼び出しはデザイナーで必要です。 InitializeComponent() ' InitializeComponent() 呼び出しの後で初期化を追加します。 crvex = New CrystalReportViewerEx(Me.CrystalReportViewer1) End Sub Private crvex As CrystalReportViewerEx End Class Public Class CrystalReportViewerEx 'Inherits CrystalReportViewer '元のCrystalReportViewerに継承できないバグがあるので 'Public Sub New() ' MyBase.New() ' ReplacePrintButton(Me) ' '以下のコードがでリソースが取れない場合は継承したクラスは使い物になりません。 ' Dim t As Type ' t = GetType(CrystalReportViewerEx) ' Dim manifestResourceStream As System.IO.Stream = t.Assembly.GetManifestResourceStream(t, "DefaultAnimation.gif") 'End Sub Public Sub New(ByVal target As CrystalReportViewer) baseCrystalReportViewer = target ReplacePrintButton(target) End Sub Private baseCrystalReportViewer As CrystalReportViewer Private basePrintButton As ToolStripItem Private thisPrintButton As ToolStripButton Private Sub ReplacePrintButton(ByVal target As CrystalReportViewer) Dim baseToolstrip As ToolStrip baseToolstrip = FindControl(Of ToolStrip)(target) If (baseToolstrip IsNot Nothing) Then For Each item As ToolStripItem In baseToolstrip.Items If (item.ToolTipText.Contains("印刷") OrElse item.ToolTipText.Contains("Print")) Then basePrintButton = item thisPrintButton = New ToolStripButton() thisPrintButton.Text = item.Text thisPrintButton.Image = item.Image thisPrintButton.Size = item.Size thisPrintButton.Padding = item.Padding thisPrintButton.Margin = item.Margin thisPrintButton.DisplayStyle = item.DisplayStyle thisPrintButton.ImageScaling = item.ImageScaling thisPrintButton.ForeColor = item.ForeColor thisPrintButton.BackColor = item.BackColor thisPrintButton.ToolTipText = item.ToolTipText thisPrintButton.AccessibleName = item.AccessibleName thisPrintButton.Tag = item.Tag AddHandler thisPrintButton.Click, AddressOf thisPrintButton_Click Dim index As Integer index = baseToolstrip.Items.IndexOf(basePrintButton) baseToolstrip.Items.Insert(index, thisPrintButton) 'baseToolstrip.Items.Remove(basePrintButton) basePrintButton.Visible = False Exit For End If Next End If End Sub Private Sub thisPrintButton_Click(ByVal sender As Object, ByVal e As EventArgs) MessageBox.Show("印刷") 'baseCrystalReportViewer.PrintReport() End Sub Private Function FindControl(Of T As Control)(ByVal ctl As Control) As T If (TypeOf ctl Is T) Then Return CType(ctl, T) End If Dim retval As T = Nothing For Each child As Control In ctl.Controls System.Diagnostics.Debug.Print(child.GetType().ToString()) retval = FindControl(Of T)(child) If (retval IsNot Nothing) Then Exit For End If Next Return retval End Function End Class
個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)
- 回答としてマーク Ninichi 2013年1月31日 4:15