Table of Contents

Использование в вычисляемом поле значений из разных меток времени

Рассмотрим использование в вычисляемом поле значений из разных меток времени. Задача: создать вычисляемое поле для сглаженного значения расхода воды. Сглаживание выполняется по трем соседним значениям: 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. Пример сформированного отчета.