Как получить предыдущее значение строки в SSRS

#sql-server #reporting-services #ssrs-2008-r2 #ssrs-2012

#sql-сервер #службы отчетов #ssrs-2008-r2 #ssrs-2012

Вопрос:

В моем отчете SSRS есть две группы (учетная запись, месяц). Учетная запись является родительской, а месяц — дочерней группой. Теперь я хочу показать конечный баланс каждого месяца как начальный баланс следующего месяца. Образец отчета приведен ниже. Красным шрифтом указана СУММА каждой группы. Помните, что я пытаюсь получить результат с помощью функции SSRS Previous(), но не могу получить ожидаемый результат.

 Previous(Sum(Fields!NetAmt.Value),"Month")
  

Месяц => Название группы месяцев.

Может ли кто-нибудь мне помочь?

Заранее спасибо.

Rashed

Пример данных SQL

 CREATE TABLE [dbo].[Balances](
    [id] [int] IDENTITY(1,1) NOT NULL,
    [Account] [nvarchar](50) NULL,
    [Month] [date] NULL,
    [BegBalance] [float] NULL,
    [Debit] [float] NULL,
    [Credit] [float] NULL,
    [EndBalance] [float] NULL,
 CONSTRAINT [PK_Balances] PRIMARY KEY CLUSTERED 
(
    [id] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET IDENTITY_INSERT [dbo].[Balances] ON
INSERT [dbo].[Balances] ([id], [Account], [Month], [BegBalance], [Debit], [Credit], [EndBalance]) VALUES (1, N'Cash', CAST(0xDB3A0B00 AS Date), 0, 100, 50, 50)
INSERT [dbo].[Balances] ([id], [Account], [Month], [BegBalance], [Debit], [Credit], [EndBalance]) VALUES (2, N'Cash', CAST(0xDB3A0B00 AS Date), 0, 200, 50, 150)
INSERT [dbo].[Balances] ([id], [Account], [Month], [BegBalance], [Debit], [Credit], [EndBalance]) VALUES (3, N'Cash', CAST(0xFA3A0B00 AS Date), 0, 200, 50, 150)
INSERT [dbo].[Balances] ([id], [Account], [Month], [BegBalance], [Debit], [Credit], [EndBalance]) VALUES (4, N'Cash', CAST(0xFA3A0B00 AS Date), 0, 200, 100, 100)
INSERT [dbo].[Balances] ([id], [Account], [Month], [BegBalance], [Debit], [Credit], [EndBalance]) VALUES (5, N'Mr.  Axxx', CAST(0xDB3A0B00 AS Date), 0, 200, 100, 100)
INSERT [dbo].[Balances] ([id], [Account], [Month], [BegBalance], [Debit], [Credit], [EndBalance]) VALUES (6, N'Mr.  Axxx', CAST(0xDB3A0B00 AS Date), 0, 100, 50, 50)
INSERT [dbo].[Balances] ([id], [Account], [Month], [BegBalance], [Debit], [Credit], [EndBalance]) VALUES (7, N'Mr.  Axxx', CAST(0xFA3A0B00 AS Date), 0, 100, 50, 50)
INSERT [dbo].[Balances] ([id], [Account], [Month], [BegBalance], [Debit], [Credit], [EndBalance]) VALUES (8, N'Mr.  Axxx', CAST(0xFA3A0B00 AS Date), 0, 100, 20, 80)
SET IDENTITY_INSERT [dbo].[Balances] OFF
  

После использования функции Previous()
введите описание изображения здесь

Комментарии:

1. Не могли бы вы добавить несколько примеров данных? Я думаю, что это может быть достигнуто.

Ответ №1:

Вы можете обработать это в SQL-запросе вашего набора данных, попробуйте использовать LAG() :

 SELECT mt.*, beg.begbal FROM [dbo].[Balances] mt
JOIN
(
SELECT [Account]
      ,[Month]
      ,SUM([EndBalance]) EndBal
      ,LAG (SUM([EndBalance]), 1, 0) OVER (PARTITION BY [Account] ORDER BY [Month] ASC) begbal
  FROM [dbo].[Balances]
  GROUP BY [Account]
      ,[Month]
) beg
ON mt.Month = beg.Month
AND mt.Account = beg.Account
  

Обновление: без использования LAG() попробуйте приведенный ниже код.

 WITH CTE AS
(
SELECT [Account]
      ,[Month]
      ,SUM([EndBalance]) EndBal
      ,ROW_NUMBER() OVER (PARTITION BY [Account] ORDER BY [Month] ASC) RowVal
  FROM [dbo].[Balances]
  GROUP BY [Account]
      ,[Month]
)

SELECT mt.*, ISNULL(t2.EndBal, 0) as begbal FROM CTE t1
LEFT JOIN CTE t2
ON t1.Account = t2.Account AND t1.RowVal = t2.RowVal   1
JOIN [dbo].[Balances] mt
ON t1.Month = mt.Month AND t1.Account = mt.Account
  

Кроме того, ниже приведен код выражения SSRS, который вы ищете:

 =IIF
(
(RunningValue(Fields!Month.Value, CountDistinct, "Account")) = 1,
0,
Previous(SUM(Fields!EndBalance.Value),"MonthGrp")
)
  

Комментарии:

1. Функция LAG() не поддерживается SQL server 2008 R2

2. Обновлен ответ с помощью выражения SSRS. Также замена T-SQL с использованием ROW_NUMBER() .

3. Спасибо за ваш код выражения SSRS. На самом деле я искал это. Для меня это отлично работает.

Ответ №2:

Вы можете использовать LOOKUPSET функцию и пользовательский код для получения предыдущего End Balance итога.

Перейдите в Report меню / Report properties... на Code вкладке вставить эту функцию VB.

 Public Function GetBegBal(values As Object) As String
    Dim total As Double = 0
    For Each value As Double In values
                      total = total   value
        Next
    Return total
End Function
  

В Beg Balance использовать это выражение:

 =Code.GetBegBal(
LOOKUPSET(
Fields!Account.Value amp; "-" amp; MONTH(Fields!Month.Value)-1,
Fields!Account.Value amp; "-" amp; MONTH(Fields!Month.Value),
Fields!EndBalance.Value,
"DataSetName")
)
  

Замените DataSetName на ваше фактическое имя, затем просмотрите свой отчет, он должен выглядеть так:

введите описание изображения здесь

Обратите внимание, что я использую MONTHNAME функцию в столбце Месяцы, поэтому она возвращает название месяца на основе региональных и языковых настроек на моем компьютере (испанский).

Дайте мне знать, если это поможет.