При разработке или кастомизации документов в 1С, особенно связанных с бухгалтерским учетом, многие разработчики сталкиваются с интересным поведением системы. Вы выбираете счет в поле ввода, и в ту же секунду поля субконто на форме магическим образом меняют свой тип: например, из СправочникСсылка.Склады превращаются в СправочникСсылка.Контрагенты. Самое удивительное, что если зайти в отладчик и поставить точку останова (удобно через инструмент отладки кода 1С в режиме Предприятие) в обработчике ПриИзменении для счета, выяснится, что типы субконто уже изменились еще до выполнения первой строчки вашего кода.
В этой статье мы подробно разберем, как реализована эта «магия» на уровне платформы 1С, изучим настройки метаданных (поможет расширение с консолью разработчика и анализом метаданных) и поймем, как повторить это поведение в собственных разработках.
Главный секрет кроется в свойстве реквизитов, которое называется Связь по типу (Type Link). Рассмотрим ситуацию, когда у нас есть объект (документ или обработка), содержащий реквизиты СчетУчета (что важно для понимания движения средств между счетами) и несколько реквизитов Субконто1, Субконто2 и так далее.
Проанализируем, как настроены эти реквизиты в конфигураторе:
Субконто1.СчетУчета.Когда мы указываем такую связь, платформа начинает автоматически отслеживать изменение значения в поле СчетУчета. Как только пользователь выбирает новый счет, система обращается к метаданным этого счета, анализирует его виды субконто и мгновенно перестраивает ОписаниеТипов для связанных полей субконто. Это происходит на «аппаратном» уровне ядра платформы (написанного на C++), именно поэтому мы не видим этого процесса в конфигурации в виде скриптов на языке 1С.
Чтобы связь по типу работала корректно для бухгалтерских счетов, система задействует объект План видов характеристик (чаще всего он называется «Виды субконто хозрасчетные»), что крайне важно, если вы создаете помощник формирования баланса с расшифровкой.
Разберем по шагам цепочку зависимостей, которую выстраивает платформа:
Тип значения жестко задано, какие данные он может хранить (например, СправочникСсылка.Контрагенты), что используется, когда выполняется сопоставление субконто при вводе остатков — для этого подойдёт обработка для переноса и корректировки остатков между счетами.Когда в поле Субконто1 настроена связь по типу со счетом, платформа понимает, что нужно взять тип из первой строки видов субконто выбранного счета. Если на счете 60.01 первым видом субконто стоят «Контрагенты», то реквизит Субконто1 автоматически ограничит свой тип до контрагентов.
Выясним причину, по которой отладчик показывает уже измененный тип данных в момент срабатывания обработчика ПриИзменении. В событийно-ориентированной модели 1С порядок действий при интерактивном изменении поля следующий:
ПривестиЗначение(). Если старое значение (например, Склад) не влезает в новый тип (Контрагенты), значение очищается и заменяется на пустую ссылку нового типа.ПриИзменении, где разработчик может дописать свою логику, например, расшифровку затратных счетов.Таким образом, к моменту начала работы вашего кода состояние объекта уже консистентно и соответствует новым правилам типизации.
Рассмотрим критически важный нюанс: чтобы описанная «магия» работала, реквизиты Субконто1..3 должны иметь составной тип данных. Если вы укажете для субконто только тип ЛюбаяСсылка, этого может быть недостаточно для корректной работы всех механизмов связи.
Обычно в типовых конфигурациях реквизиты субконто имеют тип, включающий в себя Характеристика.ВидыСубконтоХозрасчетные. Это специальный тип, который сообщает платформе: «в этом поле может лежать любой тип, который разрешен в данном Плане видов характеристик».
Если вы создаете самописный документ и хотите повторить это поведение, убедитесь, что:
Иногда автоматики платформы недостаточно, и нам нужно программно имитировать это поведение (например, при загрузке данных из внешних источников или в сложных обработках). В таких случаях мы используем объект ОписаниеТипов.
Проанализируем пример кода, который выполняет установку типа вручную, основываясь на данных Плана видов характеристик:
// Предположим, у нас есть выбранный счет и мы хотим настроить тип субконто
ВидСубконтоОбъект = СчетУчета.ВидыСубконто[0].ВидСубконто; // Получаем первый вид субконто счета
НужныйТип = ВидСубконтоОбъект.ТипЗначения; // Это объект ОписаниеТипов
// Теперь мы можем применить этот тип к реквизиту или элементу формы
// Если это управляемая форма, можно ограничить выбираемые типы для поля ввода:
Элементы.Субконто1.ОграничениеТипа = НужныйТип;
Элементы.Субконто1.ВыбиратьТип = Ложь;
// Если нужно очистить значение, если оно не соответствует типу:
Объект.Субконто1 = НужныйТип.ПривестиЗначение(Объект.Субконто1);
Использование метода ПривестиЗначение() крайне полезно, так как оно корректно обрабатывает ситуацию: если текущее значение уже входит в новый набор типов, оно сохранится. Если нет — станет пустой ссылкой нужного типа. Для анализа и интерактивного изменения параметров элементов формы пригодится обработка для редактирования свойств элементов управляемых форм в режиме «Предприятие».
В современных конфигурациях на управляемых формах механизм работает еще эффективнее. Платформа минимизирует количество серверных вызовов. Когда на клиенте меняется счет, информация о новых типах связанных полей может быть получена из кэша метаданных или через быстрый контекстный вызов.
Важный момент: если вы меняете значение счета программно в коде на сервере (например, в процедуре ПередЗаписью), автоматическая смена типов в интерфейсе может не отобразиться до тех пор, пока форма не будет перечитана или данные не будут переданы на клиент. Автоматика «Связи по типу» лучше всего проявляет себя именно при интерактивной работе пользователя с элементами формы.
Подведем итоги нашего анализа:
ПриИзменении всегда вызывается после того, как типы приведены к актуальному состоянию.Понимание этих основ позволяет разработчику меньше писать «лишнего» кода и эффективно использовать встроенные возможности 1С для создания динамических и интеллектуальных интерфейсов.