带有链接子报表的Crystal报表仅适用于报表预览

时间:2016-06-08 07:06:50

标签: c# sql-server stored-procedures crystal-reports

我使用带有sql参数的存储过程和我的主报告。

enter image description here

我的主报告的存储过程 enter image description here

然后我尝试使用以下存储过程在工作报告中添加子报告

enter image description here

然后将Subreport字段参数链接到我的Main

enter image description here

如果子报告正在运行,我检查了主报告预览

enter image description here

然后我运行报告,但我看到的只是这个 enter image description here 它只是停留在这条消息并继续运行,我甚至等了几个小时,检查任务管理器是否挂起报告,但是没有...它也没有任何错误消息。但为了关闭正在运行的报告,我必须"结束流程"在任务管理器中。

所以我尝试从子报告中删除字段参数以及链接并重新运行报告。

enter image description here

它正在工作,但是如果没有从主报告传递值,报告就没用了。因为我有日期范围。什么似乎是问题?当我链接参数时,为什么它只是在加载报告?

了解更多信息我使用SAP Crystal Report Service Pack 16和IDE作为Visual Studio 2015

这是我用于主报告上参数的获取/设置值的代码

 private void SalesByRangeReport_Load(object sender, EventArgs e)
    {

        FormBorderStyle = FormBorderStyle.Sizable;

        WindowState = FormWindowState.Maximized;

        TopMost = true;

        DataTable dtSalesByRangeReport = GetData();

        showReport(dtSalesByRangeReport);
    }

    private void showReport(DataTable dtSalesByRangeReport)
    {
        ReportDocument rdoc = new ReportDocument();

        //rdoc.Load(@"Report\SalesByRangeReport.rpt");

        rdoc.Load(AppDomain.CurrentDomain.BaseDirectory + @"Report\SalesByRangeReport.rpt");
        rdoc.SetDataSource(dtSalesByRangeReport);

        TextObject txt;
        if (rdoc.ReportDefinition.ReportObjects["test"] != null)
        {
            txt = (TextObject)rdoc.ReportDefinition.ReportObjects["test"];
            txt.Text = "From :" + StartDate.ToString(" MMMM  dd  yyyy  hh :mm") + " To :" + EndDate.ToString(" MMMM  dd  yyyy  hh :mm");
        }

        SalesByRangeCystalReport.ReportSource = rdoc;
    }


 private DataTable GetData()
    {
        DataTable dtData = new DataTable();

        using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["CSPOSWare.Reports.Properties.Settings.fpos_chaplinConnectionString"].ConnectionString))
        {

            //TODO Mark and Reni : Create a Stored Procedure, Saved in SalesByRangeReport.txt 

            using (SqlCommand cmd = new SqlCommand("usp_ReportShowSalesRangeDateTime", conn))
            {
                cmd.CommandType = CommandType.StoredProcedure;

                conn.Open();

                //cmd.Parameters.AddWithValue("@TopInt", this.TopInt);
                cmd.Parameters.AddWithValue("@SortType", this.SortType);
                cmd.Parameters.AddWithValue("@StartDate", this.StartDate);
                cmd.Parameters.AddWithValue("@EndDate", this.EndDate);
                cmd.Parameters.AddWithValue("@DeptGroup", this.DeptGroup);
                cmd.Parameters.AddWithValue("@DateType", this.DateType);

                //Console.WriteLine("Start Date" + StartDate);

                SqlDataReader rdr = cmd.ExecuteReader();

                dtData.Load(rdr);
            }

        }


        return dtData;
    }

我的报告都有这些属性:

Build Action: Compile
Copy to Output Directory: Copy Always
Custom Tool: 
Custom Tool Name: 

