delphi 水晶报表9 如何用代码连接rpt文件并更改sql?
还有就是怎么设置能直接打印不预览,
以及如何选择已经设置的自定义纸张的大小
谢谢,急

解决方案 »

  1.   

    unit print;
    interface
    uses SysUtils, WinSpool, Windows, Forms, Messages, Classes, printers, UCrpeClasses, UCrpe32, Unit_frmMain;
     {declare function and procedure  }
    function GetDefaultPrinterName(): PChar; //得到默認的印表機名稱
    function addpage(p: Pchar): Boolean; //添加一打印紙張類型名稱?300k
    function changepape(p: Pchar): Boolean; //改變當前的打印紙張設置
    function SetPaperSize(P: Pchar; W: Integer; L: Integer): Boolean; overload;
    function SetPaperSize(X, Y: Integer): boolean; overload; //設置紙張大小
    procedure initCrpe(Crpe: TCrpe; sender: TForm; showinForm: boolean = true);
    implementationvar
      hPrinter: THandle;
    function GetDefaultPrinterName(): PChar; //得到默認的印表機名稱
    var
      sIniFile, sSection, sKeyName, p, q: PChar;
    begin
      sIniFile := 'win.ini';
      sSection := 'windows';
      sKeyName := 'device';
      p := StrAlloc(80);
      q := StrAlloc(80);
      GetPrivateProfileString(sSection, sKeyName, nil, p, 80, sIniFile);
      StrLCopy(q, p, (strscan(p, ',') - p));
      Result := q;
    end;function addpage(p: Pchar): Boolean; //添加一打印紙張類型名稱?300k
    var
      FormInfo: TFormInfo1;
      PaperSize: TSize;
      PaperRect: TRect;
    begin
      FormInfo.Flags := FORM_USER;
      FormInfo.pName := p;
      PaperSize.cx := 100000;
      PaperSize.cy := 100000; //300k紙張的默認大小 1000mm*1000mm
      PaperRect.Left := 1;
      PaperRect.Top := 1;
      PaperRect.Right := 100000;
      PaperRect.Bottom := 100000; //紙張的邊距
      FormInfo.Size := PaperSize;
      FormInfo.ImageableArea := PaperRect;
      AddForm(hPrinter, 1, @FormInfo);
      Result := True;
    end;function changepape(p: Pchar): Boolean; //改變當前的打印紙張設置
    var
      FormInfos: array[1..1024] of Form_Info_1;
      cbNeeded, cReturned, neededsize: DWORD;
      i, j: integer;
      ppo: PRINTER_INFO_2;
      dev: PDeviceMode;
      ppp: string;
    begin
      ppp := string(p);
      EnumForms(hPrinter, 1, nil, 0, cbNeeded, cReturned);
      EnumForms(hPrinter, 1, @FormInfos, cbNeeded, cbNeeded, cReturned);
      j := 0;
      for i := 1 to cReturned do //通過輪尋找到300k的紙張的紙張類型排序號
        if FormInfos[i].pName = ppp then j := i;
      if j = 0 then
      begin
        addpage(p);
        j := cReturned + 1;
      end; //如無300k紙張則添加
      GetPrinter(hPrinter, 2, nil, 0, @NeededSize);
      GetPrinter(hPrinter, 2, @ppo, NeededSize, @NeededSize);
      dev := ppo.pDevMode;
      dev.dmPaperSize := j;
      ppo.pDevMode := dev;
      winspool.SetPrinter(hPrinter, 2, @ppo, 0); //定義印表機列表並選擇300k紙張
      Result := True;
    end;function SetPaperSize(P: Pchar; W: Integer; L: Integer): Boolean; overload; //用於NT系統
     //設置印表機的紙張類型?300k,並動態修改300k的大小和邊距
    var
      FormInfo: TFormInfo1;
      PaperSize: TSize;
      PaperRect: TRect;
    begin
      OpenPrinter(GetDefaultPrinterName, hPrinter, nil);
      changepape(p); //改變紙張類型定義
      FormInfo.Flags := FORM_USER;
      FormInfo.pName := P;
      PaperSize.cx := W * 100;
      PaperSize.cy := L * 100;
      PaperRect.Left := 0;
      PaperRect.Top := 0;
      PaperRect.Right := W * 100;
      PaperRect.Bottom := L * 100;
      FormInfo.Size := PaperSize;
      FormInfo.ImageableArea := PaperRect;
      SetForm(hPrinter, P, 1, @FormInfo); //設置紙張大小
      ClosePrinter(hPrinter);
      Result := True;
    end;function SetPaperSize(X, Y: Integer): boolean; overload; //用於98系統
    var
      Device: array[0..255] of char;
      Driver: array[0..255] of char;
      Port: array[0..255] of char;
      hDMode: THandle;
      PDMode: PDEVMODE;
    begin
      Printer.PrinterIndex := Printer.PrinterIndex;
      Printer.GetPrinter(Device, Driver, Port, hDMode);
      if hDMode <> 0 then
      begin
        pDMode := GlobalLock(hDMode);
        if pDMode <> nil then
        begin
          if (x = 0) or (y = 0) then
          begin
    //{設置合法的紙張大小
            pDMode^.dmFields := pDMode^.dmFields or dm_PaperSize;
            pDMode^.dmPaperSize := DMPAPER_FANFOLD_US; // 合法的紙張大小標示
          end
          else
          begin
    //{設置用戶自定義紙張
            pDMode^.dmFields := pDMode^.dmFields or DM_PAPERSIZE or DM_PAPERWIDTH or DM_PAPERLENGTH;
            pDMode^.dmPaperSize := DMPAPER_USER; // 設置?用戶自定義紙張標示
            pDMode^.dmPaperWidth := x; // 紙張寬度
            pDMode^.dmPaperLength := y; // 紙張長度
          end;
    //{設定紙張來源
          pDMode^.dmFields := pDMode^.dmFields or DMBIN_MANUAL;
          pDMode^.dmDefaultSource := DMBIN_MANUAL;
          GlobalUnlock(hDMode);
          result := true;
        end;
      end;
    end;procedure initCrpe(Crpe: TCrpe; sender: TForm; showinForm: boolean = true);
    begin
      Crpe.Printer.Name := GetDefaultPrinterName;
      Crpe.WindowButtonBar.PrintSetupBtn := true;
      if showinForm then //如果為true報表將嵌套在窗口中,否則是它自己的窗口
      begin
        crpe.WindowButtonBar.CloseBtn := true;
        Crpe.WindowParent := sender;
        Crpe.WindowEvents := true; // 響應windows消息機制
        Crpe.wOnCloseBtnClick := frmMain.CrpewOnCloseBtnClick;
        Crpe.WindowState := wsMaximized; //這句不能少
        frmMain.reporting := true; //報表沒關閉,當前窗口是不能關閉的
        frmMain.coolbar1.Visible := false;
      end else
      begin
        Crpe.WindowState := wsMaximized;
      end
    end;end.
    //這是我寫的一個單元文件
      

  2.   

    procedure TfrmJXC_XH.ReportXHD;
    var sql, s: widestring;
      path: string;
      crpe1: Tcrpe;
    begin
      sql := 'SELECT XHMX_DH,XHMX_YDRY,DM_MC,XH_RQ,XH_BZ,XHMX_GLM, PP_MC,XLB_MC,CZ_ZWM, '
        + ' YS_ZWM,ST_MC,XHMX_CC,XHMX_SL,XHMX_DW,XHMX_DJ,XHMX_DZ,UG_XM AS CDRU,XHMX_JG '
        + ' FROM XHMX '
        + ' LEFT OUTER JOIN XH ON XH_DH=XHMX_DH  '
        + ' LEFT OUTER JOIN DM ON XH_BM=DM_DM '
        + ' LEFT OUTER JOIN UG ON XH_CDRU=UG_DM '
        + ' LEFT OUTER JOIN '
        + V_CP
        + ' ON XHMX_GLM=CP_DM '
        + ' WHERE 1=1 ';
      s := TrunSQLWhere(Q_Master.CommandText);
      if s <> '' then
        s := ' AND ' + S;
      sql := sql + S; //+用函數條件從數據集的commandtext中分離出來 // sql := sql + ' GROUP BY XHMX_DH,DM_MC,XH_RQ,XHMX_GLM,CZ_ZWM,PP_MC,XLB_MC,YS_ZWM,ST_MC,XHMX_CC,XHMX_SL,XHMX_DW,XHMX_DJ,XHMX_DZ,XHMX_JG,XH_BZ,XHMX_YDRY,UG_XM  ';
      sql := sql + 'ORDER BY XHMX_DH,XHMX_GLM,CZ_ZWM  ';  screen.Cursor := crSQLWait;
      path := ExtractFilePath(Application.ExeName);
      if not fileexists(path + 'crsReport\XHD.rpt') then
      begin
        showmessage('報表文件不存在,請檢查');
        exit;
      end;
      crpe1 := TCrpe.Create(self);
      try
        try
          Rep_Qry.Close;
          Rep_Qry.CommandText := sql;
          Rep_Qry.Open;
          if not Rep_Qry.IsEmpty then
          begin
          Crpe1.Printer.SetCurrent;
          Crpe1.Printer.PreserveRptSettings := [prPaperSize, prPaperSource];
          Crpe1.ReportName := path + 'crsReport\XHD.rpt';
          initCrpe(crpe1, self);
          crpe1.Show;
          end;
        except
          on e: exception do
          begin
            frmMain.coolbar1.Visible := true;
            frmMain.reporting := false;
            showmessage('出錯原因:    ' + chr(10) + chr(10) + e.Message);
          end;
        end;
      finally
        screen.Cursor := crDefault;
        refresh;
      end;
    end;
    //以上是如何在dephi動態調用報表。
      

  3.   

    问一下  
    Rep_Qry是什么,是adoquery控件吗
    上面代码看不到
    Rep_Qry与crpe1有联系呀?