2010-08-24

變更 CrystalReporsts 中的 MS Access 檔案位置

如何變更 CrystalReports 報表檔 (*.rpt) 的資料來源呢?以 MS Access 資料庫 (*.mdb) 為例,Crystal Reports XI Technical Reference Guide 內提供了三個範例。如下:

Example.1
這個範例是使用 DatabaseTable.Location 屬性的方式來變更 MS Access 資料庫位置。
var
  vCRApp: IApplication;
  vCRRpt: IReport;
  vCRTbl: IDatabaseTable;
  vRptFileName: String;
begin
  // Create a new instance of the report.
  vCRApp := CoApplication.Create;
  vCRRpt := vCRApp.OpenReport(vRptFileName, crOpenReportByDefault);

  // Get the first table in the report. Index is 1-Base.
  vCRTbl = vCRRpt.Database.Tables(1);

  // Set the new location of the database.
  vCRTbl.Location = "C:\databases\xtreme.mdb"

  // Set the report source of the viewer and view the report.
  Screen.Cursor := crHourGlass;
  CRViewer.ReportSource := vCRRpt;
  CRViewer.ViewReport;
  Screen.Cursor := crDefault;
end;
Example.2
這個範例是使用 DatabaseTable.ConnectionProperty 物件的方式來變更 MS Access 資料庫位置。
var
  vCRApp: IApplication;
  vCRRpt: IReport;
  vCRTbl: IDatabaseTable;
  vCRConnProperty: IConnectionProperty;
  vRptFileName: String;
begin
  // Create a new instance of the report.
  vCRApp := CoApplication.Create;
  vCRRpt := vCRApp.OpenReport(vRptFileName, crOpenReportByDefault);

  // Get the first table in the report. Index is 1-Base.
  vCRTbl = vCRRpt.Database.Tables(1);

  // Get the "Database Name" property from the
  // ConnectionProperties collection.
  vCRConnProperty := vCRTbl.ConnectionProperties['Database Name'];

  // Set the new location of the database.
  vCRConnProperty .Value = 'C:\databases\xtreme.mdb'

  // Set the report source of the viewer and view the report.
  Screen.Cursor := crHourGlass;
  CRViewer.ReportSource := vCRRpt;
  CRViewer.ViewReport;
  Screen.Cursor := crDefault;
end;
Example.3
這個範例是使用 DatabaseTable.SetTableLocation 的方法(Method)來變更 MS Access 資料庫位置。
var
  vCRApp: IApplication;
  vCRRpt: IReport;
  vCRTbl: IDatabaseTable;
  vRptFileName: String;
begin
  // Create a new instance of the report.
  vCRApp := CoApplication.Create;
  vCRRpt := vCRApp.OpenReport(vRptFileName, crOpenReportByDefault);

  // Get the first table in the report. Index is 1-Base.
  vCRTbl = vCRRpt.Database.Tables(1);

  // Set the new database location and the new table name.
  vCRTbl.SetTableLocation(
    'C:\databases\xtreme.mdb',
    NewCustomer, 
    '');

  // Set the report source of the viewer and view the report.
  Screen.Cursor := crHourGlass;
  CRViewer.ReportSource := vCRRpt;
  CRViewer.ViewReport;
  Screen.Cursor := crDefault;
end;
使用 Example.1 並不適合使用在多 Table 的報表中,尤其是來至於不同的 Database(*.mdb)。所以當多 Table 並且跨 Database (*.mdb)的情況下,建議使用 Example.2。Crystal Reports XI Technical Reference Guide 中所描述的 Example.2 在 Delphi 中需要稍微做修改,因為 Delphi 轉換過來的使用方式不同於 RDC 用法。

Example.2-fix
var
  vCRApp: IApplication;
  vCRRpt: IReport;
  vCRTbl: IDatabaseTable;
  vCRValuePairs: INameValuePairs;
  vRptFileName, vAccFileName: String;
  ii: Integer;
  vOO: OleVariant;
begin
  // Create a new instance of the report.
  vCRApp := CoApplication.Create;
  vCRRpt := vCRApp.OpenReport(vRptFileName, crOpenReportByDefault);

  for ii := 1 to vCRRpt.Database.Tables.Count do
  begin
    // Get the first table in the report. Index is 1-Base.
    vCRTbl := vCRRpt.Database.Tables[ii];

    // 取得 Table.ConnectionProperties,也就是 IConnectionProperty 集。
    vCRValuePairs := vCRTbl.ConnectionProperties;

    if LowerCase(ExtractFileName(vCRTbl.LogOnDatabaseName)) = 'r_main.mdb' then
    begin
      // Get the "Database Name" property from the
      // ConnectionProperties collection.
      // vOO is IConnectionProperty
      vOO :=
        vCRValuePairs.Item['Database Name'];

      // Set the new location of the database.
      vOO.Value :=                 
        IncludeTrailingPathDelimiter(ExtractFilePath(vAccFileName)) +
        'R_Main.mdb';
    end
    else
    begin
      // Get the "Database Name" property from the
      // ConnectionProperties collection.
      // vOO is IConnectionProperty
      vOO :=
        vCRValuePairs.Item['Database Name'];

      // Set the new location of the database.
      vOO.Value :=                     
        vAccFileName;
    end;

    ShowMessage(vCRTbl.Name + #13#10 +
      vCRTbl.LogOnDatabaseName);
  end;

  // Set the report source of the viewer and view the report.
  Screen.Cursor := crHourGlass;
  CRViewer.ReportSource := vCRRpt;
  CRViewer.ViewReport;
  Screen.Cursor := crDefault;
end;
這裡可以看到使用 ConnectionProperties.Item['Name'] 屬性來取得 IConnectionProperty 物件,而非 ConnectionProperties['Name']屬性。而 Delphi 轉換過來的 IConnectionProperty 是個 OleVariant。如果您使用剛剛所提到的多 Table 跨 Database (*.mdb) 並使用 Example.1 。可以在 ShowMessage 中來驗證 IDatabaseTable.LogOnDatabaseName 屬性中的資料是否每一個 Table 都正常;有可能不正常。

沒有留言: