繁体   English   中英

在向报表添加参数时,Crystal Reports未选择任何记录

[英]Crystal Reports not selecting any records when I add a parameter to the report

我在Visual Studio 2010中使用Crystal Reports和ASP.NET。

我有一个从数据库中提取数据的DataSet,它似乎很好地加载到报告中。 当我在浏览器中查看报告时,所有记录都正确加载。

我必须添加一个参数供用户输入,以过滤掉报表中的条目。 问题是,当我向报表添加任何类型的参数时,查看器无法找到任何记录。 这是我对选择向导做任何事情之前

我添加了一个下拉列表参数,其中只包含数字1,2和3.如果选择专家中没有任何内容,则不应影响任何内容。 但无论出于何种原因,当报告中没有任何记录被选中时。 一旦我删除参数它再次工作。

如果这会产生影响,我会通过字段资源管理器添加参数及其值。

奇怪的是,当报表直接从数据库中提取数据时,实现是有效的,而不是先创建DataSet。 我无法使用此实现的原因是它一直在询问数据库登录信息。 即使我预先定义了信息。 我切换到DataSet,所以我会避免登录提示。

我在想我的DataSet实现有问题。 相关代码在这里:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using CrystalDecisions.CrystalReports.Engine;
using CrystalDecisions.Shared;
using System.Data;
using System.Data.Common;
using System.Data.SqlClient;
using System.Configuration;
using Microsoft.Practices.EnterpriseLibrary.Data;


public partial class reportPage : System.Web.UI.Page
{

    private ReportDocument rpt;
    private string mapPath;

    protected void Page_Load(object sender, EventArgs e)
    {

        if (!Page.IsPostBack) // If the page is loaded for the first time
        {

            mapPath = "CrystalReport1.rpt";
            ConfigureCrystalReport();

        }

    }

    private void ConfigureCrystalReport() // Creates the instance of the report file and binds it to the viewer on the page
    {

        myDataSet ds = new myDataSet();

        myDataSetTableAdapters.myTableTableAdapter dsTA = new myDataSetTableAdapters.myTableTableAdapter();
        dsTA.Fill(ds.myTable);

        // Initializing the report file
        rpt = new ReportDocument();
        string reportPath = Server.MapPath(mapPath);
        rpt.Load(reportPath);

        DataTable dt = ds.myTable;
        Response.Write("<script>alert('Table has "+ dt.Rows.Count.ToString() +" rows');</script>");
        rpt.SetDataSource(dt); 

        // Binding the report file to the report viewer on the page
        CrystalReportViewer1.ReportSource = rpt;
        CrystalReportViewer1.ToolPanelView = CrystalDecisions.Web.ToolPanelViewType.ParameterPanel;
        CrystalReportViewer1.HasToggleGroupTreeButton = false;

    }

response.write会在页面上弹出一个警告,指出要发送到报表的表中有多少行。 它正确计算,所以我知道数据IS被发送到报告,但它没有选择任何一个。

老实说,我不知道为什么它没有选择任何东西。

编辑 :经过一些快速测试后,看起来我可以将参数添加到列表而不会破坏报告。 当我将实际参数元素放在页面上时,或者当我将它用作选择专家的一部分时,报表无法加载行。

换句话说,报告仅在未显示参数提示时才起作用。

编辑2 :我尝试更改我的DataSet代码,以使其实际连接到数据库。 我以为我正在使用DataSet来避免这种情况......但我在教程视频中看到了它。

代码在这里:

        string sConnectionString;
        sConnectionString = "Password=mYp@ssw0rd*;User ID=sa;" + "Initial Catalog=databaseName;" + "Data Source=serverName";
        SqlConnection conn = new SqlConnection(sConnectionString);
        conn.Open();
        SqlDataAdapter sDA = new SqlDataAdapter("Select * from myTable", conn);
        conn.Close();

        myDataSet ds = new myDataSet();

        sDA.Fill(ds, "myTable");
        // Initializing the report file
        rpt = new ReportDocument();
        string reportPath = Server.MapPath(mapPath);
        rpt.Load(reportPath);

        rpt.SetDataSource(ds);

毕竟,没有。 如果没有参数可用,它仍会加载表中的所有数据。 只要我添加一个参数(到页面,或作为选择专家的一部分),就不会加载任何记录。

编辑3 :我尝试以编程方式传递参数:

rpt.SetParameterValue("par1", 1);

有趣的是,它确实加载了DataSet中的所有数据......直到我向它传递了一个新参数。 然后,即使我将参数设置回1,也没有加载任何记录。看起来,一旦查看者必须处理参数,它就会丢弃所有记录。

我真的不知道现在在哪里看。 据我所知,这是rpt.SetDataSource()或CrystalReportsViewer1.ReportSource = rpt的问题。

编辑4 :正如user4663200指出的那样,当页面被回发时,mapPath为空。 我尝试修复它,但遇到了一个新的错误,弹出窗口出现并说'请等待文档正在处理中'。 永远。 我查看了这个错误,多个来源告诉我将加载代码从Page_Load()传递给Page_Init()。

重要的一点是,当用户输入参数页面回发时,会以某种方式导致此错误。 显然,如果页面没有回发,页面就会很好。

我尝试在Page_Init中实现我的代码的更简单版本,但它不起作用,仍然有无限的加载弹出窗口。

这是我的代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using CrystalDecisions.CrystalReports.Engine;
using CrystalDecisions.Shared;
using System.Data;
using System.Data.Common;
using System.Data.SqlClient;
using System.Configuration;
using Microsoft.Practices.EnterpriseLibrary.Data;  



private ReportDocument rpt;
private myDataSet ds;

protected void Page_Init(object sender, EventArgs e)
    {

        if (!Page.IsPostBack)
        {

            ds = new myDataSet();


            myDataSetTableAdapters.myTableTableAdapter dsTA = new myDataSetTableAdapters.myTableTableAdapter();

            dsTA.Fill(ds.myTable);
            // Initializing the report file
            rpt = new ReportDocument();
            string reportPath = Server.MapPath("myReport.rpt");
            rpt.Load(reportPath);
            Session.Add("dataSet", ds);
            Session["dataSet"] = ds;

            rpt.SetDataSource(ds);

            CrystalReportViewer1.ReportSource = rpt;

        }
        else
        {

            ds = (myDataSet)Session["Report"];
            rpt = new ReportDocument();
            string reportPath = Server.MapPath("myReport.rpt");
            rpt.Load(reportPath);
            rpt.SetDataSource(ds);
            CrystalReportViewer1.ReportSource = rpt;

        }

    }

问题是其他解决方案要求将REPORT保存在会话中,但为了实现这一点,需要将Sessionstate设置为“InProc”模式。 我无法将此网站从“StateServer”模式中删除。 我尝试通过在会话中保存DataSet,然后每次将其绑定到新报表来解决方法。 但这也不起作用。

编辑4.5我刚尝试将sessionState更改为InProc,这仍然无法正常工作。 即使我这样做,报告就是在会话中保存的内容。

编辑4.75我尝试在Page_Init()中放置一个断点,它揭示了一些有趣的东西。

我可以看到Session [“Report”]; 在初始运行代码期间正确保存。

但是在输入参数后我又看了一次Page_Init(),当它尝试做rpt =(ReportDocument)Session [“Report”]时; Session [“Report”]中的所有内容均为null。 它抛出了许多空异常,但这些仅在断点调试器中可见,它们似乎在正常运行期间似乎没有出现。 我很确定这就是为什么它会在回帖后永远加载。

所以现在的问题是输入参数后回发会导致会话中的所有数据丢失。

编辑4.825 :您可以忽略之前的编辑。 我注释掉了这段代码:

