我的VB程序中用data report打印报表,现有两报表A、B,  A报表是A4大小,B报表是自定义纸型,比A4大些。运行时,若此时打印机的默认纸型是A4,则B报表会出错,提示纸张超出,若此时打印机的默认纸型是我的自定义的那种纸型,则A报表也按自定义的纸张大小显示而不是A4版面了。一般情况下默认纸型都是A4,我如何才能在调用B报表前,用代码改变打印机的默认纸型成为自定义的,在报表打印完成后用又代码还原成A4的?
或者有其他方法能解决我的问题也行,比如用代码来设定纸张大小。谢谢!

解决方案 »

  1.   

    '*Constants  used  in  the  DevMode  structure  
    Private  Const  CCHDEVICENAME  =  32  
    Private  Const  CCHFORMNAME  =  32  
     
    '*Constants  for  NT  security  
    Private  Const  STANDARD_RIGHTS_REQUIRED  =  &HF0000  
    Private  Const  PRINTER_ACCESS_ADMINISTER  =  &H4  
    Private  Const  PRINTER_ACCESS_USE  =  &H8  
    Private  Const  PRINTER_ALL_ACCESS  =  (STANDARD_RIGHTS_REQUIRED  Or  PRINTER_ACCESS_ADMINISTER  Or  PRINTER_ACCESS_USE)  
     
    '*Constants  used  to  make  changes  to  the  values  contained  in  the  DevMode  
    Private  Const  DM_MODIFY  =  8  
    Private  Const  DM_COPY  =  2  
    Private  Const  DM_DUPLEX  =  &H1000&  
    Private  Const  DMDUP_SIMPLEX  =  1  
    Private  Const  DMDUP_VERTICAL  =  2  
    Private  Const  DMDUP_HORIZONTAL  =  3  
     
    Private  Const  DM_IN_BUFFER  As  Long  =  8  
    Private  Const  DM_OUT_BUFFER  As  Long  =  2  
    Private  Const  DM_ORIENTATION  As  Long  =  &H1  
    Private  Const  DM_PAPERSIZE  =  &H2&  
    Private  Const  DM_PAPERWIDTH  =  &H8&  
    Private  Const  DM_PAPERLENGTH  =  &H4&  
     
    Private  Type  DEVMODE  
           dmDeviceName                As  String  *  32  
           dmSpecVersion              As  Integer  
           dmDriverVersion          As  Integer  
           dmSize                            As  Integer  
           dmDriverExtra              As  Integer  
           dmFields                        As  Long  
           dmOrientation              As  Integer  
           dmPaperSize                  As  Integer  
           dmPaperLength              As  Integer  
           dmPaperWidth                As  Integer  
           dmScale                          As  Integer  
           dmCopies                        As  Integer  
           dmDefaultSource          As  Integer  
           dmPrintQuality            As  Integer  
           dmColor                          As  Integer  
           dmDuplex                        As  Integer  
           dmYResolution              As  Integer  
           dmTTOption                    As  Integer  
           dmCollate                      As  Integer  
           dmFormName                    As  String  *  32  
           dmUnusedPadding          As  Integer  
           dmBitsPerPel                As  Integer  
           dmPelsWidth                  As  Long  
           dmPelsHeight                As  Long  
           dmDisplayFlags            As  Long  
           dmDisplayFrequency    As  Long  
    End  Type  
     
    Private  Type  PRINTER_DEFAULTS  
           pDataType                      As  String  
           pDevMode                        As  Long  
           DesiredAccess              As  Long  
    End  Type  
     
    Private  Type  PRINTER_INFO_2  
           pServerName                  As  Long  
           pPrinterName                As  Long  
           pShareName                    As  Long  
           pPortName                      As  Long  
           pDriverName                  As  Long  
           pComment                        As  Long  
           pLocation                      As  Long  
           pDevMode                        As  Long  
           pSepFile                        As  Long  
           pPrintProcessor          As  Long  
           pDataType                      As  Long  
           pParameters                  As  Long  
           pSecurityDescriptor  As  Long  
           Attributes                    As  Long  
           Priority                        As  Long  
           DefaultPriority          As  Long  
           StartTime                      As  Long  
           UntilTime                      As  Long  
           status                            As  Long  
           cJobs                              As  Long  
           AveragePPM                    As  Long  
    End  Type  
     
      

  2.   

    '*------DECLARATIONS  
    Private  Declare  Sub  CopyMemory  Lib  "kernel32"  Alias  "RtlMoveMemory"  _  
                   (hpvDest  As  Any,  hpvSource  As  Any,  _  
                   ByVal  cbCopy  As  Long)  
     
    Private  Declare  Function  OpenPrinter  Lib  "winspool.drv"  Alias  "OpenPrinterA"  _  
                   (ByVal  pPrinterName  As  String,  _  
                   phPrinter  As  Long,  pDefault  As  Any)  As  Long  
     
    Private  Declare  Function  ClosePrinter  Lib  "winspool.drv"  _  
                   (ByVal  hPrinter  As  Long)  As  Long  
     
    Private  Declare  Function  DocumentProperties  Lib  "winspool.drv"  Alias  "DocumentPropertiesA"  _  
                   (ByVal  hWnd  As  Long,  ByVal  hPrinter  As  Long,  _  
                   ByVal  pDeviceName  As  String,  pDevModeOutput  As  Any,  _  
                   pDevModeInput  As  Any,  ByVal  fMode  As  Long)  As  Long  
     
    Private  Declare  Function  GetPrinter  Lib  "winspool.drv"  Alias  "GetPrinterA"  _  
                   (ByVal  hPrinter  As  Long,  ByVal  level  As  Long,  _  
                   pPrinter  As  Any,  ByVal  cbBuf  As  Long,  pcbNeeded  As  Long)  As  Long  
     
    Private  Declare  Function  SetPrinter  Lib  "winspool.drv"  Alias  "SetPrinterA"  _  
                   (ByVal  hPrinter  As  Long,  ByVal  level  As  Long,  _  
                   pPrinter  As  Any,  ByVal  Command  As  Long)  As  Long  
     
    Private  Sub  Command1_Click()  
    Dim  uu  As  Boolean  
    If  Printer.PaperSize  <>  9  Then  
           uu  =  mySetPrinter(Printer.DeviceName,  1,  9,  0,  0)  
           Printer.EndDoc  
    End  If  
    End  Sub  
     
    Public  Function  mySetPrinter(prnName  As  String,  Optional  eOrientation  As  Integer,  Optional  iDmpaper  As  Integer,  Optional  iDmpaperLength  As  Single,  Optional  iDmpaperWidth  As  Single)  As  Boolean  
     
    Dim  bDevMode()                    As  Byte  
    Dim  bPrinterInfo2()          As  Byte  
    Dim  hPrinter                        As  Long  
    Dim  lResult                          As  Long  
    Dim  nSize                              As  Long  
    Dim  sPrnName                        As  String  
     
    Dim  dm                    As  DEVMODE  
    Dim  olddm              As  DEVMODE  
    Dim  pd                    As  PRINTER_DEFAULTS  
    Dim  pi2                  As  PRINTER_INFO_2  
     
           On  Error  GoTo  err_proc  
             
           sPrnName  =  prnName  
           pd.DesiredAccess  =  PRINTER_ALL_ACCESS  
             
           If  OpenPrinter(sPrnName,  hPrinter,  pd)  Then  
             
             
                   Call  GetPrinter(hPrinter,  2&,  0&,  0&,  nSize)  
                   ReDim  bPrinterInfo2(1  To  nSize)  As  Byte  
                   lResult  =  GetPrinter(hPrinter,  2,  bPrinterInfo2(1),  nSize,  nSize)  
                   Call  CopyMemory(pi2,  bPrinterInfo2(1),  Len(pi2))  
                   nSize  =  DocumentProperties(0&,  hPrinter,  sPrnName,  0&,  0&,  0)  
                   ReDim  bDevMode(1  To  nSize)  
                     
                   If  pi2.pDevMode  Then  
                           Call  CopyMemory(bDevMode(1),  ByVal  pi2.pDevMode,  Len(dm))  
                   Else  
                           Call  DocumentProperties(0&,  hPrinter,  sPrnName,  bDevMode(1),  0&,  DM_OUT_BUFFER)  
                   End  If  
                     
                   Call  CopyMemory(dm,  bDevMode(1),  Len(dm))  
                   Call  CopyMemory(olddm,  bDevMode(1),  Len(olddm))  
                     
                   With  dm  
                           If  eOrientation  <>  0  Then  
                                   .dmOrientation  =  eOrientation  
                                   .dmFields  =  DM_ORIENTATION  
                           End  If  
                           If  iDmpaper  <>  0  And  iDmpaper  <>  vbPRPSUser  Then  
                                   .dmPaperSize  =  iDmpaper  
                                   .dmFields  =  DM_PAPERSIZE  
                           End  If  
                           If  iDmpaper  =  vbPRPSUser  Then  
                                   .dmFields  =  DM_PAPERLENGTH  Or  DM_PAPERWIDTH  
                                   .dmPaperLength  =  iDmpaperLength  
                                   .dmPaperWidth  =  iDmpaperWidth  
                           End  If  
                   End  With  
             
                   Call  CopyMemory(bDevMode(1),  dm,  Len(dm))  
                     
                   Call  DocumentProperties(0&,  hPrinter,  sPrnName,  _  
                                                                   bDevMode(1),  bDevMode(1),  DM_IN_BUFFER  Or  _  
                                                                   DM_OUT_BUFFER)  
             
                   pi2.pDevMode  =  VarPtr(bDevMode(1))  
                     
                   lResult  =  SetPrinter(hPrinter,  2,  pi2,  0&)  
                     
                   Call  ClosePrinter(hPrinter)  
                   mySetPrinter  =  True  
           Else  
                   mySetPrinter  =  False  
           End  If  
             
           Exit  Function  
             
    err_proc:  
           mySetPrinter  =  False  
    End  Function  
     
    在2000下我也遇到过,不过是常规纸张的设置,至于自定义你可以试试,eOrientation是方向,iDmpaper  =  vbPRPSUser为自定义,  iDmpaperLength和iDmpaperWidth  是长和宽以上程序是网上zt的
      

  3.   

    vb报表里的纸张的大小是如何控制的? 
     
     
      如果您使用Win98/me系统,您可以设置VB的 printer object的Width和Height属性或Papersize属性调整打印的纸张大小。  相关信息请参考:   PaperSize Property   http://msdn.microsoft.com/library/en-us/vb98/html/vbproPaperSize.asp   Height, Width Properties   http://msdn.microsoft.com/library/en-us/vb98/html/vbproheight.asp  如果您使用Win2000/NT系统,纸张的大小由DevMode结构的四个属性决定:   dmPaperSize As Integer   dmPaperLength As Integer   dmPaperWidth As Integer   dmFormName As String * CCHFORMNAME  其中dmFormName用于NT系统中指定打印纸张大小为预定义的某个纸张(Form),但是VB的 printer object不支持FormName属性,您可以通过API函数DocumentProperties修改DevMode结构的dmFormName属性实现自定义打印。  分两步做:  1. 先在打印机目录下,从File菜单下进入Server Properties对话框,在这里您可以手工添加自定义纸张,您也可以用API函数AddForm在程序中添加自定义纸张。  2. 在您的程序中,用API函数DocumentProperties获得当前打印机的设置并修改dmFormName为前面添加的自定义纸张。  关于DevMode结构和DocumentProperties的使用可参考下面的例子。  Q282474 HOWTO: Print Using Custom Page Sizes on Windows NT/2000
      http://support.microsoft.com/support/kb/articles/q282/4/74.asp  Q180645 FIX: Cannot Change Page Settings During Print Job
      http://support.microsoft.com/support/kb/articles/q180/6/45.asp
     
      API函数的相关信息请参考:  AddForm  http://msdn.microsoft.com/library/en-us/gdi/prntspol_0prh.aspAddForm
    The AddForm function adds a form to the list of available forms that can be selected for the specified printer. BOOL AddForm(
      HANDLE hPrinter,  // handle to printer object
      DWORD Level,      // data-structure level
      LPBYTE pForm      // form information buffer
    );
    Parameters
    hPrinter 
    [in] Handle to the printer that supports printing with the specified form. Use the OpenPrinter or AddPrinter function to retrieve a printer handle. 
    Level 
    [in] Specifies the level of the structure to which pForm points. This value must be 1. 
    pForm 
    [in] Pointer to a FORM_INFO_1 structure. 
    Return Values
    If the function succeeds, the return value is a nonzero value.If the function fails, the return value is zero. To get extended error information, call GetLastError. Res
    An application can determine which forms are available for a printer by calling the EnumForms function. Requirements 
      Windows NT/2000/XP: Included in Windows NT 3.51 and later.
      Windows 95/98/Me: Unsupported.
      Header: Declared in Winspool.h; include Windows.h.
      Library: Use Winspool.lib.
      Unicode: Implemented as Unicode and ANSI versions.
      DocumentProperties  http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/prntspol_7k1f.asp
      

  4.   

    我平常这样用,很简单:Private Sub DataReport_Initialize()
        DataReport1.LeftMargin = 700
        DataReport1.RightMargin = 700
        DataReport1.TopMargin = 2.8 * 567
        DataReport1.BottomMargin = 2 * 567
    End Sub