我已經研究瞭如何動態地改變這裏的數據源連接在計算器上許多不同的方式。我使用並驗證了幾乎所有可以找到的c#和vb.net示例,但不知怎的,事情不會按照他們的想法運行。動態更改數據庫類型,在Crystal Reports源等(爲Visual Studio 2012)
我們項目的想法是將舊報告(即使用xBase dll)的數據源連接更改爲crdb_ado.dll和VFPOLEDB提供程序以連接到Visual Foxpro DBF文件(每個文件代表一個表) 。
我已經下載了最新的水晶Developer版本的Visual Studio(2012年)在這裏:http://scn.sap.com/docs/DOC-35074 爲了能夠直接在VS使用這些組件,而引用的DLL在Program Files文件 - 業務對象目錄(如中所看到的其他例子)。
我試着通過VS調試器的舊版「更新」報告驗證內容(請參閱下面的代碼)以及Crystal Reports中新創建的報告(最新版本,它使用正確的路徑和設置連接到dbf )所以他們匹配。
不過,我遇到這些問題:
- 的代碼是能夠改變所有參數和屬性,但其保存放棄所有更改(文件不是隻讀)
- 更改table.location拋出一個COM異常(翻譯:無法加載數據庫中的數據,在錯誤報告)
- 當「附接」的報告的文檔對象到晶體報告觀看者發生同樣的情況。
- reportDocument.VerifyDatabase()顯然失敗
- 對於據我所看到的,所有的設置都在這兩個文件中
的開發環境似乎是windows 7/64/2012 VS臨。 Crystal Reports(XI或2011)安裝在本機上。我們所有的報告都是使用Crystal Reports的版本9和版本11創建的。
下面是確實更改了所有屬性或參數(表格位置除外)的一個修改代碼示例。我也使用過使用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 connection dbf」指向「vfpoledb connection dbf」(如果你理解我的點),而不會丟失報告中的所有字段。
我嘗試安裝了VS CR開發人員版本的32個和64位版本,但它似乎並沒有改變任何東西。
而且,接下來的一段代碼不工作在Visual FoxPro中(和我能夠在我的水晶閱讀這些轉換後的文件報告文檔查看器)。這只是討厭它不能輕易完成在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)
任何想法或建議?謝謝
我有一個類似的問題,但沒有使用ReportAppServer,因爲我只是在本地運行報告。我不能爲我的生活找出數據庫名稱的來源 - 它看起來並不像公開顯示的那樣。使用反射器進行檢查時,看起來好像在我的程序集(9.2.3333.0)中似乎將來自ConnectionInfo的信息傳遞給非託管代碼。 this._obfuscatedtablename_(connectionInfo.ServerName,connectionInfo.DatabaseName,connectionInfo.UserID,connectionInfo.Password,true); – agrath 2014-05-23 04:04:44