如何构建前滚SSRS报告

时间:2017-01-22 21:31:20

标签: sql-server reporting-services ssrs-2008

我一直在制作一份报告,允许用户查看前滚的总数。

这是一个矩阵。我已经在数据中包含了一个示例。

该报告应该从10月开始计算运行总额42美元。然后报告将对帐户进行总结。然后拿42美元+ 64美元= 106美元。 106美元将结转到12月份开始的余额为106美元。

报告我正在努力 Report that I am working on

报告示例

                     2016-011            2016-012

Beginning Balance       42                   106

AP                      31                    41
APAJ                    32                    42
CJ                      33                    43
GEN                    -32                   -42

Total Account           64                    84

Begin Bal + Total Acc  106                   190

数据示例

DECLARE @ClosingBalTemp TABLE
(
  Account_ID varchar(30),
  Period_Nbr varchar(10),
  Source_Code varchar(10),
  Closing_Balance_Amt numeric(16,2)
)

INSERT INTO @ClosingBalTemp (Account_ID, Period_Nbr, Source_Code, Closing_Balance_Amt)

    VALUES ('01-002-333', '2016-008', 'AP', 1),
           ('01-002-333', '2016-008', 'APAJ', 2),
           ('01-002-333', '2016-008', 'CJ', 3),
           ('01-002-333', '2016-008', 'GEN', -2),
           ('01-002-333', '2016-009', 'AP', 11),
           ('01-002-333', '2016-009', 'APAJ', 12),
           ('01-002-333', '2016-009', 'CJ', 13),
           ('01-002-333', '2016-009', 'GEN', -12),
           ('01-002-333', '2016-010', 'AP', 20),
           ('01-002-333', '2016-010', 'APAJ', 21),
           ('01-002-333', '2016-010', 'CJ', 23),
           ('01-002-333', '2016-010', 'GEN', -22),
           ('01-002-333', '2016-011', 'AP', 31),
           ('01-002-333', '2016-011', 'APAJ', 32),
           ('01-002-333', '2016-011', 'CJ', 33),
           ('01-002-333', '2016-011', 'GEN', -32),
           ('01-002-333', '2016-012', 'AP', 41),
           ('01-002-333', '2016-012', 'APAJ', 42),
           ('01-002-333', '2016-012', 'CJ', 43),
           ('01-002-333', '2016-012', 'GEN', -42)

SELECT * FROM @ClosingBalTemp


The data should look like this

The logic is almost working. The Bal type is not calculating the running balance correctly after Period 9. The 4.00 is coming from Oct that does not display.

B   BAL    2016 9   4.00
T   AP     2016 9   11.00
T   APAJ   2016 9   12.00
T   CJ     2016 9   13.00
T   GEN    2016 9   -12.00
B   BAL    2016 10  24.00     **Should be 33**
T   AP     2016 10  20.00
T   APAJ   2016 10  21.00
T   CJ     2016 10  23.00
T   GEN    2016 10  -22.00
B   BAL    2016 11  42.00     **Should be 75**
T   AP     2016 11  31.00
T   APAJ   2016 11  32.00
T   CJ     2016 11  33.00
T   GEN    2016 11  -32.00
B   BAL    2016 12  64.00     **Should be 139**
T   AP     2016 12  41.00
T   APAJ   2016 12  42.00
T   CJ     2016 12  43.00
T   GEN    2016 12  -42.00

2 个答案:

答案 0 :(得分:0)

在这里查看runningvalue():https://msdn.microsoft.com/en-us/library/dd255229.aspx 这可以与组一起用作范围,因此可以在列组中使用。

答案 1 :(得分:0)

由于列布局,我不认为运行总计会起作用。我们希望2016-012的顶部来自2016-011的底部。我会说我不太了解你的数据集,我做了很多前滚/试算余额Hers's s post on Trial blances。但我相信我已经使用建议的存储过程使用2008年的东西解决了你的问题。理想情况下,年份和期间将是单独的字段,以便更容易计算期间。我现在只是硬编码了。 使用输出,您可以在SSRS报告中为每个月创建一列。您可以在SSRS中自己计算月末总数。 在2008年可能有更好的方法来做到这一点,但我的服务器上没有2008,所以我无法测试。 (我会以不同的方式处理初始余额汇总)

DECLARE @CurrentPeriod CHAR(10);
DECLARE @PriorPeriod CHAR(10);
DECLARE @PPPeriod CHAR(10)

SET @CurrentPeriod = '2016-012';
SET @PriorPeriod = '2016-011';
SET @PPPeriod = '2016-010';
-- First Step - Summarize the balances
WITH Balances (CurrentPeriodOpenBal, PriorPeriodOpenBal)
  AS (
     SELECT SUM(CASE WHEN cbt.Period_Nbr IN (@PPPeriod, @PriorPeriod)
            THEN cbt.Closing_Balance_Amt ELSE 0 END)
            AS CurrentPeriodOpenBal,
        SUM(CASE WHEN cbt.Period_Nbr IN (@PPPeriod) 
            THEN cbt.Closing_Balance_Amt ELSE 0 END) 
            AS PriorPeriodOpenBal
        FROM dbo.ClosingBalTemp cbt
        WHERE cbt.Period_Nbr < @CurrentPeriod
  )
