tagCANDY CGI VBレスキュー(花ちゃん) の Visual Basic 2010 用 掲示板(VB.NET 掲示板) [ツリー表示へ]   [Home]
一括表示(VB.NET VB2005)
タイトル改ページしても1枚の紙に印刷されてしまいます。
記事No1910
投稿日: 2005/07/20(Wed) 11:05
投稿者浦島太郎
[OSのVer]:WindowsXp    [VBのVer]:VB.NET2003
お邪魔します。いつも参考にさせて頂いております。
テキストファイルを開いて印刷をしようとしていますが、改ページができません
行間隔を7oとって、20行で改ページのつもりなんですが、1枚の紙に2度打
ちされるばかりです。
  行数をカウントして20行になったら
    e.HasMorePages = True
  20行以下なら
    e.HasMorePages = False
という考え方では出来ないんでしょうか。
 色々調べましたが、1ページに印刷可能な文字数等と比較して改ページさせて
いる例ばかりしか見つからず、行数指定とかデータの内容で変更とかは見つかり
ませんでした。
VB4.0 を少しやっていましたが、まったくの初心者です。

[ツリー表示へ]
タイトルRe: 改ページしても1枚の紙に印刷されてしまいます。
記事No1911
投稿日: 2005/07/20(Wed) 12:05
投稿者花ちゃん
下記の過去ログは参考になりませんでしたか?

Re^3: PrintDocument−改頁について - 花ちゃん 12/29-18:22 No.1244
hhttp://www.bcap.co.jp/hanafusa/bbs/wforum.cgi?mode=allread&no=1239#1244

[ツリー表示へ]
タイトルRe^2: 改ページしても1枚の紙に印刷されてしまいます。
記事No1913
投稿日: 2005/07/20(Wed) 13:16
投稿者浦島太郎
[OSのVer]:Windows    [VBのVer]:VB.NET  
> 下記の過去ログは参考になりませんでしたか?
>
> Re^3: PrintDocument−改頁について - 花ちゃん 12/29-18:22 No.1244
> hhttp://www.bcap.co.jp/hanafusa/bbs/wforum.cgi?mode=allread&no=1239#1244

 お恥ずかしい話ですが、投稿の前に見させて頂きました。
それで、e.HasMorePages = True だけで改ページは出来ないのかな?
というのは
Case0、Case1 の必要性が理解出来ず、
   e.HasMorePages = False
の位置も...?です。
 例は、”あいうえお”を10行印刷後改ページして残りに”かきくけこ”???
といったレベルです。例の実行結果を教えてください。もう一度考えてみます。

[ツリー表示へ]
タイトルRe^3: 改ページしても1枚の紙に印刷されてしまいます。
記事No1916
投稿日: 2005/07/20(Wed) 15:48
投稿者花ちゃん
> 例の実行結果を教えてください。もう一度考えてみます。

