7

我目前在视觉工作室网站中嵌入了一份水晶报告。我部署网站并将其安装在 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 页面中:

<%@ Page Title="Home Page" Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true"
    CodeBehind="Default.aspx.cs" Inherits="CFIBInventory._Default" %>

<%@ Register assembly="CrystalDecisions.Web, Version=13.0.2000.0, Culture=neutral, PublicKeyToken=692fbea5521e1304" namespace="CrystalDecisions.Web" tagprefix="CR" %>

<asp:Content ID="HeaderContent" runat="server" ContentPlaceHolderID="HeadContent">
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
</asp:Content>
<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
    <p>
    </p>
    <CR:CrystalReportViewer ID="CrystalReportViewer1" runat="server" 
        AutoDataBind="true" />
</asp:Content>

子报表的查询在子报表的数据库专家中。

顺便说一句,数据库正在连接到一台 windows server 2005 机器。我不相信它有公共访问设置,比如它自己的 IIS。以前没有子报告的报告安装在较新的 2012 服务器上,因为这就是数据库所在的位置。不确定机器是否与水晶报表查看器中的附加登录提示有关。

任何帮助都会很棒。先感谢您!


编辑:从 Nimesh 实施解决方案后

好吧,我添加了连接的连接类型,但是,Visual Studio 在“报告”下划线说:在声明之前不能使用局部变量“报告”。

foreach (CrystalDecisions.CrystalReports.Engine.Table CrTable in report.Database.Tables )

foreach(报表中的 ReportDocument 子报表.Subreports)

我注意到我稍后在下面将报告声明为新的水晶报告1。因此,我将该声明移至 Nimesh 代码块上方,“report”的红色下划线消失了,但随后“crtableLogoninfo”的所有 6 个实例都以红色下划线显示错误:当前上下文中不存在名称“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;
            }
        }
    }
4

4 回答 4

6

问题出在 Crystal Report 登录信息中。在显示报告之前,您必须为包含在主报告及其子报告中的所有表设置登录信息。您正在使用断开连接的数据源报告显示方法。因此您无需向报告文档提供登录信息。你的问题就在这里。

report.SetDataSource(ds);

当您使用 SetDataSource 方法时,必须提供包含在水晶报表文档中的所有表格。在这里,您只传递了数据集中的一个表。您必须通过所有表,包括子报表表。

如果您正在使用子报表,我建议您使用连接的数据源方法,而不是如果断开连接的数据源(report.SetDataSource())。在连接的数据源中,您必须在显示报告之前设置登录信息。

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 中设置表名,否则将不会显示报告。

于 2014-02-12T03:39:03.587 回答
0

试试这个
打开Field Explorer--->右击Database Field---> Current Data Source---> Report Connection---> Report---> Property--->Set Property作为---

数据源:.\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")

还要更改与数据源相同的报表连接。我认为该代码对您有用。

于 2014-12-10T06:58:22.010 回答
0

我的子报告也有这个错误。重要提示:我的报表设计器在“主”报表中只使用了一张表,在子报表中使用了一张(不同的)表。我的解决方案:

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)

这里有两件重要的事情:

  1. 报表的数据源必须是只有 1 个 DataTable 的 DataSet。
  2. 子报表的数据源必须是 DataTable,而不是完整的 DataSet。

我不完全了解 Crystal Reports 基础,所以我无法解释原因,但它解决了我的问题。

于 2016-09-09T19:28:27.383 回答
0

我的解决方案是安装 SQL Server 2012 客户端工具连接,以及使用 SQL Server 安装源的反向客户端连接组件。

于 2016-09-08T12:08:46.303 回答