-- Now we are going to combine our balances and our transaction
,
BalTrans (TransType, SourceCode, PeriodNbr, Amount) AS
(
SELECT 'B', 'BAL', @PriorPeriod, bal.PriorPeriodOpenBal 
FROM Balances bal   
UNION ALL 
SELECT 'B', 'BAL', @CurrentPeriod, bal.CurrentPeriodOpenBal 
FROM Balances  bal
UNION ALL  
SELECT 'T', trans.Source_Code, trans.Period_Nbr,  trans.Closing_Balance_Amt
   FROM dbo.ClosingBalTemp trans
  WHERE trans.Period_Nbr BETWEEN @PriorPeriod AND @CurrentPeriod
)
-- Now we simply order our transactions   
SELECT bt.TransType, bt.SourceCode, bt.PeriodNbr, bt.Amount FROM BalTrans bt
 ORDER BY bt.PeriodNbr, bt.TransType, bt.SourceCode

---修订版

-- First Step - convert period to fiscla year and period
WITH Trans AS
  (SELECT cbt.Account_ID, 
    cbt.Period_Nbr,
    CAST(SUBSTRING(cbt.Period_Nbr,1,4) AS INT) AS FiscalYear,
    CAST(SUBSTRING(cbt.Period_Nbr,6,3) AS INT) AS FiscalPeriod,
    cbt.Source_Code,
    cbt.Closing_Balance_Amt
    FROM dbo.ClosingBalTemp cbt) 


-- This gets the total balance for each period - we add one to the period
-- to figure out the opening info
, Balances ( FiscalYear, FiscalPeriod, OpenPeriod, Amount)
 AS (
  SELECT DISTINCT
       bal.FiscalYear,
       bal.FiscalPeriod,
       bal.FiscalPeriod + 1 AS OpenPeriod,
       SUM(bal.Closing_Balance_Amt) OVER(ORDER BY bal.Period_Nbr) AS Amount  
        FROM Trans bal
        WHERE bal.Period_Nbr >= @PPPeriod 
          AND bal.Period_Nbr  < @StartingPeriod
  )
-- Now we are going to combine our balances and our transaction
,

BalTrans (TransType, SourceCode, FiscalYear, FiscalPeriod, Amount) AS
(
 SELECT 'B', 'BAL', bl.FiscalYear, bl.OpenPeriod, bl.Amount FROM Balances bl    
UNION ALL 
SELECT 'T', trans.Source_Code, trans.FiscalYear, trans.FiscalPeriod, 
        trans.Closing_Balance_Amt
FROM Trans trans
WHERE trans.Period_Nbr BETWEEN @EndingPeriod AND @StartingPeriod
)   
SELECT bt.TransType, bt.SourceCode, bt.FiscalYear, Bt.FiscalPeriod,
 bt.Amount FROM BalTrans bt
ORDER BY bt.FiscalYear, bt.FiscalPeriod, bt.TransType, bt.SourceCode

- 光标示例

DECLARE @EndPeriod CHAR(10);
DECLARE @StartPeriod CHAR(10);
DECLARE @PPPeriod CHAR(10)
-- Ideally, year and period would be separate integer fields
-- so one could calculate prior period from current Period.
-- But that's not the key part of the question 
SET @EndPeriod = '2016-012';
SET @StartPeriod = '2016-009';
SET @PPPeriod = '2016-008';

DECLARE @Period_Nbr CHAR(10);
DECLARE @Source_Code CHAR(10);
DECLARE @Closing_Balance_Amt NUMERIC(16,2);

DECLARE @ReportPeriod CHAR(10);
DECLARE @ReportBalance NUMERIC(16,2);

CREATE TABLE #Output 
( ID INTEGER IDENTITY (1,1) PRIMARY KEY,   
  Period_Nbr CHAR(10), 
  Source_Code CHAR(10),
  Closing_Balance_Amt numeric(10,2)
  )
  -- the following insures that SSRS sees the output correctly
IF 1=2
  BEGIN
     SELECT ID,
        Period_Nbr,
        Source_Code,
        Closing_Balance_Amt
        FROM #Output;
  END;

DECLARE OMGUAC CURSOR FAST_FORWARD FOR
  SELECT Period_Nbr, Source_Code, Closing_Balance_Amt
  FROM dbo.ClosingBalTemp
  WHERE Period_Nbr BETWEEN @PPPeriod AND @EndPeriod
  ORDER BY Period_Nbr, Source_Code;

OPEN OMGUAC;

FETCH NEXT FROM OMGUAC INTO @Period_Nbr,@Source_Code,@Closing_Balance_Amt;

SET @ReportPeriod = @Period_Nbr;
SET @ReportBalance = 0;

WHILE @@FETCH_STATUS = 0
  BEGIN 
    -- When the period Changes, print the opening balance
     IF @Period_Nbr <> @ReportPeriod    
        BEGIN 
            INSERT INTO #Output
                ( Period_Nbr ,
                  Source_Code ,
                  Closing_Balance_Amt
                )
            VALUES  (@Period_Nbr, 'Open Bal',@ReportBalance);
        END
 IF @Period_Nbr > @PPPeriod
    BEGIN 
        INSERT INTO #Output
                ( Period_Nbr ,
                  Source_Code ,
                  Closing_Balance_Amt
                )
        VALUES  (@Period_Nbr, @Source_Code,@Closing_Balance_Amt);
    END
  SET @ReportBalance = @ReportBalance + @Closing_Balance_Amt;
  SET @ReportPeriod = @Period_Nbr
  FETCH NEXT FROM OMGUAC INTO @Period_Nbr, @Source_Code,
 @Closing_Balance_Amt;
   END;
SELECT * FROM #Output 
ORDER BY ID;
DROP TABLE #Output;
CLOSE OMGUAC;
DEALLOCATE OMGUAC;