サンプルがあるのですから、ご自分で色々設定を変えて見て試して頂いたら、ご理解できるかと
思うのですが、e.HasMorePages は、VB6.0 の改ページ動作とは違います(ヘルプ参照)
従ってPrintDocument1_PrintPage イベントに送るデータは1ページ分づつになり
PrintDocument1_PrintPage イベントを抜けた時に改ページが行れます。その時に
e.HasMorePages =True に設定するともう一度PrintDocument1_PrintPage イベント を呼び出し
残りの文書を印刷できるようになるのです。
下記を一度試して見て下さい。

    Private prpg As Integer         '印字ページのフラグ
    Private count As Integer        '印字済み行数
    Private pgMax As Integer = 45   '印字する総行数
    Private pagno As Integer        '印字ページの番号
    Private kara As Integer
    Private myText(45) As String

    Private Sub Button1_Click(ByVal sender As System.Object, _
                              ByVal e As System.EventArgs) Handles Button1.Click
        Dim i As Integer
    '実際はテキストファイルを行毎に配列に入れて下さい。
        For i = 0 To 45
            myText(i) = i & "  印刷する文書の1行分のデータ"
        Next

        PrintDocument1.Print()

    End Sub

    Private Sub PrintDocument1_PrintPage(ByVal sender As Object, _
        ByVal e As System.Drawing.Printing.PrintPageEventArgs) _
            Handles PrintDocument1.PrintPage

        Dim i As Integer
        Dim g As Graphics = e.Graphics
        Dim ln As Integer = 0

        'ミリメートルを長さの単位に指定します。
        g.PageUnit = GraphicsUnit.Millimeter
        Select Case prpg
            Case 0      '1ページ分のデータを印字

                For i = kara To kara + 9
                    ln += 1
                    g.DrawString(myText(i), _
                            New Font("MS Pゴシック", 12), Brushes.Black, 20, ln * 25)
                    count += 1
                Next i
                e.HasMorePages = True
            Case 1          '残りの行数を印字
                e.HasMorePages = False

                For i = kara To pgMax
                    ln += 1
                    g.DrawString(myText(i), _
                            New Font("MS Pゴシック", 12), Brushes.Black, 20, ln * 25)
                Next i
  '追加分ここから
                '印刷プレビューでもこのイベントは呼び出されるので初期化が必要
                kara = 0
                prpg = 0
                count = 0
                Exit Sub
  '追加分ここまで
        End Select
        If ((pgMax - count) / 10) > 1 Then
            kara = i
            prpg = 0        '次のページを印字
        Else
            kara = i
            prpg = 1        '最後のページを印字
        End If
    End Sub

[ツリー表示へ]
タイトルRe: 改ページしても1枚の紙に印刷されてしまいます。
記事No1917
投稿日: 2005/07/20(Wed) 16:13
投稿者魔界の仮面弁士
# う。既に回答が付いていたようで……。でも、折角書いたので投稿しておこう。(^^;


> VB4.0 を少しやっていましたが、まったくの初心者です。

VB.NETの印刷処理は、VB4の時とは全く異なります。

そもそも、VB.NET においては、
 PrintPreviewDialog1.Document = PrintDocument1
 PrintPreviewDialog1.ShowDialog()
のような処理によって、
 Private Sub PrintDocument1_PrintPage〜〜〜
というイベントが呼び出される、という点までは理解されていますでしょうか。

まず、[PrintDocument] が、印刷処理の核となるオブジェクトです。
このオブジェクトの『PrintPageイベント』に、印刷内容を描画するための
処理を記述する事になります。

この PrintDocumentオブジェクトを、[PrintPreviewDialog] に割り当てれば、
印刷プレビュー画面が表示されますし、[PrintPreviewControl]に割り当てれば、
フォーム上にてプレビューを行うことができます。


そして、この『PrintPageイベント』は、印刷の各ページごとに呼び出されます。
また、PrintPageイベント内で『e.HasMorePages』を設定している部分が、
PrintDocumentに、改ページを指示する処理に当たります。

e.HasMorePages = True とすれば、『まだ、印刷したページが残っているので、
もう一回、PrintPageイベントを処理してください』という意味になりますし、
e.HasMorePages = False とすれば、『もう、印刷するページは残っていない』
という意味になります。


たとえば、VB4 で 3ページの文書を印刷する場合は、
 Private Sub Command1_Click()
  Printer.Print "1ページ目"
  Printer.NewPage   '改ページ
  Printer.Print "2ページ目"
  Printer.NewPage   '改ページ
  Printer.Print "3ページ目"
  Printer.EndDoc    '描画終了→印刷開始
 End Sub
のように、1回の呼び出しで、3ページ分の印刷処理を行っていました。

しかし、VB.NETの場合は異なります。
3ページの文書を印刷するなら、PrintPage自体が 3 回呼ばれます。
1回のPrintPageイベントで、3ページ分の印刷処理を行うわけではありません。


