Как автоматически заполнить реквизит контрагента или перевозчика в форме документа 1С?

Программист 1С v8.3 (Управляемые формы) 1С:Управление торговлей Управленческий учет Торговля и дистрибуция
← На главную

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

Типичные ошибки при заполнении ссылочных полей формы

Проанализируем распространенные ошибки, которые приводят к неработоспособности алгоритма:

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

Способ 1. Заполнение реквизита в форме документа (ПриСозданииНаСервере)

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

Рассмотрим пример кода в модуле формы документа:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    
    // Проверяем, что документ новый и реквизит еще не заполнен
    Если Объект.Ссылка.Пустая() И Не ЗначениеЗаполнено(Объект.Перевозчик) Тогда
        
        // Выполняем точный поиск контрагента по наименованию
        СсылкаПеревозчик = Справочники.Контрагенты.НайтиПоНаименованию("ТрансЛогистик ООО", Истина);
        
        Если ЗначениеЗаполнено(СсылкаПеревозчик) Тогда
            Объект.Перевозчик = СсылкаПеревозчик;
        КонецЕсли;
        
    КонецЕсли;

КонецПроцедуры

Обратите внимание на второй параметр Истина в методе НайтиПоНаименованию() — он включает режим строгого точного соответствия строки.

Способ 2. Архитектурно правильное решение: ОбработкаЗаполнения в модуле объекта

Платформенно более надежным подходом является вынос логики инициализации реквизитов в модуль самого документа — в процедуру ОбработкаЗаполнения. Это гарантирует, что контрагент по умолчанию заполнится не только при открытии формы пользователем, но и при программном создании документа (например, при загрузке из внешних систем, обработках или фоновых заданиях).

Посмотрим на пример кода в модуле объекта документа:


Процедура ОбработкаЗаполнения(ДанныеЗаполнения, ТекстЗаполнения, СтандартнаяОбработка)
    
    // Вызываем типовую логику заполнения
    БазовоеЗаполнение = Истина;
    
    // Устанавливаем значение по умолчанию, если оно не заполнено
    Если Не ЗначениеЗаполнено(ЭтотОбъект.Перевозчик) Тогда
        СсылкаПеревозчик = Справочники.Контрагенты.НайтиПоНаименованию("ТрансЛогистик ООО", Истина);
        Если ЗначениеЗаполнено(СсылкаПеревозчик) Тогда
            ЭтотОбъект.Перевозчик = СсылкаПеревозчик;
        КонецЕсли;
    КонецЕсли;

КонецПроцедуры

Как отладить поиск, если метод НайтиПоНаименованию возвращает пустую ссылку

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

  1. Проверка через интерактивный выбор: Откройте форму документа в режиме «1С:Предприятие», вручную выберите нужного контрагента из справочника и выведите его точное системное наименование и код через отладчик или временную команду формы:
    
    &НаКлиенте
    Процедура ПроверитьЗначение(Команда)
        Если ЗначениеЗаполнено(Объект.Перевозчик) Тогда
            Сообщить("Выбран контрагент: [" + Строка(Объект.Перевозчик) + "]");
        КонецЕсли;
    КонецПроцедуры
    
  2. Проверка неразрывных пробелов и скрытых символов: При копировании названий организаций из внешних документов или сайтов в наименование могут попадать неразрывные пробелы (Символы.НПП) или пробелы в конце строки, из-за чего строковое сравнение выдает ложь.
  3. Поиск через запрос с условием ПОДОБНО: Если точное наименование неизвестно или может содержать лишние пробелы, используем запрос:
    
    &НаСервере
    Функция НайтиКонтрагентаПоФрагменту(ТекстПоиска)
        
        Запрос = Новый Запрос;
        Запрос.Текст = 
            "ВЫБРАТЬ ПЕРВЫЕ 1
            |	Контрагенты.Ссылка КАК Ссылка
            |ИЗ
            |	Справочник.Контрагенты КАК Контрагенты
            |ГДЕ
            |	Контрагенты.Наименование ПОДОБНО &ШаблонПоиска
            |	И НЕ Контрагенты.ПометкаУдаления";
        
        Запрос.УстановитьПараметр("ШаблонПоиска", "%" + ТекстПоиска + "%");
        Выборка = Запрос.Выполнить().Выбрать();
        
        Если Выборка.Следующий() Тогда
            Возврат Выборка.Ссылка;
        КонецЕсли;
        
        Возврат Справочники.Контрагенты.ПустаяСсылка();
    
    КонецФункции
    

Лучшие практики: отказ от жесткого кодирования строк

Жестко прописывать строки с наименованиями (hardcode) непосредственно в тексте программы считается плохой практикой: при переименовании контрагента пользователями в режиме «1С:Предприятие» программный код перестанет работать. Рассмотрим альтернативные надежные подходы:

  1. Использование константы или регистра настроек: Создайте в конфигурации константу (например, ОсновнойПеревозчик) с типом СправочникСсылка.Контрагенты. Администратор один раз выбирает нужное значение в пользовательском интерфейсе, а в коде значение извлекается через Константы.ОсновнойПеревозчик.Получить().
  2. Предопределенные элементы: Если элемент справочника является системным и неизменным, создайте его в дереве метаданных как предопределенный элемент справочника Контрагенты. В коде обращение к нему выполняется напрямую без поиска: Справочники.Контрагенты.ОсновнойПеревозчик.
  3. Поиск по уникальному идентификатору (UUID): Если создание константы невозможно, зафиксируйте системный идентификатор (GUID) элемента и получайте ссылку напрямую через Справочники.Контрагенты.ПолучитьСсылку(Новый УникальныйИдентификатор("...")).
← На главную