- PR -

用紙サイズ(幅、高さ)の指定

投稿者投稿内容
O-Nadegata
会議室デビュー日: 2004/10/20
投稿数: 13
投稿日時: 2004-11-20 12:00
VB.NETの連続帳票の印刷で、用紙サイズの幅、高さを指定したいのですが
うまくいきません。

下のコードを実行すると
------------------------------------------------
PrintDoc.DefaultPageSettings.PaperSize.Height = 10
PrintDoc.DefaultPageSettings.PaperSize.Width = 10
PrintDoc.Print()
------------------------------------------------
「Kind が、Custom に設定されていません。」というエラーが出たので、

------------------------------------------------
Dim ppSize As Printing.PaperSize = _
New Printing.PaperSize("Custom Paper size",10,10)
PrintDoc.DefaultPageSettings.PaperSize = ppSize
------------------------------------------------
という風に書き直してみたのですが、
今度はエラーは出ないのですが用紙サイズが反映されていません。

助言できるかたがいましたら宜しくお願いいたします。
O-Nadegata
会議室デビュー日: 2004/10/20
投稿数: 13
投稿日時: 2004-11-20 13:05
自己レスです。

これはVB.NETのバグかも・・・

http://www.dotnet247.com/247reference/msgs/31/155147.aspx

英語なのでよく分からないですが、
真ん中ちょっと下あたりに
「this is a bug」
と書いてあるので、
O-Nadegata
会議室デビュー日: 2004/10/20
投稿数: 13
投稿日時: 2004-11-25 17:53
http://support.microsoft.com/default.aspx?scid=kb;ja;436118

に回避策が載っていました。

が、しかし同じように実装しても
変わりません。

他の回避策をご存知の方、ご教授お願いします。
todo
ぬし
会議室デビュー日: 2003/07/23
投稿数: 682
投稿日時: 2004-11-25 18:43
> http://support.microsoft.com/default.aspx?scid=kb;ja;436118
Pocket PCの情報ですよ。

Win2000ならば、OSに用紙サイズを登録してみては?

コントロールパネル
→プリンタ
→サーバーのプロパティ
→「新しい用紙を作成する」

参考
[VB] Visual Basic 6.0 における印刷関連の制限事項および注意点
O-Nadegata
会議室デビュー日: 2004/10/20
投稿数: 13
投稿日時: 2004-11-25 19:22
todoさん返信ありがとうございます。

私の環境はWindowsXPですが、
OSにMyPaperという名前で用紙サイズを登録してみました。

さらに下のコードを実行したのですが
やはり
「Kind が、Custom に設定されていません。」というエラーが
出てしまいます。

-------------------------------------
Dim ps As Printing.PaperSize
For Each ps In pDoc.PrinterSettings.PaperSizes
 If ps.PaperName.Equals("MyPaper") Then
  ps.Height = decGenpyoTsize 'ここでエラー
  ps.Width = decGenpyoYsize
  pDoc.DefaultPageSettings.PaperSize = ps
 End If
Next
-------------------------------------

おかしいのは、ps.Kind は Customになっているのに
上記のようなエクセプションが発生する事です。

[VB] Visual Basic 6.0 における印刷関連の制限事項および注意点

>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
作成した用紙をシステムの規定値に設定するとユーザー定義の
用紙サイズで印刷が可能です。
プログラムから作成した用紙サイズに変更することはできません。
あらかじめシステムの既定値で設定してください
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
と書いてあるので、やはりプログラムから指定することは
無理なのでしょうか?


todo
ぬし
会議室デビュー日: 2003/07/23
投稿数: 682
投稿日時: 2004-11-26 13:20
新しい用紙を作成する」 にて10x10を設定して

Dim ps As Printing.PaperSize
For Each ps In pDoc.PrinterSettings.PaperSizes
 If ps.PaperName.Equals("MyPaper") Then
   pDoc.DefaultPageSettings.PaperSize = ps
 End If
Next

用紙サイズが10x10に設定されるはずです。

プログラムから用紙サイズを任意に指定するなら、Win32APIを使うことになるでしょう。

VB6のサンプル(検索キー:用紙)
http://www.vbvbvb.com/jp/gtips/index.html
O-Nadegata
会議室デビュー日: 2004/10/20
投稿数: 13
投稿日時: 2004-11-27 19:45
Win32Apiを使ってみました。

以下の2つの方法を試してみました。
が、いずれも惜しいところまでいくのですが
結果的にはカスタムの用紙を設定する事が出来ませんでした。
todoさんに教えてもらったページはVBで書かれているので、
VB.NETに書き直した場合におかしくなるのですかね。

とりあえず、やったことと結果を以下に示します。

