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