Почему форма документа в 1С ведет себя как справочник и как это исправить?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

Разберем ситуацию, с которой часто сталкиваются начинающие разработчики. Вы создаете форму документа, добавляете на нее реквизиты, но при запуске в режиме Предприятия платформа автоматически называет ее «Справочник Создание». Более того, при попытке сохранить документ включаются проверки заполнения из справочника, и вместо документа в базе создается новый элемент справочника. Проанализируем причину такого поведения и выясним, как правильно настроить форму.

Причины возникновения проблемы

В платформе 1С поведение формы (её функциональное «расширение») жестко определяется тем, какой из реквизитов формы назначен основным. Если форма документа внезапно стала вести себя как справочник, это означает, что тип основного реквизита имеет значение СправочникОбъект.<Имя>, а не ДокументОбъект.<Имя>.

Рассмотрим подробнее, в каких случаях это чаще всего происходит:

  1. Форма создавалась не через стандартный конструктор (где реквизит Объект с правильным типом создается автоматически), а «с нуля». В процессе разработки был вручную добавлен реквизит с типом справочника, и ему ошибочно был установлен флаг основного реквизита.
  2. В уже существующей форме в свойствах основного реквизита Объект был случайно изменен тип данных с документа на справочник.

Важно помнить ограничения платформы: управляемая форма может иметь только один основной реквизит. Невозможно сделать так, чтобы одна и та же форма стандартными кнопками «Записать» или «Провести и закрыть» одновременно сохраняла и документ, и элемент справочника. Стандартные команды всегда работают исключительно в контексте того объекта, который указан основным.

Решение без программирования: вывод связанных данных

Если наша главная задача — просто отобразить информацию из справочника на форме документа и сохранить связь с этим справочником, процедурный код нам не понадобится. В 1С есть встроенный механизм вывода связанных данных. Разберем по шагам, как это настроить:

  1. Для начала найдем основной реквизит. В конструкторе управляемой формы (вкладка «Реквизиты», правая панель) он выделен жирным шрифтом. В свойствах этого реквизита установлена галка «Основной реквизит».
  2. Вернем основному реквизиту формы правильный тип — ДокументОбъект.<ИмяВашегоДокумента>.
  3. В самом документе (в дереве метаданных конфигуратора) создадим реквизит с типом СправочникСсылка.<ИмяВашегоСправочника>.
  4. В редакторе формы развернем реквизит Объект нажатием на значок «+», затем найдем добавленный реквизит-ссылку на справочник и развернем уже его.
  5. Откроется список внутренних полей справочника. Выберем нужные поля и просто перетащим их мышью в левую часть конструктора (в дерево элементов формы).

При таком подходе платформа сама обеспечит отображение данных. Как только в документе пользователь выберет элемент справочника, вынесенные на форму поля автоматически заполнятся. Они будут доступны только для чтения и не приведут к созданию новых записей в самом справочнике при записи документа.

Альтернативный вариант: копирование значений из справочника (с использованием кода)

Посмотрим на пример, когда значения из справочника нужно не просто показать для чтения, а физически скопировать в независимые свободные поля документа. В этом случае нам нужно, чтобы пользователь мог их отредактировать перед сохранением. Без программирования здесь обойтись нельзя.

Для реализации этого алгоритма нам потребуется обработать выбор значения. Разберем процесс:

  1. Для элемента формы документа, в котором выбирается ссылка на справочник, создадим обработчик события ПриИзменении.
  2. Прямое чтение полей справочника через ссылку на клиенте может привести к лишним серверным вызовам или ошибкам. Поэтому из клиентской процедуры вызовем серверную функцию.
  3. В серверную функцию передадим ссылку на выбранный элемент. На сервере считаем нужные поля и вернем их обратно на клиент (например, в виде структуры).
  4. На клиенте программно присвоим полученные значения соответствующим реквизитам документа, обращаясь к ним через Объект.

Пример реализации в модуле формы:


&НаКлиенте
Процедура КонтрагентПриИзменении(Элемент)
    
    // Получаем данные с сервера
    ДанныеСправочника = ПолучитьДанныеКонтрагента(Объект.Контрагент);
    
    // Заполняем свободные реквизиты документа
    Объект.АдресДоставки = ДанныеСправочника.Адрес;
    Объект.КонтактныйТелефон = ДанныеСправочника.Телефон;
    
КонецПроцедуры

&НаСервереБезКонтекста
Функция ПолучитьДанныеКонтрагента(СсылкаНаКонтрагента)
    
    Результат = Новый Структура("Адрес, Телефон");
    
    Если ЗначениеЗаполнено(СсылкаНаКонтрагента) Тогда
        Результат.Адрес = СсылкаНаКонтрагента.ЮридическийАдрес;
        Результат.Телефон = СсылкаНаКонтрагента.ОсновнойТелефон;
    КонецЕсли;
    
    Возврат Результат;
    
КонецФункции

Используя описанные методы, вы сможете настроить форму так, чтобы она корректно работала в контексте документа, правильно сохраняла данные и удобно отображала информацию из связанных справочников.

← На главную