В процессе разработки на платформе 1С:Предприятие часто возникает задача хранения нескольких записей, относящихся к одному объекту и одной дате. Стандартный непериодический регистр сведений накладывает ограничение на уникальность комбинации измерений, что заставляет разработчиков искать обходные пути. В этой статье мы подробно разберем, как правильно организовать хранение «табличных» данных, проанализируем различные архитектурные подходы и выясним, почему не стоит бояться хранения секунд в периодических регистрах.
Разберем классический подход, который предлагает сама платформа 1С. Если нам необходимо фиксировать события, происходящие с человеком в течение дня (например, время сдачи и получения ТМЦ), оптимальным решением будет использование периодического регистра сведений с периодичностью В пределах секунды.
Рассмотрим, почему это эффективно. Многие начинающие разработчики опасаются, что хранение времени «раздует» базу данных. Однако с точки зрения СУБД (будь то MS SQL Server или PostgreSQL), поле типа Datetime всегда занимает фиксированный объем памяти. Даже если вы установите периодичность В пределах дня, платформа все равно будет хранить дату со временем 00:00:00. Использование секундной периодичности дает нам следующие преимущества:
СрезПоследних().Проанализируем структуру такого регистра:
Человек (ссылка на справочник).Действие (перечисление: Сдал, Получил), Комментарий.В пределах секунды.Если по каким-то причинам вы категорически хотите использовать непериодический регистр, но вам нужно хранить несколько строк за одну дату, мы можем прибегнуть к методу «ключей связи». Разберем, как это реализовать.
Для обеспечения уникальности в состав измерений регистра добавляется поле НомерСтроки (тип Число) или ИдентификаторЗаписи (тип УникальныйИдентификатор). В этом случае уникальность будет определяться связкой: Дата + Человек + НомерСтроки.
Посмотрим на пример программной записи в такой регистр:
МенеджерЗаписи = РегистрыСведений.МойРегистр.СоздатьМенеджерЗаписи();
МенеджерЗаписи.Период = ТекущаяДата();
МенеджерЗаписи.Человек = СсылкаНаЧеловека;
МенеджерЗаписи.НомерСтроки = ПоследнийНомер + 1; // Предварительно вычисляем
МенеджерЗаписи.Действие = Перечисления.Действия.Сдал;
МенеджерЗаписи.Записать();
Этот способ позволяет имитировать табличную часть документа, но требует ручного контроля нумерации строк и затрудняет получение «последнего» состояния объекта через стандартные механизмы платформы.
Рассмотрим ситуацию, когда данные не нужно анализировать в отчетах через SQL-запросы, а нужно лишь отображать их в форме объекта целиком. В этом случае мы можем использовать ресурс с типом ХранилищеЗначения. В этот ресурс можно упаковать практически любой объект 1С: ТаблицаЗначений, Структура или Массив.
Проанализируем процесс записи и чтения:
ХранилищеЗначения.
// Запись таблицы значений в регистр
ТаблицаДляХранения = Новый ТаблицаЗначений;
// ... заполнение таблицы данными ...
Хранилище = Новый ХранилищеЗначения(ТаблицаДляХранения, Новый СжатиеДанных(9));
МенеджерЗаписи = РегистрыСведений.ДанныеТаблиц.СоздатьМенеджерЗаписи();
МенеджерЗаписи.Объект = СсылкаНаОбъект;
МенеджерЗаписи.Данные = Хранилище;
МенеджерЗаписи.Записать();
Важное ограничение: Вы не сможете в консоли запросов написать условие типа «Где Таблица.Время = 08:50». Данные внутри ХранилищеЗначения бинарны и недоступны для языка запросов. Чтобы их прочитать, запись нужно извлечь программно.
Если необходимо хранить «таблицу» в текстовом виде, выясним, какой формат лучше. Вместо громоздкого XML в современных версиях 1С (8.3) рекомендуется использовать JSON. Это текстовый формат, который занимает значительно меньше места и работает быстрее.
Мы можем сериализовать массив структур в строку и записать её в ресурс регистра с типом Строка (неограниченной длины). Это удобно, если вы планируете передавать эти данные через веб-сервисы или использовать во внешних приложениях. Однако, как и в случае с хранилищем значения, полноценный поиск по внутренним полям строки в запросе будет невозможен или крайне непроизводителен.
Часто сама попытка «впихнуть» таблицу в регистр сведений говорит об ошибке проектирования. Проанализируем задачу: если у нас есть событие, которое содержит дату, ответственного и список действий, то в системе 1С для этого предназначен объект Документ.
Рассмотрим правильную архитектуру:
ЛистРегистрации.Сотрудник и Дата.События создаем колонки Время и ТипДействия.Такой подход обеспечивает ссылочную целостность и предоставляет пользователю удобный интерфейс для редактирования истории, который в регистрах сведений реализовать сложнее.
Если состав вашей «таблицы» заранее неизвестен или может меняться (сегодня фиксируем время сдачи, завтра — номер пропуска, послезавтра — температуру сотрудника), разберем использование Планов видов характеристик.
В этом случае в регистре сведений добавляется измерение ВидХарактеристики (ссылка на ПВХ), а ресурс Значение имеет составной тип данных. Это позволяет хранить произвольный набор параметров для одного человека на одну дату, не меняя структуру конфигурации при добавлении новых типов данных. Каждая «строка» вашей воображаемой таблицы станет отдельной записью в регистре сведений.
Подводя итог, выясним, какой метод выбрать:
Помните, что архитектура базы данных должна быть прозрачной. Использование «костылей» в виде сериализации таблиц в строки оправдано только в исключительных случаях, когда другие методы не обеспечивают требуемой производительности.