所以我尝试在我的主SP和SUB SP上进行未知优化的ADDED OPTIMIZE MAIN:

  ALTER PROCEDURE[dbo].[usp_ReportShowSalesRangeDateTime]
        (                           
            @SortType     Varchar(50),
            @StartDate    DATETIME,
            @EndDate      DATETIME,
            @DeptGroup    Varchar(50),
            @DateType     Varchar(50)
        )
        AS
    BEGIN
        Declare @SQLQuery NVARCHAR(max)
         Declare @ReportCriteria NVARCHAR(max)
         If (LEN(@DeptGroup) > 0) 
            Set @ReportCriteria = ' AND B.Department =  ''' + @DeptGroup + '''';
         If (LEN(@DeptGroup) = 0)
         Set @ReportCriteria = ' ';

            WITH SalesRange AS(
                        Select A.EndDate as [Log Date], A.StoreDate as [Store Date], B.Department as [Department], B.Quantity as [Quantity], 
                        isnull(C.Amount,0) as [Discount], B.AmountDue as [AmountDue],round(B.BasePrice*1.12,4) as [Gross Sales],
                         B.BasePrice + isnull(vsa.Tax,0) as [BasePrice], 
                        case when vsa.type = 0 then isnull(vsa.Amount,0) else 0.0000 end As [VAT Sales Amount],
                        case when vsa.type = 1 then isnull(vsa.Amount,0) else 0.0000 end As [VAT Exempt Sales Amount],
                        B.ServiceCharge as [ServiceCharge], isnull(vsa.Tax,0) As [VAT Sales Tax],
                        case when D.[Type] = 0 Then D.Tax Else 0 End As [Tax],
                        case when T.MediaIndex = 4 then T.Amount else 0 End As [GiftCert],
                        case when T.MediaIndex = 4 then 1 else 0 End As [GCCount]
                        FROM  CSSaleItem B WITH(NOLOCK)
                        LEFT JOIN CSSaleItemDiscount C WITH(NOLOCK) ON B.CSSaleItemID = C.CSSaleItemID
                        LEFT JOIN CSSale A WITH(NOLOCK) ON A.CSSaleID = B.CSSaleID
                        LEFT JOIN CSSaleItemTax D WITH(NOLOCK) ON B.CSSaleItemID = D.CSSaleItemID
                        LEFT JOIN (Select CSSaleItemID, Amount, Tax, [Type] From CSSaleItemTax WITH(NOLOCK) Where [Type] = 0)  As vsa  ON vsa.CSSaleItemID = B.CSSaleItemID
                        LEFT JOIN CSSaleTender T WITH(NOLOCK) ON T.CSSaleID = A.CSSaleID
                        Where   StoreDate   BETWEEN  convert(VARCHAR,@StartDate)   AND  convert(VARCHAR,@EndDate)  and a.RefundStoreDate IS NULL 
                        )
                        SELECT [Department], sum([Quantity]) as [Quantity], SUM([Tax]) as [Tax] , sum([Discount]) as [Discount], 
                        sum(([Gross Sales]+[ServiceCharge])) as [Gross Sales], sum(([BasePrice]+[ServiceCharge]-[Discount])) As [Net Sales],
                        sum(([BasePrice]+[ServiceCharge]-[Discount]))/
                        (Select  sum(NetSales) FROM  CSSale B LEFT JOIN (select csSaleID, Department from CSSaleItem WITH(NOLOCK) group by Department, CSSALEID ) AS A On A.CSSaleID = B. CSSaleID
                          Where   StoreDate   BETWEEN  convert(VARCHAR,@StartDate)   AND  convert(VARCHAR,@EndDate)  and RefundStoreDate IS NULL )*100 as [% Total],
                        sum([GiftCert]) as [Gift Cert Total], sum([ServiceCharge]) as [Service Charge], sum([GCCount]) as [GCCountTotal]
                        From SalesRange
                        Group By [Department] 
                        Order By [Department]  desc 
                    OPTION (OPTIMIZE FOR (@StartDate UNKNOWN, @EndDate UNKNOWN))
                END

子报表:

    ALTER PROCEDURE[dbo].[usp_ReportShowMedia](
       @StartDate2    DATETIME,
                @EndDate2      DATETIME
                )
 As
        BEGIN


      Select isnull(M.MediaName,'Other') As [Media], 
      COUNT(T.MediaIndex) As [Count], 
      isnull(sum(T.Amount),0) As [Sales Amount], 
      isnull(sum(case when S.EndDate IS NOT NULL and DateRefunded IS NULL Then       S.NetSales Else 0 End),0) As [Total Sales], 
      isnull(sum(case when S.EndDate IS NULL then S.NetSales else 0 end),0) as [Cancelled Sales],
      isnull(sum(case when S.DateRefunded IS NOT NULL then S.NetSales else 0 end),0) as [Refunded Sales]
      FROM  CSSale S WITH(NOLOCK)
      LEFT JOIN (Select CSSaleID, Department from CSSaleItem WITH(NOLOCK) group by CSSaleID,Department) As I ON I.CSSaleID = S.CSSaleID
      LEFT JOIN CSSaleTender T WITH(NOLOCK) On S.CSSaleID = T.CSSaleID
      LEFT JOIN Media M WITH(NOLOCK) ON M.MediaIndex = T.MediaIndex
      Where   StoreDate   BETWEEN  convert(VARCHAR,@StartDate2)   AND        convert(VARCHAR,@EndDate2) 
      group by M.MediaName
      order by M.MediaName
      OPTION (OPTIMIZE FOR (@StartDate2 UNKNOWN, @EndDate2 UNKNOWN))
        END

相同的结果,我认为主报告中没有通过子报告,因为它总是只在预览上工作,但在运行时只是停留在加载。

我试过sp_who2 Active来检查是否被阻止。 enter image description here

顺便说一下,我在我的App.config上使用此连接,如果这有帮助..

 <?xml version="1.0" encoding="utf-8" ?>
 <configuration>
<startup useLegacyV2RuntimeActivationPolicy="true"> 
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
</startup>
<runtime>
  <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
    <probing privatePath="lib" />
  </assemblyBinding>
</runtime>
<connectionStrings>
  <add name="CSPOS.Reports.Properties.Settings.chaplinConnectionString" connectionString="Data Source=RENZ\SQLEXPRESS;Initial Catalog=erika;Integrated Security=True" providerName="System.Data.SqlClient"/>
 </connectionStrings>
 </configuration>

我检查了主人的数据库权限

enter image description here

4 个答案:

答案 0 :(得分:1)

有一天我遇到过这样的情况。主要问题是存储过程中不同参数的错误执行计划。

可以通过 OPTION(OPTIMIZE FOR(@param UNKNOWN)修复。你可以在here中阅读所有内容。

第二个问题:查询中可能存在一些读锁定。如果报告数据不那么敏感,您可以使用标准 WITH(NOLOCK)提示( READ UNCOMMITTED 隔离级别)。

尝试将查询修改为如下所示并检查结果。

SELECT 
...
FROM CSSale S WITH(NOLOCK)
LEFT JOIN (... FROM CSSaleItem WITH(NOLOCK) ...)
LEFT JOIN CSSaleTender T WITH(NOLOCK) ...
LEFT JOIN Media M WITH(NOLOCK)
ORDER BY M.MediaName
OPTION (OPTIMIZE FOR (@StartDate2 UNKNOWN, @EndDate2 UNKNOWN))

您还需要检查用于相同问题的主查询的存储过程。

P.S。无论如何,检查 SQL Profiler 是否有传出的查询。

答案 1 :(得分:1)

让我们试着找出问题是否与存储过程有关。

尝试捕获传递给子报告的存储过程(dbo.usp_ReportShowMedia)的参数,方法是将它们作为SP的第一个语句插入到某个虚拟表(dbo.subReportParamsTb)中。

INSERT INTO dbo.subReportParamsTb(
StartDate2,
EndDate2
) 
VALUES (
@StartDate2,
@EndDate2
);

运行主报告后,当您看到卡住的消息时,请检查包含nolo的dbo.subReportParamsTb。

SELECT *
FROM dbo.subReportParamsTb WITH(NOLOCK);

如果您看到参数已成功传递给SP,请尝试使用这些参数独立运行SP。

如果SP在限定时间内没有产生输出,您可以通过查看执行计划来尝试进一步排除故障。

如果SP运行正常,您可以确定该问题不适用于SP。

答案 2 :(得分:0)

我认为这可能是两个报告之间的数据链接问题。请确保主报告和子报告具有唯一ID并正确链接。

答案 3 :(得分:0)

我通过使用两个sqlcommand来解决了这个问题,并且不再使用存储过程..感谢btw。