過去ログ

                                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をインストールしています。一度設定した内容をレポートが確実に保持していればいいのですが、移設したりすると、とたんにトラブルになります。設定方法、対策などご指導いただけないでしょうか。

 ───────────────────────────────────────  ■題名 : Re:AccessVBAでプリンタの用紙サイズ制御  ■名前 : MJ  ■日付 : 04/1/13(火) 14:23  -------------------------------------------------------------------------
   こんにちは。

使用可能な用紙サイズや給紙方法等には、
プリンタによって違いがあり、
そのプリンタ固有のサイズがあったり、
また、定数として記載されている用紙サイズが
すべて使用できるわけでもありません。
さらに、たとえ同じ用紙サイズでも、
設定すべきコードが同じとは限りません。
(典型的なA4やB5などは統一されているようですが)

そこで、当方では、
WinAPIのDeviceCapabilitiesAを使用して、
プリンタの性能(用紙サイズや給紙方法)を取得してから、
PrtDevMode ないし PrtMip で使用するようにしていますが、
如何でしょう。

 ───────────────────────────────────────  ■題名 : Re:AccessVBAでプリンタの用紙サイズ制御  ■名前 : yn  ■日付 : 04/1/13(火) 15:28  -------------------------------------------------------------------------
   早速、ありがとうございます。WinAPIは使ったことがありません。
具体的にお教えいただけないでしょうか。
▼MJ さん:
>こんにちは。
>
>使用可能な用紙サイズや給紙方法等には、
>プリンタによって違いがあり、
>そのプリンタ固有のサイズがあったり、
>また、定数として記載されている用紙サイズが
>すべて使用できるわけでもありません。
>さらに、たとえ同じ用紙サイズでも、
>設定すべきコードが同じとは限りません。
>(典型的なA4やB5などは統一されているようですが)
>
>そこで、当方では、
>WinAPIのDeviceCapabilitiesAを使用して、
>プリンタの性能(用紙サイズや給紙方法)を取得してから、
>PrtDevMode ないし PrtMip で使用するようにしていますが、
>如何でしょう。

 ───────────────────────────────────────  ■題名 : Re:AccessVBAでプリンタの用紙サイズ制御  ■名前 : yn  ■日付 : 04/1/13(火) 15:44  -------------------------------------------------------------------------
   先ほどはお礼形式で送信してしまいました。
WindowsAPIについては知識がありません。
具体的に、
用紙情報の取得、設定についてお教えいただけませんか。

 ───────────────────────────────────────  ■題名 : Re:サンプルコード1  ■名前 : MJ  ■日付 : 04/1/13(火) 16:11  -------------------------------------------------------------------------
   え〜と、説明が大変なのでサンプルコードを提示します。(^_^;)
あとで、解析なさって見てください。

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            'プリンタドライバに適合するバージョン

 ───────────────────────────────────────  ■題名 : Re:サンプルコード2  ■名前 : MJ  ■日付 : 04/1/13(火) 16:13  -------------------------------------------------------------------------
   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

 ───────────────────────────────────────  ■題名 : Re:サンプルコード3  ■名前 : MJ  ■日付 : 04/1/13(火) 16:13  -------------------------------------------------------------------------
   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

 ───────────────────────────────────────  ■題名 : Re:サンプルコード3  ■名前 : yn <ynakajima@njlab.co.jp>  ■日付 : 04/1/13(火) 16:21  -------------------------------------------------------------------------
   貴重な情報をありがとうございます。
はがきや各種用紙を使って一度レポートを作成し、
WinAPIのDeviceCapabilitiesAでその値を取得。
取得した値をVBAで(確か)PRTDEVMODEで、
対応するプロパティに設定するという考え方でよろしいのでしょうか。

困難を極めていましたので、今晩の楽しみができました。
いろいろやって見ます。
うまくいくといいと思います。

 ───────────────────────────────────────  ■題名 : Re:AccessVBAでプリンタの用紙サイズ制御  ■名前 : MJ  ■日付 : 04/1/13(火) 16:38  -------------------------------------------------------------------------
   長々と、提示しましたが、
もっと単純にするならば、ページ設定のダイアログを表示するだけ
という方法もあります。
ただ、この方法だと、レポートごとにいちいち表示しなければならないので…

当方では、各レポートを、一括で設定できるようにしたいがために
この方法をとり、提示したコードに加え、
すべてのレポートのページ設定情報の取得及び設定を行っています。

 ───────────────────────────────────────  ■題名 : Re:AccessVBAでプリンタの用紙サイズ制御  ■名前 : yn <ynakajima@njlab.co.jp>  ■日付 : 04/1/13(火) 16:47  -------------------------------------------------------------------------
   ▼MJ さん:
>長々と、提示しましたが、
>もっと単純にするならば、ページ設定のダイアログを表示するだけ
>という方法もあります。
>ただ、この方法だと、レポートごとにいちいち表示しなければならないので…
>
>当方では、各レポートを、一括で設定できるようにしたいがために
>この方法をとり、提示したコードに加え、
>すべてのレポートのページ設定情報の取得及び設定を行っています。
ありがとうございます。
ダイアログで設定という方法なら特に問題はないのですが、
私の場合も同様にすべてレポートの印刷条件をコントロールしたいため
苦労していました。

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━    通常モードに戻る  ┃  INDEX  ┃  ≪前へ  │  次へ≫    ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━                                 Page 480