如何在打开子报表时阻止crystal report viewer查询登录凭据
我目前有一个嵌入视觉工作室网站的水晶报告。 我部署网站并将其安装在IIS上,并提供指向用户的链接,以便他们可以全局访问并查看此报告。 这个系统一直很好用。
但是,当我嵌入具有子报告的水晶报告时,凭据不会自动传递到子报告。 当我调试解决方案时,初始报告打开正常,当我单击项目打开子报告时,水晶报告查看器会要求我提供数据库登录凭据。
如何在代码中自动传递这些凭据,以便用户在水晶报表查看器中查看时无需输入代码。
下面是我在default.aspx.cs页面中使用的代码。 它包含连接字符串。
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using System.Data.SqlClient; namespace CFIBInventory { public partial class _Default : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { SqlConnection con = new SqlConnection("Data Source=HPL-WTS;Initial Catalog=Enterprise32;Persist Security Info=True;User ID=sa;Password=********"); DataSet1 ds = new DataSet1(); SqlDataAdapter adapter = new SqlDataAdapter("SELECT dbo.Material.MaterialCode, dbo.Material.CategoryCode, dbo.Material.Description, dbo.MaterialOnHand.LocationCode, dbo.Material.ValuationMethod, dbo.MaterialOnHand.Quantity FROM dbo.Material INNER JOIN dbo.MaterialOnHand ON dbo.Material.MaterialCode = dbo.MaterialOnHand.MaterialCode WHERE (dbo.Material.CategoryCode = 'CFIB3') AND (dbo.Material.ValuationMethod = 1) AND (dbo.Material.InactiveFlag = 0)", con); adapter.Fill(ds.cfibInventory); CrystalReport1 report = new CrystalReport1(); report.SetDataSource(ds); CrystalReportViewer1.ReportSource = report; CrystalReportViewer1.ToolPanelView = CrystalDecisions.Web.ToolPanelViewType.None; } } }
水晶报表查看器通过以下代码嵌入到我的.aspx页面中:
子报告的查询位于子报告的数据库专家中。
顺便说一句,数据库连接到Windows Server 2005计算机。 我不相信它有公共访问设置,例如它自己的IIS。 以前的报告没有子报告,安装在较新的2012 Server上,就像数据库所在的那样。 不确定机器是否与crystal report viewer中的其他登录提示有关。
任何帮助都会很棒。 先感谢您!
编辑:从Nimesh实施解决方案后
好吧,我添加了连接的连接类型,但是,visual studio强调“报告”说:在声明之前不能使用局部变量’report’。
foreach(CrystalDecisions.CrystalReports.Engine.Table CrTable in report .Database.Tables)
和
foreach( 报告中的 ReportDocument子报告 .Subreports)
我注意到我在下面宣布报告为新的crystalreport1。 所以我将该声明移到Nimesh代码块之上,并且’report’的红色下划线消失了,但随后所有6个’crtableLogoninfo’实例都以红色加下划线并出现错误:当前上下文中不存在名称’crtableLogoninfo’
任何进一步的帮助将不胜感激。
以下是我的代码现在的样子:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using System.Data.SqlClient; using CrystalDecisions.Shared; using CrystalDecisions.CrystalReports.Engine; namespace CFIBInventory { public partial class _Default : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { //Nimesh code ConnectionInfo crConnectionInfo = new ConnectionInfo(); crConnectionInfo.ServerName = "HPL-WTS"; crConnectionInfo.DatabaseName = "Enterprise32"; crConnectionInfo.UserID = "sa"; crConnectionInfo.Password = "*********"; foreach (CrystalDecisions.CrystalReports.Engine.Table CrTable in report.Database.Tables) { crTableLogoninfo = CrTable.LogOnInfo; crtableLogoninfo.ConnectionInfo = crConnectionInfo; CrTable.ApplyLogOnInfo(crtableLogoninfo); } foreach (ReportDocument subreport in report.Subreports) { foreach (CrystalDecisions.CrystalReports.Engine.Table CrTable in subreport.Database.Tables) { crtableLogoninfo = CrTable.LogOnInfo; crtableLogoninfo.ConnectionInfo = crConnectionInfo; CrTable.ApplyLogOnInfo(crtableLogoninfo); } } // nimesh code end //Old connection string, i assume this shouldnt be here since nimesh code is for connecting //SqlConnection con = new SqlConnection("Data Source=HPL-WTS;Initial Catalog=Enterprise32;Persist Security Info=True;User ID=sa;Password=123qwerTy987"); DataSet1 ds = new DataSet1(); SqlDataAdapter adapter = new SqlDataAdapter("SELECT dbo.Material.MaterialCode, dbo.Material.CategoryCode, dbo.Material.Description, dbo.MaterialOnHand.LocationCode, dbo.Material.ValuationMethod, dbo.MaterialOnHand.Quantity FROM dbo.Material INNER JOIN dbo.MaterialOnHand ON dbo.Material.MaterialCode = dbo.MaterialOnHand.MaterialCode WHERE (dbo.Material.CategoryCode = 'CFIB3') AND (dbo.Material.ValuationMethod = 1) AND (dbo.Material.InactiveFlag = 0)", con); adapter.Fill(ds.cfibInventory); CrystalReport1 report = new CrystalReport1(); // OLD CODE //report.SetDataSource(ds); CrystalReportViewer1.ReportSource = report; CrystalReportViewer1.ToolPanelView = CrystalDecisions.Web.ToolPanelViewType.None; } } }
问题出在Crystal Report登录信息中。 在显示报告之前,您必须将登录信息设置为主报告及其子报告中包含的所有表。 您正在使用Disconnected Datasource Report Show方法。 因此您无需为报告文档提供登录信息。 你的问题在这里。
report.SetDataSource(ds);
当您使用SetDataSource方法时,必须提供水晶报告文档中包含的所有表。 在这里,您只在数据集中传递了一个表。 您必须传递所有表,包括子报表。
我建议您使用子报表,然后使用连接的数据源方法,如果断开连接的数据源(report.SetDataSource())。 在Connected数据源中,您必须在显示报告之前设置登录信息。
private void PrintReport() { ReportDocument report = new ReportDocument(); report.Load("ReportPath"); ConnectionInfo crConnectionInfo = new ConnectionInfo(); crConnectionInfo.ServerName = "HPL-WTS"; crConnectionInfo.DatabaseName = "Enterprise32"; crConnectionInfo.UserID = "sa"; crConnectionInfo.Password = "*********"; TableLogOnInfo crTableLogoninfo = new TableLogOnInfo(); foreach (CrystalDecisions.CrystalReports.Engine.Table CrTable in report.Database.Tables) { crTableLogoninfo = CrTable.LogOnInfo; crTableLogoninfo.ConnectionInfo = crConnectionInfo; CrTable.ApplyLogOnInfo(crTableLogoninfo); } foreach (ReportDocument subreport in report.Subreports) { foreach (CrystalDecisions.CrystalReports.Engine.Table CrTable in subreport.Database.Tables) { crTableLogoninfo = CrTable.LogOnInfo; crTableLogoninfo.ConnectionInfo = crConnectionInfo; CrTable.ApplyLogOnInfo(crTableLogoninfo); } } CrystalReportViewer1.ReportSource = report; CrystalReportViewer1.ToolPanelView = CrystalDecisions.Web.ToolPanelViewType.None; }
如果您想使用断开连接的数据源,即使您没有包含子报表,也可以使用单个命令而不是多个表。 这样可以轻松实现更好的性能。 因为你只需要将一个表传递给SetDataSource方法。 但是,不要忘记在DataTable中设置tablename,否则将不会显示报告。
试试这个
打开Field Explorer
—>右键单击Database Field
—> Current Data Source
—> Report Connection
—> Report
—> Property
—> Set Property
as —
数据源:。\ Databasename.accdb
和查看器表单上的代码加载为
Dim cryRpt As New ReportDocument Dim Report1 As New rptItemWise Dim strServerName As String strServerName = Application.StartupPath rptItemWise.SetDatabaseLogon("admin", "", strServerName, "dastabasename.accdb", True) cryRpt.Load(Application.StartupPath + "\rptItemWise.rpt")
同时更改与数据源相同的报告连接。 我认为代码对你有用。
我的解决方案是使用SQL Server安装源安装SQL Server 2012客户端工具连接和后向客户端连接组件。
我也有子报告的错误。 重要提示:我的报表设计器在“主”报表中只使用了一个表,在子报表中只使用了一个(不同的)表。 我的解决方案
Dim ds as DataSet '... Put your code to fectch data report.SetDataSource(ds) Dim ds1 as DataSet '... Put your code to fetch data Dim dtb = ds1.Tables(0) dtb.TableName = "Same_name_used_in_report_designer" report.Subreports(0).SetDataSource(dtb)
这里有两件重要事情:
- Report的数据源必须是DataSet,只有1个DataTable。
- 子报表的数据源必须是DataTable,而不是完整的DataSet。
我不完全理解Crystal Reports基础,所以我无法解释原因,但它解决了我的问题。