Использование в вычисляемом поле значений из разных меток времени
Рассмотрим использование в вычисляемом поле значений из разных меток времени. Задача: создать вычисляемое поле для сглаженного значения расхода воды. Сглаживание выполняется по трем соседним значениям: V[i] = (V1[i-1] + V1[i] + V1[i+1]) / 3, где V[i] - сглаженное значение расхода в подающей магистрали, V1[i-1] - значение расхода воды в подающей магистрали для предыдущей относительно текущей метки времени, V1[i] - значение расхода воды в подающей магистрали для текущей метки времени, V1[i+1] - значение расхода воды в подающей магистрали для следующей относительно текущей метки времени,
ШАГ 1. Создайте отчетную форму типа Ведомость параметров для объекта учета с колонками: Дата, i, V1[i-1], V1[i], V1[i + 1], V[i]
В секции Detail ячейку в колонке Дата назовите tableCell_DataDate и свяжите ее с полем DataDate из узла 'Архивы потреблений и интеграторов' В секции Detail ячейку в колонке V1[i] назовите current_V1 и свяжите ее с полем с полем V1 из узла 'Архив потреблений и интеграторов.Архив потреблений.ХВС 1' В секции Detail ячейку в колонке i назовите tableCell_i
ШАГ 2. Откройте вкладку Скрипты и скопируйте в нее следующий код:
using System;
using System.Collections.Generic;
using Lers.Reports;
// Коллекции возвращаемых значений для вычисляемых полей
Dictionary<DateTime, double?> calcValues = new Dictionary<DateTime, double?>();
Dictionary<DateTime, double?> previousValues = new Dictionary<DateTime, double?>();
Dictionary<DateTime, double?> currentValues = new Dictionary<DateTime, double?>();
Dictionary<DateTime, double?> nextValues = new Dictionary<DateTime, double?>();
// Отображаемый номер текущей записи
int k = 0;
// Обработчик события 'Запрос источника данных'
private void BaseReport_DataSourceDemanded(object sender, System.EventArgs e)
{
// Ячейка tableCell_DataDate связана с полем DataDate в узле 'Архив потреблений и интеграторов',
// который является источником данных для секции Detail
// Все его дочерние узлы синхронизированы по значению поля DataDate,
// которое определено для каждой записи независимо от наличия данных.
// Количество записей в источнике данных для секции Detail
int n = (int)DataSourceUtils.GetRecordsCount(tableCell_DataDate);
// Формируем коллекции возвращаемых значений для вычисляемых полей
for(int i = 0; i < n; i++)
{
// i - порядковый номер записи в источнике данных для секции Detail
// Текущая метка времени
var dataDate = (DateTime)DataSourceUtils.GetBindedValue(tableCell_DataDate, i);
// Ячейка tableCell_V1 связана с полем V1 из узла 'Архив потреблений и интеграторов.Архив потреблений.ХВС 1'
// Возвращаемое значение вычисляемого поля previousValue для текущей метки времени получаем из предыдущей метки
previousValues[dataDate] = (DataSourceUtils.GetBindedValue(current_V1, i - 1) as double?);
// Возвращаемое значение вычисляемого поля currentValue для текущей метки времени
currentValues[dataDate] = (DataSourceUtils.GetBindedValue(current_V1, i) as double?);
// Возвращаемое значение вычисляемого поля nextValue для текущей метки времени получаем из следующей метки
nextValues[dataDate] = (DataSourceUtils.GetBindedValue(current_V1, i + 1) as double?);
// Возвращаемое значение вычисляемого поля calcValue для текущей метки времени
calcValues[dataDate] = (previousValues[dataDate] + currentValues[dataDate] + nextValues[dataDate]) / 3;
}
}
// Обработчик скрипта 'Получить значение' для вычисляемых полей: previousValue, currentValue, nextValue, calcValue.
private void value_GetValue(object sender, DevExpress.XtraReports.UI.GetValueEventArgs e)
{
// Значение текущей метки времени
var dataDate = (DateTime)GetCurrentColumnValue("DataDate");
// Выбор возвращаемого значения по наименованию вычисляемого поля
switch (((CalculatedField)sender).Name)
{
case "previousValue":
e.Value = previousValues[dataDate];
break;
case "currentValue":
e.Value = currentValues[dataDate];
break;
case "nextValue":
e.Value = nextValues[dataDate];
break;
case "calcValue":
e.Value = calcValues[dataDate];
break;
}
}
// Вывод номера текущей записи
private void tableCell_i_PrintOnPage(object sender, DevExpress.XtraReports.UI.PrintOnPageEventArgs e)
{
tableCell_i.Text = (k++).ToString();
}
ШАГ 3. В узле 'Архивы потреблений и интеграторов' создайте вычисляемые поля с именами: previousValue, currentValue, nextValue и calcValue.
ШАГ 4. Для каждого из вычисляемых полей задайте свойство Получить значение равным value_GetValue.
ШАГ 5. В свойствах ячейки tableCell_i задайте скрипт Печать на странице равным tableCell_i_PrintOnPage.
ШАГ 6. В секции Detail свяжите ячейки в колонках V1[i-1], V1[i + 1], V[i] с вычисляемыми полями previousValue, nextValue и calcValue соответственно.
ШАГ 7. В секции ReportFooter свяжите ячейки в колонках V1[i-1], V1[i], V1[i + 1], V[i] с вычисляемыми полями previousValue, currentValue, nextValue, calcValue соответственно и задайте для них сводку суммирования по отчету.
ШАГ 8. Сохраните изменения.
ШАГ 9. Пример сформированного отчета.