ここ StackOverflow でデータソース接続を動的に変更する方法について、さまざまな方法を調査しました。見つけたほぼすべての c# と vb.net の例を使用して検証しましたが、どうにかしてうまくいきません。
私たちのプロジェクトのアイデアは、データソース接続を古いレポート (xBase dll を使用している) から VFPOLEDB プロバイダーを使用して crdb_ado.dll に変更し、Visual Foxpro DBF ファイル (各ファイルは 1 つのテーブルを表す) に接続することです。
Visual Studio (2012) の最新の Crystal Developer バージョンをダウンロードしました: http://scn.sap.com/docs/DOC-35074プログラム ファイル で dll を参照せずに、これらのコンポーネントを VS で直接使用できるようにするには-ビジネス オブジェクトディレクトリ (他の例を参照)。
古い「更新された」レポート (以下のコードを参照) の内容を、Crystal Reports で新しく作成されたレポート (正しいパスと設定を使用して dbf に接続する最新バージョン) と一緒に VS デバッガーを介して確認しようとしました。上。
ただし、次の問題が発生しました。
- コードはすべてのパラメーターと属性を変更できますが、保存するとすべての変更が破棄されます(ファイルは読み取り専用ではありません) 。
- table.location を変更するとcom 例外がスローされます(翻訳: データベース データを読み込めませんでした、レポートにエラーが表示されます)
- レポート ドキュメント オブジェクトを Crystal レポート ビューアに「添付」する場合も同様です。
- reportDocument.VerifyDatabase() は明らかに失敗します
- 私が見る限り、すべての設定は両方のファイルにあるようです
開発環境はWindows 7/64bit/VS 2012 Proです。このマシンには Crystal Reports (XI または 2011) がインストールされています。すべてのレポートは、Crystal Reports のバージョン 9 および 11 で作成されました。
以下は、すべての属性またはパラメーター(テーブルの場所を除く) を変更したコード例の 1 つです。Propertybag オブジェクトを使用した例も使用しましたが、それらは機能しませんでした。
reportDocument1.Load("path to document");
// also tried adding these two lines as a test
reportDocument1.DataSourceConnections.Clear();
reportDocument1.DataSourceConnections[0].SetConnection(@"c:\testreports","",false);
//changing of table data connections
foreach (Table table in reportDocument1.Database.Tables)
{
ChangeTableLogonInfo(table);
}
// ---
private void ChangeTableLogonInfo(Table table)
{
// server = place containing *.DBF files
table.LogOnInfo.ConnectionInfo.ServerName = @"c:\testreports\";
// set to empty string (looking at generated report in CrRep)
table.LogOnInfo.ConnectionInfo.DatabaseName = "";
table.LogOnInfo.ConnectionInfo.UserID = "";
table.LogOnInfo.ConnectionInfo.Password = "";
// create logon properties
var connectionAttributes = new DbConnectionAttributes();
connectionAttributes.Collection.Set("Collating Sequence","Machine");
connectionAttributes.Collection.Set("Data Source", @"c:\testreports");
connectionAttributes.Collection.Set("Locale Identifier", 1033);
connectionAttributes.Collection.Set("OLE DB Services", -5);
connectionAttributes.Collection.Set("Provider", "VFPOLEDB"); //eg: SQLOLEDB
connectionAttributes.Collection.Set("Use DSN Default Properties",false);
// CLEAR and SET NEW attributes for the given table
table.LogOnInfo.ConnectionInfo.Attributes.Collection.Clear();
table.LogOnInfo.ConnectionInfo.Attributes.Collection.Add(new NameValuePair2 { Name = "Database DLL", Value = "crdb_ado.dll" });
table.LogOnInfo.ConnectionInfo.Attributes.Collection.Add(new NameValuePair2 { Name = "QE_DatabaseName", Value = "" });
table.LogOnInfo.ConnectionInfo.Attributes.Collection.Add(new NameValuePair2 { Name = "QE_DatabaseType", Value = "OLE DB (ADO)" });
table.LogOnInfo.ConnectionInfo.Attributes.Collection.Add(new NameValuePair2 { Name = "QE_LogonProperties", Value = connectionAttributes });
table.LogOnInfo.ConnectionInfo.Attributes.Collection.Add(new NameValuePair2 { Name = "QE_ServerDescription", Value = @"c:\testreports" });
table.LogOnInfo.ConnectionInfo.Attributes.Collection.Add(new NameValuePair2 { Name = "QE_SQLDB", Value = true });
table.LogOnInfo.ConnectionInfo.Attributes.Collection.Add(new NameValuePair2 { Name = "SSO Enabled", Value = false });
// gives a COM error
try
{
table.Location = "some-table-name";
}
catch (Exception e)
{
// handling
}
}
Crystal Reports 自体に「厄介な」点があることに気付きました。それと何か関係があるのだろうか:
CR 自体を介して xbase 接続を変更したい場合、レポート内のすべてのフィールドを失うことなく、"xbase 接続 dbf" から "vfpoledb 接続 dbf" にポイントすることはできません (私の主張を理解している場合)。
VS CR 開発者版の 32 ビット版と 64 ビット版をインストールしてみましたが、何も変わらないようです。
また、次のコードは Visual FoxPro で機能します (そして、Crystal Reports ドキュメント ビューアでこれらの変換されたファイルを読み取ることができます)。C#では簡単に実行できないのは面倒です(そうです:))
lotest = CREATEOBJECT("crystalruntime.application.9")
lorap = lotest.openreport("c:\factuur.rpt")
loData = loRap.Database
LOCAL lnI
lnI = 1
FOR EACH loTable IN lodata.tables
loconn = loTable.connectionproperties
loTable.dllname = "crdb_odbc.dll"
loConn.DeleteAll
IF lnI = 1
loCOnn.Add("Database", "Hoofding")
ELSE
loCOnn.Add("Database", "Detail")
ENDIF
loConn.Add("Database Type","ODBC")
loConn.Add("DSN","DBFACTw")
lnI = lnI + 1
ENDFOR
loRap.Saveas("c:\Factuur2.rpt",2048)
アイデアや提案はありますか?ありがとう