Page 480 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 通常モードに戻る ┃ INDEX ┃ ≪前へ │ 次へ≫ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ▼AccessVBAでプリンタの用紙サイズ制御 yn 04/1/13(火) 13:52 ┗Re:AccessVBAでプリンタの用紙サイズ制御 MJ 04/1/13(火) 14:23 ┣Re:AccessVBAでプリンタの用紙サイズ制御 yn 04/1/13(火) 15:28 ┗Re:AccessVBAでプリンタの用紙サイズ制御 yn 04/1/13(火) 15:44 ┣Re:サンプルコード1 MJ 04/1/13(火) 16:11 ┣Re:サンプルコード2 MJ 04/1/13(火) 16:13 ┗Re:サンプルコード3 MJ 04/1/13(火) 16:13 ┗Re:サンプルコード3 yn 04/1/13(火) 16:21 ┗Re:AccessVBAでプリンタの用紙サイズ制御 MJ 04/1/13(火) 16:38 ┗Re:AccessVBAでプリンタの用紙サイズ制御 yn 04/1/13(火) 16:47 ─────────────────────────────────────── ■題名 : AccessVBAでプリンタの用紙サイズ制御 ■名前 : yn ■日付 : 04/1/13(火) 13:52 -------------------------------------------------------------------------
PRTDEVMOD、PRTMIPを使ってReportで印刷する用紙のサイズ、方向、余白などをコントロールしています。 ほとんど問題ないのですが、 はがきサイズ、封筒長形3号、封筒角形2号の設定ができません。(プリンタはEPSON LP−7800Cで、手作業では選択可能です) PRTDEVMODEのPapersizeプロパティでは、各種の用紙サイズを指定する定数がありますが、上記用紙サイズがみあたりません。 FORMMODE?か何がのプロパティ(ちょっと忘れましたが)では、 直接文字列で"A4","B5"などと指定可能ですが、この場合の指定する文字列がわかりません。Access2000を使っています。用紙サイズが規定値に戻るバグがあり、SR−1をインストールしています。一度設定した内容をレポートが確実に保持していればいいのですが、移設したりすると、とたんにトラブルになります。設定方法、対策などご指導いただけないでしょうか。 |
こんにちは。 使用可能な用紙サイズや給紙方法等には、 プリンタによって違いがあり、 そのプリンタ固有のサイズがあったり、 また、定数として記載されている用紙サイズが すべて使用できるわけでもありません。 さらに、たとえ同じ用紙サイズでも、 設定すべきコードが同じとは限りません。 (典型的なA4やB5などは統一されているようですが) そこで、当方では、 WinAPIのDeviceCapabilitiesAを使用して、 プリンタの性能(用紙サイズや給紙方法)を取得してから、 PrtDevMode ないし PrtMip で使用するようにしていますが、 如何でしょう。 |
早速、ありがとうございます。WinAPIは使ったことがありません。 具体的にお教えいただけないでしょうか。 ▼MJ さん: >こんにちは。 > >使用可能な用紙サイズや給紙方法等には、 >プリンタによって違いがあり、 >そのプリンタ固有のサイズがあったり、 >また、定数として記載されている用紙サイズが >すべて使用できるわけでもありません。 >さらに、たとえ同じ用紙サイズでも、 >設定すべきコードが同じとは限りません。 >(典型的なA4やB5などは統一されているようですが) > >そこで、当方では、 >WinAPIのDeviceCapabilitiesAを使用して、 >プリンタの性能(用紙サイズや給紙方法)を取得してから、 >PrtDevMode ないし PrtMip で使用するようにしていますが、 >如何でしょう。 |
先ほどはお礼形式で送信してしまいました。 WindowsAPIについては知識がありません。 具体的に、 用紙情報の取得、設定についてお教えいただけませんか。 |
え〜と、説明が大変なのでサンプルコードを提示します。(^_^;) あとで、解析なさって見てください。 GetPrinterCapabilitiesを起動することにより、 lngCountには、取得件数 NameListには、取得名称 ItemListには、取得名称に対応するコード が格納されます。 結果は、イミディエイトウィンドウ等で確認して下さい。 長いので分割します。 −以下、サンプルコード1− Option Compare Database Option Explicit Public Type PRINTERDEVICE strDriverName As String strDeviceName As String strPort As String End Type Private Declare Function GetProfileSection Lib "kernel32" Alias "GetProfileSectionA" (ByVal lpAppName As String, _ ByVal lpReturnedString As String, _ ByVal nSize As Long) As Long Private Declare Function DeviceCapabilitiesLong Lib "winspool.drv" Alias "DeviceCapabilitiesA" (ByVal lpDeviceName As String, _ ByVal lpPort As String, _ ByVal iIndex As Long, _ ByVal lpOutput As Long, _ ByVal lpDevMode As Long) As Long Private Declare Function DeviceCapabilitiesString Lib "winspool.drv" Alias "DeviceCapabilitiesA" (ByVal lpDeviceName As String, _ ByVal lpPort As String, _ ByVal iIndex As Long, _ ByVal lpOutput As String, _ ByVal lpDevMode As Long) As Long Private Declare Function DeviceCapabilitiesAny Lib "winspool.drv" Alias "DeviceCapabilitiesA" (ByVal lpDeviceName As String, _ ByVal lpPort As String, _ ByVal iIndex As Long, _ lpOutput As Any, _ ByVal lpDevMode As Long) As Long 'DeviceCapabilitiesAのiIndex指定値 Private Const DC_BINADJUST = 19 'pDevModeで指定された用紙トレイの位置 '戻り値は次の定数のうち1つ Private Const DCBA_FACEDOWNCENTER = &H101 Private Const DCBA_FACEDOWNLEFT = &H102 Private Const DCBA_FACEDOWNNONE = &H100 Private Const DCBA_FACEDOWNRIGHT = &H103 Private Const DCBA_FACEUPCENTER = &H1 Private Const DCBA_FACEUPLEFT = &H2 Private Const DCBA_FACEUPNONE = &H0 Private Const DCBA_FACEUPRIGHT = &H3 Private Const DC_BINNAMES = 12 '用紙ビン名を格納する配列(24バイトごとの文字列の並び) Private Const DC_BINS = 6 '使用可能なビンのインデックスの配列(DCBIN_XXXの整数値配列) Private Const DC_COPIES = 18 '最大コピー数 Private Const DC_DATATYPE_PRODUCED = 21 'プリンタドライバがサポートするデータタイプ数 Private Const DC_DRIVER = 11 'プリンタドライバーのバージョン番号 Private Const DC_DUPLEX = 7 '両面印刷のサポートレベル Private Const DC_EMF_COMPLIANT = 20 'プリンタドライバがEMFをサポートしているとき1 Private Const DC_ENUMRESOLUTIONS = 13 '使用可能な解像度リスト Private Const DC_EXTRA = 9 'プリンタドライバのDEVMODE構造体に付加されたデータのバイト数 Private Const DC_FIELDS = 1 'DEVMODE構造体のdmFiledsを返す Private Const DC_FILEDEPENDENCIES = 14 'ドライバがインストールされたときロードする必要のあるファイル数(64バイトごとの文字列の並び) Private Const DC_MAXEXTENT = 5 '最大用紙サイズを格納するPOINTAPI構造体 Private Const DC_MINEXTENT = 4 '最小用紙サイズを格納するPOINTAPI構造体 Private Const DC_ORIENTATION = 17 '用紙の向き '戻り値は以下の定数の1つ '0 横向きは不可 '90 縦向きを90度傾ける '270 同、270度(例:ドットマトリクスプリンタ) Private Const DC_PAPERNAMES = 16 '用紙サイズ名のリスト(64バイトごとの文字列の並び) Private Const DC_PAPERS = 2 '用紙サイズのインデント(DMPAPER_XXX) Private Const DC_PAPERSIZE = 3 '用紙サイズ(1/10mm単位の用紙の寸法を格納するPOINTAPI構造体の配列) Private Const DC_SIZE = 8 'DEVMODE構造体のdmSizeメンバ Private Const DC_TRUETYPE = 15 'TrueTypefフォントを使用するための能力を示す定数の組み合わせ '次の定数の組み合わせ Private Const DCTT_BITMAP = &H1& 'TrueTypeフォントをビットマップとして印刷可能 Private Const DCTT_DOWNLOAD = &H2& 'TrueTypeフォントをダウンロード Private Const DCTT_DOWNLOAD_OUTLINE = &H8& 'アウトラインTrueTypeフォントをダウンロード Private Const DCTT_SUBDEV = &H4& '代替デバイスフォント Private Const DC_VERSION = 10 'プリンタドライバに適合するバージョン |
Public Function GetPrinterCapabilities() As Boolean Dim PD() As PRINTERDEVICE Dim DP As PRINTERDEVICE Dim NameList() As String Dim ItemList() As Integer Dim lngCount(2) As Long Dim idx As Integer ' インストールプリンタの取得 lngCount(0) = GetPrinterDevice(PD()) If lngCount(0) > 0 Then For idx = 0 To lngCount(0) - 1 ' プリンタごとの用紙サイズ及び給紙方法の取得 DP.strDeviceName = PD(idx).strDeviceName DP.strPort = PD(idx).strPort ' プリンタの用紙サイズを取得 Erase NameList Erase ItemList lngCount(1) = GetDeviceCapabilitiesString(DP, DC_PAPERNAMES, NameList()) lngCount(2) = GetDeviceCapabilitiesAny(DP, DC_PAPERS, ItemList()) ' プリンタの給紙方法を取得 Erase NameList Erase ItemList lngCount(1) = GetDeviceCapabilitiesString(DP, DC_BINNAMES, NameList()) lngCount(2) = GetDeviceCapabilitiesAny(DP, DC_BINS, ItemList()) Next idx End If Exit Function End Function Private Function GetPrinterDevice(PD() As PRINTERDEVICE) As Long ' WIN.INIよりインストールプリンタを取得 Dim lpReturnedString As String Dim lngSize As Long Dim lngCount As Long Dim intPos1 As Integer Dim intPos2 As Integer Dim strBuff As String Dim intCol1 As Integer Dim intCol2 As Integer lpReturnedString = Space(32767) lngSize = GetProfileSection("Devices", lpReturnedString, 32767) If lngSize > 0 Then lpReturnedString = Left(lpReturnedString, lngSize) End If lngCount = 0 intPos1 = 1 Do While intPos1 < lngSize intPos2 = InStr(intPos1, lpReturnedString, vbNullChar) If intPos2 > 0 Then strBuff = Mid(lpReturnedString, intPos1, intPos2 - intPos1) If Len(strBuff) > 0 Then ReDim Preserve PD(lngCount) intCol1 = InStr(strBuff, "=") intCol2 = InStr(strBuff, ",") PD(lngCount).strDeviceName = Left(strBuff, intCol1 - 1) PD(lngCount).strDriverName = Mid(strBuff, intCol1 + 1, intCol2 - 1 - intCol1) PD(lngCount).strPort = Right(strBuff, Len(strBuff) - intCol2) lngCount = lngCount + 1 End If End If intPos1 = intPos2 + 1 Loop GetPrinterDevice = lngCount End Function |
Private Function GetDeviceCapabilitiesString(PD As PRINTERDEVICE, iIndex As Long, strList() As String) As Long ' プリンタの名称配列を取得 Dim lngCount As Long Dim intSize As Integer Dim lpOutput As String Dim idx As Integer Dim strBuff As String lngCount = DeviceCapabilitiesLong(PD.strDeviceName, PD.strPort, iIndex, 0, 0) If lngCount > 0 Then ReDim strList(lngCount - 1) Select Case iIndex Case DC_PAPERNAMES intSize = 64 Case DC_BINNAMES intSize = 24 End Select lpOutput = String(intSize * lngCount, 0) lngCount = DeviceCapabilitiesString(PD.strDeviceName, PD.strPort, iIndex, lpOutput, 0) If lngCount > 0 Then lpOutput = StrConv(lpOutput, vbFromUnicode) For idx = 0 To lngCount - 1 strBuff = MidB(lpOutput, idx * intSize + 1, intSize) strBuff = StrConv(strBuff, vbUnicode) & vbNullChar strList(idx) = Left(strBuff, InStr(strBuff, vbNullChar) - 1) Next idx End If End If GetDeviceCapabilitiesString = lngCount End Function Private Function GetDeviceCapabilitiesAny(PD As PRINTERDEVICE, iIndex As Long, intList() As Integer) As Long ' プリンタのインデックス配列を取得 Dim lngCount As Long lngCount = DeviceCapabilitiesLong(PD.strDeviceName, PD.strPort, iIndex, 0, 0) If lngCount > 0 Then ReDim intList(lngCount - 1) lngCount = DeviceCapabilitiesAny(PD.strDeviceName, PD.strPort, iIndex, intList(0), 0) End If GetDeviceCapabilitiesAny = lngCount End Function |
貴重な情報をありがとうございます。 はがきや各種用紙を使って一度レポートを作成し、 WinAPIのDeviceCapabilitiesAでその値を取得。 取得した値をVBAで(確か)PRTDEVMODEで、 対応するプロパティに設定するという考え方でよろしいのでしょうか。 困難を極めていましたので、今晩の楽しみができました。 いろいろやって見ます。 うまくいくといいと思います。 |
長々と、提示しましたが、 もっと単純にするならば、ページ設定のダイアログを表示するだけ という方法もあります。 ただ、この方法だと、レポートごとにいちいち表示しなければならないので… 当方では、各レポートを、一括で設定できるようにしたいがために この方法をとり、提示したコードに加え、 すべてのレポートのページ設定情報の取得及び設定を行っています。 |
▼MJ さん: >長々と、提示しましたが、 >もっと単純にするならば、ページ設定のダイアログを表示するだけ >という方法もあります。 >ただ、この方法だと、レポートごとにいちいち表示しなければならないので… > >当方では、各レポートを、一括で設定できるようにしたいがために >この方法をとり、提示したコードに加え、 >すべてのレポートのページ設定情報の取得及び設定を行っています。 ありがとうございます。 ダイアログで設定という方法なら特に問題はないのですが、 私の場合も同様にすべてレポートの印刷条件をコントロールしたいため 苦労していました。 |