tagCANDY CGI VBレスキュー(花ちゃん) の Visual Basic 2010 用 掲示板(VB.NET 掲示板) [ツリー表示へ]   [Home]
一括表示(VB.NET VB2005)
タイトルRe6.NETの印刷の改ページ処理
記事No3270
投稿日: 2006/03/13(Mon) 22:30
投稿者マサノリ
[OSのVer]:Windows    [VBのVer]:VB.NET  

   OSのVer]:Windows xp [VBのVer]:VB.NET 2005 

   魔界の仮面弁士さん、沢山の回答有難う御座います。
   しかし、 今だに、うまく行かないのですが。
   私が作成しようとしている表は
    
               原価表
 ------------------------------------------------  
   番号    材料費   経費  間接費
    No.1    100    250   300
  No.2    500    600   150 
  
と言った表で、No.50迄印刷すると、ページ替えをして、再度”原価表”
  ” 番号    材料費   経費  間接費”というタイトルを印刷し、
No.51から再度印刷するという物で、
 
 PrintDocument_Page1に
      ”原価表”
 ”番号    材料費   経費  間接費” というタイトルの印刷設定をし、
 PrintDocument_Page2に 
   ”No.1  100    250   300”を印刷する設定をし、
 
 call PrintDocument_Page1

  call PrintDocument_Page2
  という様に設定すると
  ”原価表”
”番号    材料費   経費  間接費” 
 というタイトルを印刷してすぐページ替えをして、
  次ページに
   ”No.1  100    250   300”
  が印刷されてしまいます。
又 PrintDocument_Page1から他のプロシージャー、つまり
Private Sub に”No.1  100    250   300”を
印刷する設定をしても、e.Graphic(”No.1  100    250   300”〜)
がエラー状態になってしまいます。
Private Sub には印刷の項目が書けない様ですし、どのようにすれば良いのか、
お教え願います。

[ツリー表示へ]
タイトルRe: VB.NETの印刷の改ページ処理
記事No3272
投稿日: 2006/03/14(Tue) 09:09
投稿者魔界の仮面弁士
> [OSのVer]:Windows    [VBのVer]:VB.NET  
>  OSのVer]:Windows xp [VBのVer]:VB.NET 2005 
# VB.NET 2005 → VB 2005 の方が正確かな。

> VB.NET では Printdocument1_Pageの箇所に印刷する項目をまとめなければならないように
WithEvents に頼らずとも、AddHandler で動的に結びつける事もできますし、あるいは
Pageイベントの中で、別のプロシージャを呼び出すような書き方にする事も出来ますよね。

[ツリー表示へ]
タイトルRe^2: VB.NETの印刷の改ページ処理
記事No3273
投稿日: 2006/03/14(Tue) 13:57
投稿者あきこ
魔界の仮面弁士様、私もずっと困っていた問題だったので回答に飛びつきました。

でも、私は知識の浅い "にわかプログラマー"  なので、せっかくの魔界の仮面弁士様
の説明がよくわかりません。

私はVB5.0からの移行なのですがマサノリさんはたぶん、

  Call タイトル印刷
  Call 明細印刷
  Printer.NewPage とされるのだと思います。

> > VB.NET では Printdocument1_Pageの箇所に印刷する項目をまとめなければならないように
> WithEvents に頼らずとも、AddHandler で動的に結びつける事もできますし、あるいは
> Pageイベントの中で、別のプロシージャを呼び出すような書き方にする事も出来ますよね。

どうやるのかまったくわかりません。
具体的にコーディングして教えていただけないでしょうか? 
すみません。本当によろしくお願いします。

[ツリー表示へ]
タイトルRe^3: VB.NETの印刷の改ページ処理
記事No3274
投稿日: 2006/03/14(Tue) 15:00
投稿者魔界の仮面弁士
すみません。悩んでいる部分がよく分からなかったので……印刷処理の概要から書きます。


まず、ページの印刷が必要になるたびに、PrintDocument の PrintPageイベントが呼ばれます。

このイベントの第2引数から得られる e.Graphics が、描画のためのキャンパスです。
(VB6 でいう所の、Printer や PictureBox に相当しますね)

そしてこの第2引数に、「e.HasMorePages = True」と指定した状態でイベントを抜けると、
続けて次のページの印刷処理が発生し、再度 PrintPageイベントが呼び出されます。
以降、HasMorePages に False が指定されるまで、PrintPage イベントが発生しますので、
これが改ページ処理という事になります。


> 具体的にコーディングして教えていただけないでしょうか?
「明細印刷」の中で使われているデータの扱いなどが不明瞭なので、
具体的なコードを書くのは難しいです…。特に決まった書き方があるでも無し。


とりあえずコードのイメージで書くと、たとえば 3 ページ固定で印刷するなら、

 Private ページ番号 As Integer = 0
 Private Sub PrintDocument1_PrintPage(……
  ページ番号 += 1
  タイトル印刷(e.Graphics)
  明細印刷(e.Graphics, ページ番号)
  If ページ番号 = 3 Then
   e.HasMorePage = False  '3ページ印刷したら終了
   ページ番号 = 0
  Else
   e.HasMorePage = True
  End If
 End Sub

のようなイメージで書けるかな、と思います。


あるいは、PrintDocument クラス自体を継承させて

 NotInheritable Class 月次売上帳票
  Inherits Printing.PrintDocument
   :
  Private ページ番号 As Integer = 0
  Private 月次売上 As 営業売上
  Protected Overrides Sub OnPrintPage(ByVal e As Printing.PrintPageEventArgs)
   ページ番号 += 1
   タイトル印刷(e.Graphics)
   e.HasMorePages = 明細印刷(e.Graphics)
   MyBase.OnPrintPage(e)
  End Sub
  Private Sub タイトル印刷(ByVal G As Graphics)
   :
  End Sub
  Private Function 明細印刷(ByVal G As Graphics) As Boolean
   :
   'ページ内に印刷し切れなかったデータがあれば、True
   '全データを印刷し終わったら False を返す
   :
  End Sub
 End Class

のようにするとか。

[ツリー表示へ]
タイトルRe^4: VB.NETの印刷の改ページ処理
記事No3275
投稿日: 2006/03/14(Tue) 17:02
投稿者応用の利かないあきこ
魔界の仮面弁士様、はやくもお返事有り難うございました。

すみません。まだ解決できないのです。

私の場合(VB5.0なのですが)、まず、
    Dim Yoko As Single
    Dim Tate As Single
    Dim Page As Integer
    Dim Data As Integer
    Dim Data_1 As Integer
    Dim Data_2 As Integer
    Dim Data_3 As Integer

Private Sub タイトル印刷()
        Yoko = 40
        Tate = 560
v      e.Graphics.DrawImage(img, Yoko, Tate)
End Sub

Private Sub 明細印刷()  ’実際はもっと複雑なんです
    Data = Data /   25  *  315
        e.Graphics.DrawString(Data, New Font("HGOCR-B", 13, FontStyle.Regular),  Yo
ko, Tate)
        Tate = Tate + 2.7
End Sub


Private Sub ページ印刷()
       Call タイトル印刷
         Page = 0
      Do Until Page = 100
            Data = Data_1          
          Call 明細印刷
            Data = Data_2          
          Call 明細印刷
            Data = Data_3          
          Call 明細印刷

            Data_1 = Data_1 + 1
            Data_2 = Data_2 + 1
            Data_3 = Data_3 + 1
           Page = Page + 1
        Loop
End Sub
です。

VB.NETでこれをすると
    Private Sub PrintDocument1_PrintPage(・・・

        Yoko = 40  ’タイトル印刷です
        Tate = 560
       e.Graphics.DrawImage(img, Yoko, Tate)

        Yoko = 40  ’ 以下明細印刷です
        Tate = 660

    Data_1 = Data_1 /   25  *  315
        e.Graphics.DrawString(Data, New Font("HGOCR-B", 13, FontStyle.Regular),  Yo
ko, Tate)
        Tate = Tate + 2.7

    Data_2 = Data_2 /   25  *  315
        e.Graphics.DrawString(Data, New Font("HGOCR-B", 13, FontStyle.Regular),  Yo
ko, Tate)
        Tate = Tate + 2.7

もし、Dataが200個有れば200カ所書くことになり、実際はもっと複雑なのですごい行数になります。


私が無い頭で考えた事は、
  PrintDocumentは、いくつも貼り付ける事ができるので、タイトル印刷・明細印刷をそれぞれ   
PrintDocument1・PrintDocument2にして

    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)

        PrintDocument1.Print()
        Page = 0
    Do Until Page = 100
            Data = Data_1          
            PrintDocument2.Print()
            Data = Data_2          
            PrintDocument2.Print()
            Data = Data_3          
            PrintDocument2.Print()
            Data_1 = Data_1 + 1
            Data_2 = Data_2 + 1
            Data_3 = Data_3 + 1
            Page = Page + 1
        Loop
    End Sub
としたのですが、
        PrintDocumentはすべてページ変えをしてしまったのです。

長くなって申し訳ありませんが途方に暮れている状態なのです。
よろしくお願いします。

[ツリー表示へ]
タイトルRe^5: VB.NETの印刷の改ページ処理
記事No3283
投稿日: 2006/03/15(Wed) 10:25
投稿者魔界の仮面弁士
> 私の場合(VB5.0なのですが)、まず、
    :
> Private Sub タイトル印刷()
>         Yoko = 40
>         Tate = 560
> v      e.Graphics.DrawImage(img, Yoko, Tate)
> End Sub
    :

あれ? とても VB5 の構文には見えないのですが……。(^^;
もし、VB5 ではなく VB.NET の間違いだったとしても、この e.Graphics が、
どこからどのように渡されているのかといった、肝心な情報が抜け落ちている気が。


> VB.NETでこれをすると
   :
> Dataが200個有れば200カ所書くことになり、実際はもっと複雑なのですごい行数になります。
Data_1 や Data_2 が何を意味するのか分かりませんでしたが、この場合は、
 Private Sub PrintDocument1_PrintPage(・・・
  ページ番号 += 1
  Call タイトル印刷(e)
  Call 明細印刷(e, ページ番号)
 End Sub
というイメージで処理できませんか?
(ページ番号ではなく、出力する座標位置で管理しても良いですけど)


> PrintDocumentは、いくつも貼り付ける事ができるので、タイトル印刷・明細印刷を
> それぞれ PrintDocument1・PrintDocument2 にして

それだと、方向性が間違っています。
ページが複数あっても、文書としては一つなので、PrintDocument 自体は一つしか使いません。


「PrintDocument」とは、その名の通り、印刷対象となる『文書(ドキュメント)』を表すものであって、
印刷対象となる個々の『ページ』を表すものでは無い事に注意してください。

各ページの処理は、それぞれの文書(PrintDocumentクラス)内の、
ページごとの印刷処理(PrintPageイベント)に記述する事になります。


たとえば、3ページ分の印刷が必要な場合、処理の流れとしてはこうなります。
(使用する PrintDocument クラスは、一つだけです)

 1. 印刷処理の開始 ← PrintPreviewDialog1.Show() や PrintDocument1.Print() など。

 2. PrintPage イベントが発生 → タイトルと、1ページ目の印刷処理を実行した後、
    e.HasMorePages = True にして、イベントプロシージャを抜ける

 3. PrintPage イベントが再発生 → タイトルと、2ページ目の印刷処理を実行した後、
    e.HasMorePages = True にして、イベントプロシージャを抜ける

 4. PrintPage イベントが再々発生 → タイトルと、3ページ目の印刷処理を実行した後、
    e.HasMorePages = False にして、イベントプロシージャを抜ける

 5. これにて印刷処理が完了し、プレビューあるいはプリンタ出力が行われる。

[ツリー表示へ]
タイトルRe^4: VB.NETの印刷の改ページ処理
記事No3276
投稿日: 2006/03/14(Tue) 17:32
投稿者あきこ
削除してください

[ツリー表示へ]
タイトルRe5: VB.NETの印刷の改ページ処理
記事No3278
投稿日: 2006/03/14(Tue) 20:50
投稿者マサノリ
[OSのVer]:Windows    [VBのVer]:VB.NET  
> [OSのVer]:Windows    [VBのVer]:VB.NET  
>  OSのVer]:Windows xp [VBのVer]:VB.NET 2005 

   魔界の仮面弁士さん、沢山の回答有難う御座います。
   しかし、 今だに、うまく行かないのですが。
   私が作成しようとしている表は
    
               原価表
 ------------------------------------------------  
   番号    材料費   経費  間接費
    No.1    100    250   300
  No.2    500    600   150 
  
と言った表で、No.50迄印刷すると、ページ替えをして、再度”原価表”
  ” 番号    材料費   経費  間接費”というタイトルを印刷し、
No.51から再度印刷するという物で、
 
 PrintDocument_Page1に
      ”原価表”
 ”番号    材料費   経費  間接費” というタイトルの印刷設定をし、
 PrintDocument_Page2に 
   ”No.1  100    250   300”を印刷する設定をし、
 
 call PrintDocument_Page1

  call PrintDocument_Page2
  という様に設定すると
  ”原価表”
”番号    材料費   経費  間接費” 
 というタイトルを印刷してすぐページ替えをして、
  次ページに
   ”No.1  100    250   300”
  が印刷されてしまいます。
又 PrintDocument_Page1から他のプロシージャー、つまり
Private Sub に”No.1  100    250   300”を
印刷する設定をしても、e.Graphic(”No.1  100    250   300”〜)
がエラー状態になってしまいます。
Private Sub には印刷の項目が書けない様ですし、どのようにすれば良いのか、
お教え願います。

[ツリー表示へ]
タイトルRe: Re5: VB.NETの印刷の改ページ処理
記事No3279
投稿日: 2006/03/14(Tue) 21:44
投稿者YAS
マサノリさん,こんばんは。

印刷プレビューですが,簡単なサンプルです。
(プレビューできれば印刷は簡単です。)
参考にしてください。

Public Class Form1

    Dim WithEvents PrintDocument As New Drawing.Printing.PrintDocument
    Dim WithEvents PrintPreviewDialog As New PrintPreviewDialog
    Dim List As New Specialized.StringCollection

    Private Sub Form1_Load(ByVal sender As System.Object, _
    ByVal e As System.EventArgs) Handles MyBase.Load
        For i As Integer = 0 To 100
            List.Add(String.Format("{0}行目のデータ", i))
        Next
        Me.PrintPreviewDialog.Document = PrintDocument
        Me.PrintPreviewDialog.ShowDialog(Me)
    End Sub

    Private Page As Integer = 0
    Private Sub PrintDocument_PrintPage(ByVal sender As Object, _
    ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles PrintDocument.PrintPage
        e.Graphics.DrawString("タイトル", Me.Font, _
        Brushes.Black, e.MarginBounds.Left, e.MarginBounds.Top)
        For i As Integer = 0 To 19
            e.Graphics.DrawString(List(Page * 20 + i), Me.Font, Brushes.Black, _
            e.MarginBounds.Left, e.MarginBounds.Top + e.MarginBounds.Height / 21 * (i + 1))
        Next
        Page += 1
        e.HasMorePages = (Page < 5)
    End Sub
End Class

フォームのコードに貼り付ければ動作します。

[ツリー表示へ]
タイトルRe: Re5: VB.NETの印刷の改ページ処理
記事No3280
投稿日: 2006/03/14(Tue) 22:40
投稿者あきこ
マサノリさん、はじめまして。

>  call PrintDocument_Page1
>
>   call PrintDocument_Page2
>   という様に設定すると
>   ”原価表”
> ”番号    材料費   経費  間接費” 
>  というタイトルを印刷してすぐページ替えをして、
>   次ページに
>    ”No.1  100    250   300”
>   が印刷されてしまいます。
私もそうでした。
e.HasMorePage = True と書いてもページ替えをしてしまいます。
ページ替えさせるように設定しているのなら、なぜPrintDocument_Pageをいくつも貼り付けられるよう
にしているのか理解できません。

> Private Sub には印刷の項目が書けない様ですし、・・・・
これもしました。

PrintDocument_Pageをページ替えさせないようにする方法をどなたか教えていただけないでしょうか?

[ツリー表示へ]
タイトルRe^2: Re5: VB.NETの印刷の改ページ処理
記事No3281
投稿日: 2006/03/14(Tue) 23:08
投稿者YAS
別々のPrintDocumentに出力しているのですから別々に印刷されてしまいます。
同じページに納めたい内容は1つのPrintDocumentに描画するようにしてください。
3274で魔界の仮面弁士さんが示しているように,ページを表すプライベートな変数を用意して,その変
数をインデックスにページ毎に適切なデータが出力されるようにします。

VB2005であれば私の3279のコードを試してみてください。だぶんご希望の処理はこういうことだと思う
のですが。コードを貼り付けるだけで動作するはずです。

ちなみに,マサノリさん,あきこさんが挑戦している,2つのPrintDocumentを1つに合成して出力する
方法は私にもわかりませんし,逆に問題を難しくしている気がします。

[ツリー表示へ]
タイトルRe^3: Re5: VB.NETの印刷の改ページ処理
記事No3284
投稿日: 2006/03/15(Wed) 11:22
投稿者あきこ
魔界の仮面弁士さん、YASさん、昨日は大変ありがとうございました。

この問題は1年位私の頭を悩ませていました。

> 別々のPrintDocumentに出力しているのですから別々に印刷されてしまいます。
そうなんです。
イヤというほどわかってます。
私はデータの数だけ e.Graphics.DrawString(・・・ を書いていました。
でも、昨日色々と教えられて問題は、横座標と縦座標なのだとやっとわかりました。
マサノリさんのように一定間隔に縦にさがっていくのなら、魔界の仮面弁士さんの3274サンプルプロ
グラムの
ページ番号+=1の下に
縦座標+=いくつ かを加えれば出来るような気がします。
私の場合縦・横の座標が一定間隔に動くのでは無いのでIF文で判断をかけるようにした方が今やって
いる方法より効率よいとわかりこれを取り入れようと決めました。

アッ!今魔界の仮面弁士さんの回答b調べたらまた、また回答を下さってたのですね!
長い、下手なコーディングを読んでくださって有り難うございました。
ハイ、少しごちゃ混ぜになっていました。

以下 魔界の仮面弁士さん回答3283より
Private Sub PrintDocument1_PrintPage(・・・
  ページ番号 += 1
  Call タイトル印刷(e)
  Call 明細印刷(e, ページ番号)
 End Sub
というイメージで処理できませんか?
★私これが出来ません!!

(ページ番号ではなく、出力する座標位置で管理しても良いですけど)
☆しかたがないので今はこれにしようと思ってます。

マサノリさんの質問3278の最後:
Private Sub に”No.1  100    250   300”を
印刷する設定をしても、e.Graphic(”No.1  100    250   300”〜)
がエラー状態になってしまいます。
Private Sub には印刷の項目が書けない様ですし、どのようにすれば良いのか、・・・

Call 明細印刷(e, ページ番号)とする方法が私達にはこの「Private Sub 明細印刷」とする方法しか
わかりません。どのようにするか教えていただけないでしょうか?
何度もすみません。

[ツリー表示へ]
タイトルRe^4: Re5: VB.NETの印刷の改ページ処理
記事No3288
投稿日: 2006/03/15(Wed) 20:35
投稿者YAS

もしかして,引数とか戻り値とかその辺がわからないのですか?
PrintDocument1_PrintPageの引数の「e」が肝心で,外部のSubに処理をまかせたければ,
この「e」を引数にして呼ばなければいけません。

例えば,

呼ぶ側 : Call PrintMeisai( e , Page )

呼ばれる側 : Private Sub PrintMeisai( e as System.Drawing.Printing.PrintPageEventArgs, Page
As Integer )

呼ばれた側はこの「e」を使ってGraphicsオブジェクトに描画します。
呼ぶ側から渡された「e」を使わなければe.Graphicsとしても「e」の中はからっぽなので
当然,Null参照のエラーになります。

以下のサンプルはこのまま動作はしませんが,これに肉付けをすればたぶん望む処理になると思います。

    Private Sub PrintTitle(ByVal e As System.Drawing.Printing.PrintPageEventArgs)
        Dim img As Image
        e.Graphics.DrawImage(img, 40, 560)
    End Sub

    Private Sub PrintMeisai(ByVal e As System.Drawing.Printing.PrintPageEventArgs, ByVal Page As Integer)
        Dim Data As Integer
        e.Graphics.DrawString(Data.ToString, New Font("HGOCR-B", 13, FontStyle.Regular), Brushes.Black, 40, 660)
    End Sub

    Dim Page as Integer = 0
    Private Sub PrintDocument_PrintPage(ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles PrintDocument.PrintPage
        PrintTitle(e)
        PrintMeisai(e, Page)
        Page += 1        
        e.HasMorePages = (Page < 100)
    End Sub

[ツリー表示へ]
タイトルRe^5: Re5: VB.NETの印刷の改ページ処理
記事No3289
投稿日: 2006/03/16(Thu) 00:33
投稿者あきこ
YAS様、ありがとうございます。

> もしかして,引数とか戻り値とかその辺がわからないのですか?
そうなんです。
私は、参考書と電話サポート(以前はマイクロソフトやってました)でプログラムを作った "に
わかプ
ログラマー" なので、引数・戻り値・Null等まったくわかりません。

> PrintDocument1_PrintPageの引数の「e」が肝心で,外部のSubに処理をまかせたければ,
> この「e」を引数にして呼ばなければいけません。
>
そうだったんですか〜
>
> 呼ぶ側 : Call PrintMeisai( e , Page )
>
> 呼ばれる側 : Private Sub PrintMeisai( e as System.Drawing.Printing.PrintPageEventArgs,
Page
> As Integer )

バンザイ!

これで解決だ!
 
やってみました!!

そうしたら、
    Private Sub PrintMeisai(ByVal e As System.Drawing.Printing.PrintPageEventArgs, ByVal
Page As Integer) と ”ByVal” と入力しないのに2カ所も ”ByVal”が入ってしまい、

Call PrintMeisai( e , Page ) の ”e”と ”Page”の下に青色の波線(エラーだと思います)が入
ってしまいました。

「世話がかかってしょうがない」と思われる事は百も承知ですがよろしくお願いします。

追伸:でも、これが出来るなら「PrintDocument1」は必要があるのだろうかと思いますし、私自身こんな物イラナイ。

[ツリー表示へ]
タイトルRe^6: Re5: VB.NETの印刷の改ページ処理
記事No3291
投稿日: 2006/03/16(Thu) 07:19
投稿者YAS
>     Private Sub PrintMeisai(ByVal e As System.Drawing.Printing.PrintPageEventArgs, ByVal
> Page As Integer) と ”ByVal” と入力しないのに2カ所も ”ByVal”が入ってしまい、

すみません。ByValと入って正解です。抜けていました。

> Call PrintMeisai( e , Page ) の ”e”と ”Page”の下に青色の波線(エラーだと思います)が

> ってしまいました。


変数の宣言をしていないので青線が入っているのだと思います。
が,Pageの下に青線が入るのはまだ理解できるのですが,eの下にも入るのは?です。
Call PrintMeisai(e,Page)はPrintDocument_PrintPageプロシージャの中に書いていますか?

とにもかくにも,PrintDocument.PrintPageイベントで呼ばれるプロシージャの中で
e.Graphicsに描画された内容が印刷されるのです。


マサノリさんも,あきこさんも,
この掲示板の趣旨からいって,コピー・貼り付けをすれば動くコードを教えるのは最後の
手段とは思いますが,ツリーも大分長くなってきているので,やりたいことをもう少し
具体的に(データが入っている変数や印刷したい内容など)を教えて頂ければ,ある程度
具体的なコードを示します。

ただ,基本的にNo.3274の魔界の仮面弁士さんの説明が答えのほぼ全てであって,できれば
No.3274の内容を理解して自力解決するのが,たぶんこの掲示板の設置者の望んでいること
だと思います。

[ツリー表示へ]
タイトル印刷の改ページ処理
記事No3293
投稿日: 2006/03/16(Thu) 15:56
投稿者あきこ
> すみません。ByValと入って正解です。抜けていました。
YAS様、『すみません』などと言われては恐縮です。
私が当然理解出来なくてはいけないレベルだと思います。

> ただ,基本的にNo.3274の魔界の仮面弁士さんの説明が答えのほぼ全てであって,
ハイ、IF文を入れて出来ます。
ただ、とてもコードが長くなってしまい、出来たらCallでしたかったのです。

>自力解決するのが,たぶんこの掲示板の設置者の望んでいること
> だと思います。
ご指摘のとうりだと思います。
私がVBを始めたとき、マイクロソフトは1分いくらという有料のサポートがありました。
質問が複雑になると当然時間も長くなるので料金はUPしましたが、そのお会計方法は気に入り、文系
の私でもプログラムを書けるようになりました。
自分の作成したプログラムはとても使いよくて人生が変わったような気がしました。
YAS様、魔界の仮面弁士様本当にお世話様でした。

[ツリー表示へ]
タイトル印刷の改ページ
記事No3294
投稿日: 2006/03/16(Thu) 16:49
投稿者魔界の仮面弁士
> > ただ,基本的にNo.3274の魔界の仮面弁士さんの説明が答えのほぼ全てであって,
> ハイ、IF文を入れて出来ます。
> ただ、とてもコードが長くなってしまい、出来たらCallでしたかったのです。

私のサンプルで、その Call に相当するのが、
>>  タイトル印刷(e.Graphics)
>>  明細印刷(e.Graphics, ページ番号)
の部分となります。

「Sub タイトル印刷」や「Sub 明細印刷」の記述次第ではありますが、
PrintPage イベントへの記述自体は、それほど長くならないと思いますよ。

[ツリー表示へ]
タイトル印刷の改ページ
記事No3295
投稿日: 2006/03/16(Thu) 20:52
投稿者マサノリ
[OSのVer]:Windows    [VBのVer]:VB.NET  
> > > ただ,基本的にNo.3274の魔界の仮面弁士さんの説明が答えのほぼ全てであって,
> > ハイ、IF文を入れて出来ます。
> > ただ、とてもコードが長くなってしまい、出来たらCallでしたかったのです。
>
> 私のサンプルで、その Call に相当するのが、
> >>  タイトル印刷(e.Graphics)
> >>  明細印刷(e.Graphics, ページ番号)
> の部分となります。
>
> 「Sub タイトル印刷」や「Sub 明細印刷」の記述次第ではありますが、
> PrintPage イベントへの記述自体は、それほど長くならないと思いますよ。


こんばんは、
 そして、魔界の仮面弁士さん、YASさん、あきこさん、皆さん有難うごさいます。
 本当に、丁寧なご指導に感謝致します。
 私も、皆さんのご指導いただいた通りに作ってみたのですが、あと一歩どうしてもうまく行きません

 
私の作成したい表は、No.3278に掲載した表なのですが、
 
 ちなみに、私が作成したプログラムは、下記のようなものです。

Dim  LineMax as integer  =  225 ‘データ行数
Dim  LineCount as integer  =  0  ‘印字行数

Private Sub PrintDocument1_PrintPage(ByVal〜    )
  
  Do '@
       If  LineMax > 225   ‘印字行数が225行になれば@のDoを抜けるて終了する
           Exit Do
       End if
  
     タイトル印刷(e.Graphics)
 
       Do  ‘A
         明細印刷(e.Graphics,)   
          LineCount =  LineCount  +  1
        
          If  LineCount  = 50 then  ‘印字行数が50行になればページ換えして、AのDoを抜ける
              e.HasMorePages = True
               Exit do
         End if
            
       Loop
   Loop

  e.HasMorePages =  False

End Sub

Private Sub タイトル印刷(ByVal e )
   e.Graphics.DrawImage(“原価表” 〜)
   e.Graphics.DrawImage(“材料費” 〜)
   e.Graphics.DrawImage(“経費” 〜)
   e.Graphics.DrawImage(“間接費” 〜)
 End Sub
  
Private Function 明細印刷(ByVal e)
   
    e.Graphics.DrawImage(原価表の額 〜)
    e.Graphics.DrawImage(経費の額 〜)
    e.Graphics.DrawImage(間接費の額 〜)
    
End Sub
 
というものですが,
どうしても1ページ印刷を終わってしまいます。
最初、私は、PrintDocument1_PrintPageの中ですべて印刷項目を設定しなければいけない言われたので
、どう
しようかと思いあぐねましたが, VB 6.0 のようにサブルーチンして
Callで呼び出すことができるとわかって、本当にありがたい思いでしたが、
これから先が、まったくわかりません。
ツリーが、長くなりすぎて後ろめたい思いもありますが。
どうかよろしくお願いします。

[ツリー表示へ]
タイトル印刷の改ページ
記事No3300
投稿日: 2006/03/16(Thu) 22:36
投稿者YAS
マサノリさんへの具体例です。

初めに申し上げておきますが,以下のコードはあくまでサンプルであって,お手本ではありません。
全然練らないで思いつきでコーティングしているので定数は埋め込まれているなど,かなり適当です。

あくまで,参考程度にしてください。

(このままFormに貼り付ければ動作します。)

Public Class Form1

    Private Max As Integer = 255
    Private Genka(Max) As Genkahyo
    Private Index As Integer = 0
    Private WithEvents PrintPreviewDialog As New PrintPreviewDialog
    Private WithEvents PrintDocument As New Printing.PrintDocument

    Private Sub Form1_Load(ByVal sender As System.Object, _
                           ByVal e As System.EventArgs) Handles MyBase.Load
        '実験のため適当に数値を代入
        For i As Integer = 0 To 255
            Genka(i).Zairyohi = CInt(Rnd() * 1000)
            Genka(i).Keihi = CInt(Rnd() * 1000)
            Genka(i).Kansetsuhi = CInt(Rnd() * 1000)
        Next
        Me.PrintPreviewDialog.Document = Me.PrintDocument
        Me.PrintPreviewDialog.ShowDialog()
    End Sub

    Private Sub PrintDocument1_PrintPage(ByVal sender As Object, _
                             ByVal e As System.Drawing.Printing.PrintPageEventArgs) _
                             Handles PrintDocument.PrintPage
        'タイトル
        e.Graphics.DrawString("原価表", New Font("MS ゴシック", 9), Brushes.Black, _
                              e.MarginBounds.Left, e.MarginBounds.Top)
        Dim Title As String = "  番号    材料費      経費    間接費"
        e.Graphics.DrawString(Title, New Font("MS ゴシック", 9), Brushes.Black, _
                              e.MarginBounds.Left, e.MarginBounds.Top + 20)
        '明細
        For i As Integer = 0 To 49
            Dim Idx As Integer = i + Index
            If Idx > Max Then Exit For
            Dim Meisai As String = String.Format("{0,6:No\.000}{1,10}{2,10}{3,10}", _
                       Idx, Genka(Idx).Zairyohi, Genka(Idx).Keihi, Genka(Idx).Kansetsuhi)
            e.Graphics.DrawString(Meisai, New Font("MS ゴシック", 9), Brushes.Black, _
                                  e.MarginBounds.Left, e.MarginBounds.Top + 15 * i + 40)
        Next
        Index += 50
        e.HasMorePages = (Index < Max)
    End Sub

    Private Structure Genkahyo
        Dim Zairyohi As Integer
        Dim Keihi As Integer
        Dim Kansetsuhi As Integer
    End Structure

End Class

[ツリー表示へ]
タイトル改ページ
記事No3306
投稿日: 2006/03/17(Fri) 02:03
投稿者魔界の仮面弁士
No.3270 の、元の内容ってどうなっていましたっけ?
(中途半端に編集されてしまっていて、話の流れが分かりにくくなっているような…)


> しようかと思いあぐねましたが, VB 6.0 のようにサブルーチンして
> Callで呼び出すことができるとわかって、本当にありがたい思いでしたが、
# VB6 でサブルーチンというと、(On...)GoSub / Return の事を指す場合もあるので、
# Sub プロシージャという言い方の方が誤解が少ないかも。


> これから先が、まったくわかりません。
具体的なサンプルは、YASさんが書いてくださっていますので……印刷の考え方について。


どうやら、VB6 での開発経験がおありのようですね。
ならば、VB.NET の印刷処理を考える前に、「VB6 の Timer イベントの処理」を
思い出してみてください。


たとえば、「1 秒ごとに現在時刻を表示」し、それを「5 秒間続けるアプリ」を作る場合、
VB6 では、Timer を使って、このようなコードを書く事ができますよね。
========================================
  Option Explicit
  Private FinishTime As Date

  Private Sub Command1_Click()
    FinishTime = DateAdd("s", 5, Now)  '5秒後の時刻を取得(終了条件)
    Timer1.Interval = 1000
    Timer1.Enabled = True    '★時計の開始★
  End Sub

  '☆繰り返し呼ばれるイベント☆
  Private Sub Timer1_Timer()
    Call DrawTime(Now)       '★描画処理を Call★
    If Now >= FinishTime Then
      Timer1.Enabled = False '★終了条件を満たしたら、このイベントの発生を止める★
    End If
  End Sub

  '☆画面への描画処理☆
  Private Sub DrawTime(ByVal D As Date)
    Label1.Caption = FormatDateTime(D, vbLongTime)
  End Sub
========================================

上記では、Timer イベント自体が呼ばれるたびに、描画処理を Call して、
時刻表示を更新するといった作りになっています。


そして VB.NET の印刷処理も、これと同じような流れで記述する事ができます。

たとえば、「1 ページごとに、現在のページ番号を印字」して、
それを「5 ページ繰り返すアプリ」は、下記のように書けます。

(実行すると、左上に 1〜5 のページ番号が書かれた 5 ページの文書が出力されます)
========================================
  Private 現在のページ番号 As Integer
  Private 終了ページ番号 As Integer

  Private Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Button1.Click
    現在のページ番号 = 1
    終了ページ番号 = 5      '5ページ目が終了条件

    '印刷の場合
    'PrintDocument1.Print() '★印刷の開始★

    'プレビューの場合
    PrintPreviewDialog1.Show()
  End Sub

  '☆繰り返し呼ばれるイベント☆
  Private Sub PrintDocument1_PrintPage(ByVal sender As Object, ByVal e As Printing.PrintPageEventArgs) Handles PrintDocument1.PrintPage
    Call DrawPage(現在のページ番号, e)  '★描画処理を Call★

    現在のページ番号 += 1
    If 現在のページ番号 > 終了ページ番号 Then
      e.HasMorePages = False '★終了条件を満たしたら、このイベントの発生を止める★
    Else
      e.HasMorePages = True
    End If
  End Sub

  '☆ Grahpics への描画処理☆
  Private Sub DrawPage(ByVal ページ As Integer, ByVal e As Printing.PrintPageEventArgs)
    Dim G As Graphics = e.Graphics
    Dim myFont As Font = New Font("MS ゴシック", 220, FontStyle.Bold, GraphicsUnit.Pixel)
    Dim bluePen As Brush = Brushes.Blue.Clone()
    Dim bmpPen As Brush = New TextureBrush(Icon.ToBitmap(), Drawing2D.WrapMode.TileFlipXY)
    G.FillEllipse(bmpPen, 0, 0, 300, 300)
    G.DrawString(CStr(ページ), myFont, bluePen, 40, 40)
    bmpPen.Dispose()
    bluePen.Dispose()
    myFont.Dispose()
  End Sub
========================================


先の VB6 の Timer イベントの処理と、上記の VB.NET の PrintPage イベントの
処理とを、よく見比べて見てください。使っているメソッドやオブジェクトこそ異なりますが、
処理の流れとしては、さほど大きな違いはありませんよね。



なお、5ページ分印刷するからといって、
  Private Sub PrintDocument1_PrintPage(……
    For 現在のページ番号 = 1 To 終了ページ番号
      Call DrawPage(現在のページ番号, e)
      If 現在のページ番号 > 終了ページ番号 Then
        e.HasMorePages = False
      Else
        e.HasMorePages = True
      End If
    Next
  End Sub
といった書き方はできません。

[ツリー表示へ]
タイトル改ページ
記事No3317
投稿日: 2006/03/18(Sat) 00:24
投稿者マサノリ
[OSのVer]:Windows    [VBのVer]:VB.NET  

 魔界の仮面弁士さん、YASさん、こんばんは。
 早速ながら、毎回の丁寧なご指導、重ね重ね感謝とお礼を申し上げる
 とともに、昨日の遅い時間および深夜にも関わらず、早速のご回答いただきま
 したことに、痛み入ります。本当に有難う御座いました。

 私も、やっとのことで、改ページの作業が無事うまく行くことができました。ご指導いただいた通り
に作って
みた中で、 

  @  ============
   Call DrawPage(現在のページ番号, e)  '★描画処理を Call★ 

    現在のページ番号 += 1

   ============
  
 A  ============
If 現在のページ番号 > 終了ページ番号 Then
      e.HasMorePages = False '★終了条件を満たしたら、このイベントの発生を止める★
    Else
      e.HasMorePages = True
    End If
 ============
  この上記の箇所ですが、
  PrintDocumnt1_Page(〜  )のプロシージャーの中では
@ のような印刷したい項目を、他にも私の場合ですと、タイトルを印刷して、
明細を印刷させて、Aの判定(改ページ替え)の処理をかけなくてはいけないのではないかと、理解さ
せていた
だきました(本当に、これで合っておりますでしょうか)。
上記のことを踏まえて、作成したところ、

@ タイトルを印刷
A 1行あける。
B 金額明細を印刷
C 改ページ替えする行数に達したか
C−1改ページ替えする行数に達していなければ、1行あけて、Bへ
C−2改ページ替えする行数に達していれば、改ページをし、@へ
 というような動きをさせることが出来ました。
 本当は、実際のプログラムを書かせて頂きたいのですが、あまりにも長くなり      
ますので, これ以上余分なスペースを頂くのは、控えさせて頂こうと思い、上記のような書き方
をさせて頂きましたが。
 とにかく、路頭に迷う事無く、無事にぺージ替え処理を完成させていただき、
 心より感謝致します。有難う御座いました。
 又、あきこさんもまだ、ご覧になって居られるかわかりませんが、違った形での
質問内容に大変参考させていただきました。有難う御座います。

[ツリー表示へ]