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