■方法1
 参考にしたページ
  http://www.vbvbvb.com/jp/gtips/0351/gSetForm.html

 1.プリンタとFAX
    −ファイル→サーバのプロパティ
      -新しい用紙を作成する
   で、「MyPaper」を追加。
 2.上記ページのサンプルで、余白を設定しているところを
   用紙の幅高さを設定するように修正。

 結果
  「MyPaper」の情報は取得出来るが、一部取得データ
    に不具合がある。
     例)
      1で
       用紙幅:10
       用紙高さ:20
       余白左:3
       余白右:4
       余白上:5
       余白下:6
      と指定したにもかかわらず、
      プログラムで取得したデータは
       用紙幅:10
       用紙高さ:20
       余白左:3
       余白右:14←
       余白上:5
       余白下:6
      となってしまう。
    さらに、プログラムで指定した用紙サイズ、余白が
    プロパティの用紙サイズに反映されない。
■方法2
  方法1で実現できなかった為、カスタムの用紙サイズを
  プログラムから追加する方法を試す。
 参考にしたページ
  http://www.vbvbvb.com/jp/gtips/0351/gAddForm.html
 1.上記ページのサンプルコードをVB.NET風に書き直した
  以外は同じ実装。
 結果
  プリンタとFAX
   −ファイル→サーバのプロパティ
  にはプログラムから追加した用紙サイズが
  追加されていた。
  しかし、プリンタのプロパティの用紙サイズの
  リストには追加されていなかった。


O-Nadegata
会議室デビュー日: 2004/10/20
投稿数: 13
投稿日時: 2004-11-30 14:24
で、できましたー。。。。
つ、つらかった。

で、なぜ出来なかったかというと、
用紙の余白を指定するとき、
leftとtopはそのまま余白のサイズを
指定してよいのだが、
rightとbottomはそれぞれ
 reight = 用紙幅 - 余白
 bottom = 用紙高さ - 余白
と指定しないと駄目なようです。

http://www.vbvbvb.com/jp/gtips/0351/gSetForm.html

このページのサンプルをじっくり読めばもっと早く気づいた
のでしょうが・・・

ということでVB.NETのサンプルを乗せておきます。
あと、todoさん多くのアドバイスありがとうございました。

----------------------------------------
' プリンタアクセス権を定義する構造体の宣言
  Public Structure PRINTER_DEFAULTS
Dim pDatatype As Integer
Dim pDevMode As Integer
Dim DesiredAccess As Integer
End Structure

' 標準的な権利を要求することを示す定数の宣言
Public Const STANDARD_RIGHTS_REQUIRED = &HF0000
'プリンタアクセス権の管理者権限を示す定数の宣言
Public Const PRINTER_ACCESS_ADMINISTER = &H4&
' プリンタアクセス権のユーザー権限を示す定数の宣言
Public Const PRINTER_ACCESS_USE = &H8&
' プリンタアクセス権すべての権限を示す定数の宣言
Public Const PRINTER_ALL_ACCESS = _
(STANDARD_RIGHTS_REQUIRED Or _
PRINTER_ACCESS_ADMINISTER Or _
PRINTER_ACCESS_USE)


' デバイス名の長さを示す定数の宣言
Public Const CCHDEVICENAME = 32
' フォーム名の長さを示す定数の宣言
Public Const CCHFORMNAME = 32

' ユーザー定義の用紙を示す定数の宣言
Public Const FORM_USER = &H0&

' 詳細エラーはないことを示す定数の宣言
Public Const ERROR_SUCCESS = 0&
' 用紙名が無効であることを示す定数の宣言
Public Const ERROR_INVALID_FORM_NAME = 1902&

' 幅と高さを定義する構造体の宣言
Public Structure SIZEL
Public cx As Int32
Public cy As Int32
End Structure

' 矩形を定義する構造体の宣言
Public Structure RECTL
Public left As Int32
Public top As Int32
Public right As Int32
Public bottom As Int32
End Structure


' 用紙情報を定義する構造体の宣言
Public Structure FORM_INFO_1
Public Flags As Int32
Public pName As String
Public Size As SIZEL
Public ImageableArea As RECTL
End Structure



' 用紙が有効であること示す定数の宣言
Public Const DM_PAPERSIZE = &H2&


' プリンタのオブジェクトハンドルを取得する関数の宣言
Public Declare Function OpenPrinter Lib "winspool.drv" _
Alias "OpenPrinterA" _
( _
<MarshalAs(UnmanagedType.LPStr)> ByVal pPrinterName As String, _
ByRef phPrinter As Integer, _
ByVal pDefault As PRINTER_DEFAULTS) As Integer



Public Declare Auto Function GetForm Lib "winspool.drv" _
Alias "GetFormA" _
(ByVal hPrinter As Integer, _
<MarshalAs(UnmanagedType.LPStr)> ByVal pFormName As String, _
ByVal Level As Integer, _
ByRef pForm As Byte, _
ByVal cbBuf As Integer, _
ByRef pcbNeeded As Integer) As Integer



' ある位置から別の位置にメモリブロックを移動する関数の宣言
Public Declare Sub MoveMemory Lib "kernel32.dll" _
Alias "RtlMoveMemory" _
(ByRef Destination As FORM_INFO_1, _
ByRef Source As Byte, _
ByVal Length As Integer)

' ある位置から別の位置にメモリブロックを移動する関数の宣言
Public Declare Sub MoveMemory Lib "kernel32.dll" _
Alias "RtlMoveMemory" _
(ByRef Destination As Byte, _
ByRef Source As FORM_INFO_1, _
ByVal Length As Integer)

' プリンタの用紙情報を設定する関数の宣言
Public Declare Function SetForm Lib "winspool.drv" _
Alias "SetFormA" _
(ByVal hPrinter As Integer, _
<MarshalAs(UnmanagedType.LPStr)> ByVal pFormName As String, _
ByVal Level As Integer, _
ByRef pForm As Byte) As Integer

' プリンタのオブジェクトハンドルを破棄する関数の宣言
Public Declare Function ClosePrinter Lib "winspool.drv" _
(ByVal hPrinter As Integer) As Integer

Dim m_pDoc As System.Drawing.Printing.PrintDocument

Sub New(ByVal pDoc As System.Drawing.Printing.PrintDocument)
m_pDoc = pDoc
End Sub

Public Sub FormUpdate()


Dim strPrinterDeviceName As String
Dim udtPrinterDefaults As PRINTER_DEFAULTS
Dim lngPrinterHandle As Integer = 0
Dim strFormInfo1Name As String
Dim lngFormInfo1Level As Integer
Dim lngFormInfo1Needed As Integer = 0
Dim bytFormInfo1Buffer() As Byte
Dim udtFormInfo1 As FORM_INFO_1
Dim lngWin32apiResultCode As Integer


' プリンタ名を指定
strPrinterDeviceName = _
m_pDoc.PrinterSettings.PrinterName

' プリンタアクセス権を指定
With udtPrinterDefaults
.DesiredAccess = PRINTER_ALL_ACCESS
End With

' プリンタのオブジェクトハンドルを取得
lngWin32apiResultCode = _
OpenPrinter(strPrinterDeviceName, _
lngPrinterHandle, _
udtPrinterDefaults)

' 用紙名を指定
strFormInfo1Name = "MyPaper"


' 構造体のレベルを指定
lngFormInfo1Level = 1
' バッファに必要なサイズを取得
lngWin32apiResultCode = _
GetForm(lngPrinterHandle, _
strFormInfo1Name, _
lngFormInfo1Level, _
vbNullString, _
0, _
lngFormInfo1Needed) 'vbNullString


If lngFormInfo1Needed <= 0 Then
FormAdd()
lngWin32apiResultCode = _
GetForm(lngPrinterHandle, _
strFormInfo1Name, _
lngFormInfo1Level, _
vbNullString, _
0, _
lngFormInfo1Needed) 'vbNullString
If lngFormInfo1Needed <= 0 Then
GoTo TerminateGetForm
End If
End If

'バッファを確保()
'lngFormInfo1Needed()
Dim buff As Integer = CInt(lngFormInfo1Needed.ToString) - 1
ReDim _
bytFormInfo1Buffer _
(buff)
'用紙情報を取得()
lngWin32apiResultCode = _
GetForm(lngPrinterHandle, _
strFormInfo1Name, _
lngFormInfo1Level, _
bytFormInfo1Buffer(0), _
lngFormInfo1Needed, _
lngFormInfo1Needed)



'取得した用紙情報を構造体へ移動()
MoveMemory(udtFormInfo1, _
bytFormInfo1Buffer(0), _
Len(udtFormInfo1))

With udtFormInfo1.Size
.cx = 50000
.cy = 50000
End With
With udtFormInfo1.ImageableArea
'5mmの余白を指定()
.left = 5
.top = 5
'5mmの余白を指定()
.right = 50000 - 5 '←幅-余白 で指定する
.bottom = 50000 - 5 '←高さ-余白 で指定する
End With

'指定した用紙情報をバッファへ移動
MoveMemory(bytFormInfo1Buffer(0), _
udtFormInfo1, _
Len(udtFormInfo1))
'用紙情報を設定
lngWin32apiResultCode = _
SetForm(lngPrinterHandle, _
strFormInfo1Name, _
lngFormInfo1Level, _
bytFormInfo1Buffer(0))

TerminateGetForm:
'プリンタオブジェクトをクローズ()
lngWin32apiResultCode = _
ClosePrinter(lngPrinterHandle)
End Sub

----------------------------------------



スキルアップ/キャリアアップ(JOB@IT)