2008年7月15日火曜日

VB2005 PrintDocument データ表示

PrintDocumentにデータベースからデータを取得して表示する場合は少し工夫がいるらしいということでまとめてみました。(SQLServer2000からデータを取得)

ボタンをクリックして印刷・・・

普通の動作である。しかし、PrintDocumentで特に改ページをする場合、次ページを表示する度にデータを取得してしまい動作が非常に遅くなってしまうのであった。

そこで

Public Class Form1 の直下にSQLconnectionとsqlcommandを宣言してしまう。そうすることでボタンクリックのイベントの外でもデータセットが有効になる

Public Class Form1
Dim rnum As Integer '改ページ制御フラグ
 Private pt_Cn As New System.Data.SqlClient.SqlConnection
Private pt_SQL As System.Data.SqlClient.SqlCommand
Private pt_ds As New DataSet
Private pt_dt As New DataTable

・・・以下省略

そしてクリックイベントで目的のデータを出力するSQL文を書き込む

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button7.Click
Dim prv As New PrintPreviewDialog

Dim prv As New PrintPreviewDialog
Dim St As String
Dim ServerName As String = "サーバー名" 'サーバー名(またはIPアドレス)
Dim DatabaseName As String = "データベース名" 'データベース
Dim mySQL As String

St = "Server=""サーバー名"";"
St &= "integrated security=SSPI;"  'Windows認証
St &= "initial catalog = データベース名"

pt_Cn.ConnectionString = St
pt_SQL = pt_Cn.CreateCommand

mySQL = "SELECT SHOCD,SHONAME FROM SHOMASTER"

pt_SQL.CommandText = mySQL
pt_Cn.Open()

Dim sqlSelect As New SqlClient.SqlCommand(mySQL, pt_Cn)
Dim Adapter As New SqlClient.SqlDataAdapter(sqlSelect)

Adapter.Fill(pt_ds) 'FILL すべてのレコードを取得するメソッド
prv.Document = PrintDocument1
prv.ShowDialog()
pt_Cn.Close() '必ず閉じる。連続して実行した場合エラーが発生

End Sub


最後にPrintPageハンドラにソースを入力。ボタンクリックによりセットされたAdapter.Fill(pt_ds)の内容をLoopにより表示する

Private Sub PrintDocument1_PrintPage(ByVal sender As System.Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles PrintDocument1.PrintPage
Dim f As Font
'印刷開始位置
Dim x As Integer = 50
Dim y As Integer = 100
'行ピッチ
Dim pitch As Integer
Dim cnt As Integer = 0
Dim i As Integer
f = New Font("MS ゴシック", 16)
pitch = f.Height + 3
Dim P1 As New Pen(Color.Blue, 1)

Dim row_cnt As Integer = 0

i = 0

'row_cnt = ds.Tables(0).Rows.Count
Do Until rnum = pt_ds.Tables(0).Rows.Count
'Do Until rnum = row_cnt
'For i = 0 To row_cnt - 1
e.Graphics.DrawString(pt_ds.Tables(0).Rows(rnum)(0).ToString.PadRight(10) & _
pt_ds.Tables(0).Rows(rnum)(1).ToString.PadRight(10), f, Brushes.Black, x, y + (cnt * pitch))
e.Graphics.DrawLine(P1, x, y + (cnt * pitch), x + 600, y + (cnt * pitch))
rnum = rnum + 1
cnt = cnt + 1
If cnt = 20 Then
e.HasMorePages = True
Exit Do
End If
'Next
Loop

End Sub

改ページ用のフラグを初期化

Private Sub PrintDocument1_BeginPrint(ByVal sender As System.Object, ByVal e As System.Drawing.Printing.PrintEventArgs) Handles PrintDocument1.BeginPrint
'初期化の注意事項
'PrintPageイベント内でカウントの初期化はしてはいけない
rnum = 0

End Sub

長いソースに見えるかもしれないが、展開してみると意外とそうでもなかったりする
これでデータベースに一度だけアクセスして内容をPrintDocumentに表示する内容となるはずである。
もし、このソースを使用するのであればそれで発生した不具合等の責任は負えませんのでご了承下さい。

0 件のコメント: