При разработке учетных документов начинающие разработчики часто сталкиваются с двумя вопросами: как правильно визуализировать строки документа на форме в виде привычной таблицы и как реализовать автоматический подсчет суммы значений из разных колонок одной строки. Разберем эти задачи подробно, от создания метаданных до написания программного кода обработчиков.
Проанализируем распространенную ошибку, когда для хранения вводимых пользователем строк документа пытаются программно создать объект ТаблицаЗначений. Объект ТаблицаЗначений является универсальной коллекцией значений, существующей исключительно в оперативной памяти, причем в клиент-серверной архитектуре управляемого приложения он доступен только на стороне сервера.
Для сохранения данных в базе данных у объекта конфигурации Документ предусмотрен специальный подчиненный объект — Табличная часть. Данные табличной части автоматически привязываются к документу, сохраняются при записи и проводятся по регистрам. Создавать программную таблицу значений в данном случае не требуется: достаточно сконфигурировать табличную часть в дереве метаданных.
ПитаниеСотрудников).Сотрудник — тип СправочникСсылка.Сотрудники;Завтрак, Обед, Ужин, ПозднийУжин — тип Число (длина 10, точность 0, неотрицательное);Итого — тип Число (для фиксации общего количества приемов пищи).Выясним причину ситуации, когда добавленные реквизиты табличной части отображаются на форме не в виде столбцов таблицы, а как разрозненные поля ввода. В редакторе управляемой формы структура интерфейса представлена двумя панелями: справа расположены Реквизиты (данные), а слева — Элементы (визуальные элементы управления).
Если перетаскивать подчиненные реквизиты табличной части в дерево элементов по одному, платформа 1С распознает их как единичные значения и создает для каждого отдельный элемент ПолеВвода. Чтобы получить полноценную таблицу со столбцами, выполним следующие шаги:
Объект и раскроем его ветку.ПитаниеСотрудников.При таком действии платформа автоматически создаст элемент управления ТаблицаФормы, привяжет его к данным табличной части объекта и внутри сформирует подчиненные элементы типа ПолеФормы (колонки) для каждого реквизита.
Рассмотрим различие между двумя типами расчетов в таблицах 1С: суммированием по вертикали и суммированием по горизонтали.
Свойство Путь к данным подвала (а также флаг ИтогВПодвале) предназначено только для вертикального агрегирования данных по одной конкретной колонке для всех строк таблицы (например, чтобы узнать общее число всех обедов во всем документе: Объект.ПитаниеСотрудников.ИтогОбед). Сложить значения из разных колонок одной строки через свойства подвала невозможно.
Для расчета горизонтальной суммы (Завтрак + Обед + Ужин + ПозднийУжин) в строке реализуется программный пересчет.
Разберем оптимальный способ расчета, выполняемый на стороне клиента без лишних серверных вызовов. Мы используем клиентское событие ПриИзменении элементов ввода таблицы.
ПитаниеСотрудниковЗавтрак.ПриИзменении и нажмем кнопку с лупой для создания клиентского обработчика.Обед, Ужин, ПозднийУжин) в палитре свойств укажем этот же созданный обработчик, чтобы не дублировать код.Посмотрим на код процедуры пересчета строки в модуле формы:
&НаКлиенте
Процедура ПитаниеСотрудниковКоличествоПриИзменении(Элемент)
ТекущаяСтрока = Элементы.ПитаниеСотрудников.ТекущиеДанные;
Если ТекущаяСтрока <> Неопределено Тогда
ТекущаяСтрока.Итого =
ТекущаяСтрока.Завтрак +
ТекущаяСтрока.Обед +
ТекущаяСтрока.Ужин +
ТекущаяСтрока.ПозднийУжин;
КонецЕсли;
КонецПроцедуры
Свойство Элементы.ПитаниеСотрудников.ТекущиеДанные возвращает объект ДанныеФормыЭлементКоллекции, представляющий активную строку таблицы на клиенте. Изменение свойства Итого мгновенно отображается на экране и фиксируется в данных документа без обращения к серверу.
Если разработка ведется на обычных формах (толстый клиент), в свойствах табличного поля доступно событие ПриПолученииДанных. В нем расчет колонки можно выполнять динамически без добавления реквизита Итого в саму структуру метаданных документа, выводя значение в ячейку через метод ОформлениеСтроки.Ячейки.Итого.УстановитьТекст(). Однако в управляемом приложении (тонкий и веб-клиент) данное событие отсутствует, поэтому описанный выше расчет через ПриИзменении является стандартным и универсальным решением.
Проанализируем архитектуру решения на перспективу. Фиксация каждого приема пищи отдельным реквизитом (колонкой) делает структуру жесткой: при необходимости добавить «Полдник» или «Ночной перекус» разработчику придется менять структуру метаданных документа, формы и алгоритмы проведения.
В типовых конфигурациях для подобных задач чаще применяют нормализованную структуру табличной части всего из трех реквизитов:
Сотрудник (тип СправочникСсылка.Сотрудники);ВидПриемаПищи (тип СправочникСсылка.ВидыПитания или ПеречислениеСсылка);Количество (тип Число).Такой подход позволяет добавлять любые новые категории питания пользователями в режиме «1С:Предприятие» без внесения изменений в конфигурацию.