最初の1回目のPrintPageイベントの呼び出しでは、1ページ目の描画処理を
行う事になります。この時、「e.HasMorePages = True」と指定することで、
『まだページが残っているので、もう一回、イベントを呼び出してください』
という指示が送られる事になります。

これにより、2回目のPrintPageイベントの呼び出しが発生します。
ここで、2ページ目の描画処理を行います。さらに、3ページ目のデータを
印刷させるために、もう一度「e.HasMorePages = True」と指定しておきます。

3回目のPrintPageイベントの呼び出しが、最後の3ページ目の印刷処理です。
最後のページなので、今度は「e.HasMorePages = False」と指定し、印刷完了です。


> 行間隔を7oとって、20行で改ページのつもりなんですが、1枚の紙に2度打
> ちされるばかりです。
2度打ちされるのは、1回のイベントで、複数ページを印刷しようとしているからでしょうね。
上記に書いたように、1回のイベントでは、1ページ分の印刷処理だけを記述するようにします。


もし、ページ辺りの行数を20行にして印刷したいなら、たとえば、こんな感じでしょうか。

下記は、TextBox1の内容を印刷するサンプルです。
処理の流れがわかる様に、ページ数と行番号も印刷してみました。
# 折り返し・余白・行間等の制御は行っていません。細かい点は、適宜、書き換えてください。

Private Const MaxLine As Short = 20
Private CurrentPage As Short
Private CurrentLine As Short
Private TextLines() As String

Private Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Button1.Click
  TextLines = TextBox1.Lines
  PrintPreviewDialog1.Document = PrintDocument1
  CurrentLine = 0
  CurrentPage = 0
  PrintPreviewDialog1.ShowDialog()
End Sub

Private Sub PrintDocument1_PrintPage(ByVal sender As Object, _
        ByVal e As Printing.PrintPageEventArgs) Handles PrintDocument1.PrintPage
  Dim g As Graphics = e.Graphics
  g.PageUnit = GraphicsUnit.Point
  e.HasMorePages = True
  CurrentPage += 1
  g.DrawString(CStr(CurrentPage) & "ページ", Me.Font, Brushes.Blue, 1, 1)
  For Line As Short = 1 To MaxLine
    CurrentLine += 1
    If CurrentLine > UBound(TextLines) Then
      '全てのデータを印刷し終わった場合
      e.HasMorePages = False
      Exit For
    Else
      g.DrawString(CStr(CurrentLine) & ": " & TextLines(CurrentLine), _
        Me.Font, Brushes.Black, 20, Line * 20)
    End If
  Next
End Sub

[ツリー表示へ]
タイトルRe^2: 改ページしても1枚の紙に印刷されてしまいます。
記事No1918
投稿日: 2005/07/20(Wed) 16:58
投稿者浦島太郎
花ちゃんさん・魔界の仮面弁士さん
丁寧に回答いただきまして有難うございました。
頭の中で「そうなのかな?・そうかなあ?」の繰り返しだった事が
つながりました。
 これから、がんばって作り直してみます。

[ツリー表示へ]
タイトル念の為
記事No1920
投稿日: 2005/07/21(Thu) 10:31
投稿者花ちゃん
印刷プレビュー等を表示する場合、再度 PrintDocument3_PrintPage イベントが呼ばれますので
使用したカウント用変数は、PrintDocument3_PrintPage イベント内の最後に印刷した
後でクリアしておいて下さい、でないとプレビューしてから印刷すると印刷物がないので
印刷されません。
(どちらのサンプルでも必要です)

[ツリー表示へ]
タイトルRe: 念の為
記事No1928
投稿日: 2005/07/22(Fri) 12:45
投稿者浦島太郎
 色々ご指導有難う御座いました。
シーケンシャルファイルを配列に取り込む事と、見出しを付ける事に四苦八苦
してようやく出来ました。
 

[ツリー表示へ]