В процессе эксплуатации высоконагруженных систем на платформе 1С:Предприятие 7.7 разработчики часто сталкиваются с проблемой: база данных достигает огромных размеров (десятки и сотни гигабайт), и любое добавление даже одного реквизита в документ вызывает многочасовую (а иногда и суточную) реструктуризацию. В этой ситуации возникает необходимость внедрения механизма псевдореквизитов — дополнительных свойств, которые хранятся вне основной таблицы документа, но отображаются и редактируются непосредственно в его форме.
В данной статье мы проанализируем различные подходы к решению этой задачи, разберем архитектурные нюансы и изучим конкретные примеры кода для реализации универсального хранилища характеристик.
Рассмотрим основные причины, по которым стоит отказаться от добавления штатных реквизитов в конфигураторе:
Это классический подход для 1С 7.7. Мы создаем справочник (например, ДопРеквизиты), где владельцем является наш документ. В справочнике создаются реквизиты ИмяРеквизита и Значение.
Плюсы: штатные средства контроля ссылочной целостности, привычный интерфейс.
Минусы: замедление записи документа (нужно записывать подчиненный объект), необходимость программно отрисовывать элементы на форме документа для редактирования этих данных.
Для систем на MS SQL Server это наиболее эффективный вариант. Мы создаем таблицу напрямую в SQL, минуя словарь метаданных 1С. Это позволяет избежать реструктуризации вовсе. Разберем реализацию этого метода подробнее, опираясь на программный комплекс для работы с дополнительными реквизитами.
Проанализируем структуру SQL-таблицы, которую мы можем создать для этих целей:
CREATE TABLE ДополнительныеРеквизитыОбъектов (
Объект char(13) Not Null, -- ID документа или элемента справочника
Имя varchar(256) Not Null, -- Техническое имя реквизита
Тип varchar(256) Not Null, -- Тип данных (Строка, Число, Ссылка)
Значение_Ссылка char(13), -- Для хранения ссылок на другие объекты 1С
Значение_Число Numeric(19, 3),
Значение_Строка varchar(256),
Значение_Дата DateTime
)
CREATE INDEX ОбъектИмя ON ДополнительныеРеквизитыОбъектов(Объект, Имя)
Рассмотрим метод установки значения такого реквизита. Нам необходимо сначала удалить старое значение, а затем вставить новое, чтобы избежать дублирования. Выясним, как это выглядит в коде 1С с использованием прямых запросов:
Функция Установить(Объект, Имя, Значение, Комментарий = "") Экспорт
Тип = ТипЗначенияСтр(Значение);
// Определяем, в какую колонку SQL писать данные в зависимости от типа 1С
Если Тип = "Число" Тогда
Значение_Имя = "Значение_Число";
Значение_Значение = "" + Значение;
ИначеЕсли Тип = "Строка" Тогда
Значение_Имя = "Значение_Строка";
Значение_Значение = "'" + Значение + "'";
// Обработка ссылочных типов (Документ, Справочник)
ИначеЕсли (Тип = "Документ") Или (Тип = "Справочник") Тогда
Значение_Имя = "Значение_Ссылка";
Значение_Значение = "'" + РадугаСервис.ЗначениеВДлиннуюСтрокуБД(Значение) + "'";
Тип = Тип + "." + Значение.Вид();
КонецЕсли;
идОбъект = РадугаСервис.ЗначениеВДлиннуюСтрокуБД(Объект);
ТекстЗапроса = "
|DELETE FROM ДополнительныеРеквизитыОбъектов
|WHERE Объект = '" + идОбъект + "' AND Имя = '" + Имя + "'
|
|INSERT INTO ДополнительныеРеквизитыОбъектов
| (Объект, Имя, Тип, " + Значение_Имя + ")
|VALUES
| ('" + идОбъект + "', '" + Имя + "', '" + Тип + "', " + Значение_Значение + ")
|";
Возврат ЗапросСКЛ.Выполнить(ТекстЗапроса);
КонецФункции
Если нам нужно добавить много реквизитов, которые по смыслу относятся к шапке, но мы не хотим трогать структуру шапки, можно использовать саму табличную часть документа. Для этого создаются служебные строки с определенным флагом (например, реквизит ТипСтроки = "Служебная").
Разберем этот метод: мы выделяем несколько колонок в ТЧ, которые в обычных строках пустуют, а в служебной — хранят наши "псевдореквизиты". При открытии формы мы фильтруем строки, визуально разделяя реальную табличную часть и "виртуальную шапку".
Важный момент: использование этого метода ограничено лимитом строк в табличной части (9999 строк для 7.7), поэтому для документов с огромными спецификациями он не подойдет.
Посмотрим на ситуацию, когда нам нужно хранить много мелких настроек. Вместо создания кучи полей или таблиц, мы создаем один текстовый реквизит в шапке документа с типом Строка (неограниченная длина).
Рассмотрим алгоритм работы:
СписокЗначений.ЗначениеВСтрокуВнутр() для сериализации списка в текст.ЗначениеИзСтрокиВнутр().Это самый простой в реализации способ, не требующий внешних компонент. Однако он делает невозможным поиск документов по этим свойствам через стандартные отчеты или SQL-запросы, так как данные внутри строки хранятся в специфическом формате 1С.
Проанализируем, как вывести эти данные пользователю. Поскольку в 1С 7.7 нет динамических форм, у нас есть два пути:
Форма.ИмяРеквизита.Видимость() и Форма.ИмяРеквизита.Заголовок().Выбор метода зависит от ваших задач. Если база небольшая и реструктуризация проходит быстро — лучше использовать штатные реквизиты. Если база огромная и вы работаете на SQL — оптимальным будет вариант с внешней SQL-таблицей и прямыми запросами. Для простых задач, где не требуется поиск, отлично подойдет сериализация в строку.
Помните, что внедрение псевдореквизитов усложняет код конфигурации, так как вам придется вручную обрабатывать копирование документов, их пометку на удаление и очистку данных. Тщательно продумайте эти механизмы перед началом разработки.