Нередко перед разработчиками 1С встает задача отображения данных по платежам или взаиморасчетам в виде наглядной матрицы («шахматки»), где по вертикали располагаются даты или документы, а по горизонтали — периоды (месяцы). При попытке реализовать такую структуру новички часто допускают архитектурные ошибки, пытаясь создать фиксированные реквизиты табличной части у справочника договоров. Разберем по шагам, почему такой подход некорректен, и рассмотрим правильные варианты реализации данной задачи.
Рассмотрим типичную ошибку: создание в справочнике табличной части с жестким набором колонок Месяц1, Месяц2, ..., Месяц12 и программное заполнение строк при проведении документов оплаты.
Проанализируем ключевые риски и ограничения такого подхода:
УчетОплаты.Договор.Ссылка = &ДСсылка порождает неявное левое соединение (LEFT JOIN) с таблицей справочника договоров. Для корректной оптимизации запроса следует обращаться напрямую к ссылочному измерению: УчетОплаты.Договор = &ДСсылка.Если табличная часть с предопределенным числом месяцев уже существует и требуется заполнить ее строками со смещением, разберем программный способ адресации полей без громоздких конструкций Если ... Тогда.
Вместо перебора условий используем индексацию через квадратные скобки по строковому имени колонки и встроенную функцию ДобавитьМесяц:
&НаСервере
Процедура ЗаполнитьГрафикНаСервере()
Объект.ГрафикПлатежей.Очистить();
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| УчетОплаты.ДатаОплаты КАК ДатаОплаты,
| УчетОплаты.МесяцОплаты КАК МесяцОплаты
|ИЗ
| РегистрСведений.УчетОплаты КАК УчетОплаты
|ГДЕ
| УчетОплаты.Договор = &ДСсылка";
Запрос.УстановитьПараметр("ДСсылка", Объект.Ссылка);
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
// Если оплата покрывает несколько месяцев, создаем соответствующие строки
Для Смещение = 1 По Выборка.МесяцОплаты Цикл
НоваяСтрока = Объект.ГрафикПлатежей.Добавить();
НоваяСтрока.ДатаОплаты = ДобавитьМесяц(Выборка.ДатаОплаты, Смещение - 1);
// Формируем имя колонки динамически и присваиваем значение
ИмяКолонки = "Месяц" + Формат(Смещение, "ЧГ=");
НоваяСтрока[ИмяКолонки] = Выборка.МесяцОплаты;
КонецЦикла;
КонецЦикла;
КонецПроцедуры
Наиболее грамотный способ с точки зрения платформы — не хранить данные в метаданных справочника, а динамически формировать таблицу в памяти формы при ее открытии. Для этого используется реквизит формы с типом ТаблицаЗначений, метод ИзменитьРеквизиты() и добавление элементов управления.
Посмотрим на пример создания колонок на клиенте и сервере:
&НаСервере
Процедура СформироватьДинамическуюТаблицуНаСервере(КоличествоМесяцев)
// Создаем массив добавляемых реквизитов формы
ДобавляемыеРеквизиты = Новый Массив;
Для НомерКолонки = 1 По КоличествоМесяцев Цикл
ИмяКолонки = "Месяц_" + Формат(НомерКолонки, "ЧГ=");
ТипРеквизита = Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(10, 2));
Реквизит = Новый РеквизитФормы(ИмяКолонки, ТипРеквизита, "ТаблицаОплатНаФорме", "Месяц " + НомерКолонки);
ДобавляемыеРеквизиты.Добавить(Реквизит);
КонецЦикла;
ИзменитьРеквизиты(ДобавляемыеРеквизиты);
// Создаем элементы интерфейса
Для Каждого Реквизит Из ДобавляемыеРеквизиты Цикл
ЭлементКолонка = Элементы.Добавить(Реквизит.Имя, Тип("ПолеФормы"), Элементы.ТаблицаОплатНаФорме);
ЭлементКолонка.Вид = ВидПоляФормы.ПолеВвода;
ЭлементКолонка.ПутьКДанным = "ТаблицаОплатНаФорме." + Реквизит.Имя;
КонецЦикла;
КонецПроцедуры
Когда шахматка требуется только для аналитики и просмотра, оптимальным решением является вывод отчета на базе Системы компоновки данных (СКД) прямо на форму элемента справочника или использование элемента управления Поле табличного документа.
Разберем преимущества этого способа:
УчетОплаты в момент открытия или по требованию пользователя, не затрагивая данные самого договора.Таким образом, для реализации матричных структур следует разделять хранение данных (регистры сведений) и их визуальное представление (динамические таблицы формы или отчеты СКД), избегая принудительного расширения табличных частей объектов нормативно-справочной информации.