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