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に表示する内容となるはずである。
もし、このソースを使用するのであればそれで発生した不具合等の責任は負えませんのでご了承下さい。
2008年7月15日火曜日
登録:
コメントの投稿 (Atom)
0 件のコメント:
コメントを投稿