    protected void Page_UnLoad(object sender, EventArgs e)
    {
        try
        {
            rpt.Close();
            rpt.Dispose();
        }
        catch { }
    }

在删除此代码后,我再次查看了Session [“Report”]变量,它不再为null。

有趣的是,即使进入参数条目,也会调用Page_UnLoad BEFORE。 如果是rpt.Close(); 正在转储对rpt的所有引用,然后就好像Session变量就像一个指针,而不是存储一个实际的rpt对象。 所以当rpt是Disposed()时,Session [“Report”]似乎只是一个空指针。

所以现在它传递了正确的东西......它仍然拥有无限的“文档处理”屏幕。

编辑5 :我终于开始工作了。

事实证明会话是解决方案,但我找不到任何好的实现。

我从这里获得了大部分相关代码。 但你不能只复制和粘贴它。

这是我的实施

    private ReportDocument rpt;
    private myDataSet ds;

    protected void Page_Init(object sender, EventArgs e)
    {

        if (!IsPostBack)
        {

            Session["Report"] = null;

        }

        if (Session["Report"] == null)
        {

            ds = new myDataSet();
            myDataSetTableAdapters.myTableTableAdapter dsTA = new myDataSetTableAdapters.myTableTableAdapter();
            DataTable dt = dsTA.GetData();

            rpt = new ReportDocument();
            rpt.Load(Server.MapPath("myReport.rpt"));
            rpt.SetDataSource(dt);
            Session.Add("Report", rpt);
            CrystalReportViewer1.ReportSource = rpt;
            CrystalReportViewer1.ToolPanelView = CrystalDecisions.Web.ToolPanelViewType.ParameterPanel;
            CrystalReportViewer1.HasToggleGroupTreeButton = false;

        }

    }

    protected void Page_Load(object sender, EventArgs e)
    {

        if (Page.IsPostBack)

        {

            rpt = (ReportDocument)Session["Report"];
            CrystalReportViewer1.ReportSource = rpt;
            CrystalReportViewer1.ToolPanelView = CrystalDecisions.Web.ToolPanelViewType.ParameterPanel;
            CrystalReportViewer1.HasToggleGroupTreeButton = false;

        }

    }

    protected void butReport_Click(object sender, EventArgs e)
    {

        if (Session["Report"] == null) // Report is not in session (previously loaded) so load report, set params, view and place in session
        {

            ds = new myDataSet();
            myDataSetTableAdapters.myTableTableAdapter dsTA = new myDataSetTableAdapters.myTableTableAdapter();
            DataTable dt = dsTA.GetData();

            rpt = new ReportDocument();
            rpt.Load(Server.MapPath("myReport.rpt"));
            rpt.SetDataSource(dt);
            Session.Add("Report", rpt);
            CrystalReportViewer1.ReportSource = rpt;
            CrystalReportViewer1.ToolPanelView = CrystalDecisions.Web.ToolPanelViewType.ParameterPanel;
            CrystalReportViewer1.HasToggleGroupTreeButton = false;

        }
        else
        {

            rpt = (ReportDocument)Session["Report"];
            CrystalReportViewer1.ReportSource = rpt;
            CrystalReportViewer1.ToolPanelView = CrystalDecisions.Web.ToolPanelViewType.ParameterPanel;
            CrystalReportViewer1.HasToggleGroupTreeButton = false;

        }

    }

最重要的区别是这一行:DataTable dt = dsTA.GetData(); 在我将整个DataSet传递给rpt之前。 我不确定为什么,但是使用GetData()的结果创建一个新的DataTable可以使报告保持在会话中。

现在我的报告即使在所有回发中都会保持在会话中。 我遇到并解决了一些其他问题,例如当用户离开页面并返回时会话未重置。

您的SQL查询缺少where子句,因此无论您为参数添加什么内容,它都将始终返回所有记录。 可能后续调用失败的原因是你的mapPath是空白的,你在每个Page_Load上创建它,但只有在它不是回发时才设置它。 这意味着在初始页面加载后,mapPath为null,因此没有报告可以提取。

解决了。 有关说明,请参见编辑5。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM