При разработке и доработке управляемых форм в 1С начинающие разработчики часто сталкиваются с ситуацией, когда условие проверки значения реквизита не срабатывает, либо код вызывает ошибки времени выполнения. Разберем по шагам типичные ошибки, возникающие при сравнении договора контрагента со строковыми значениями, выясним причину их появления и рассмотрим правильные варианты реализации логики.
Рассмотрим распространенные ошибки, которые допускаются при попытке сопоставить ссылочное поле с текстовым значением:
Объект.ДоговорКонтрагента содержит значение ссылочного типа (СправочникСсылка.ДоговорыКонтрагентов), а не текст. Конструкция вида Если Объект.ДоговорКонтрагента = "Договор № 61" всегда возвращает Ложь, так как типы данных не совпадают.Объект.ДоговорКонтрагента.Код или Объект.ДоговорКонтрагента.Наименование) вызывает ошибку «Поле объекта не обнаружено», так как на клиенте ссылка не содержит данных самого объекта.Справочники доступна только на стороне сервера. При вызове Справочники.ДоговорыКонтрагентов.НайтиПоНаименованию(...) в процедуре с директивой &НаКлиенте платформа выдает ошибку «Переменная не определена (Справочники)».Объект.БанковскийСчетОрганизации приводит к тому, что поле очищается платформой, поскольку строковое значение не может быть преобразовано в ссылку справочника банковских счетов.Если необходимо проверить наименование договора без выполнения дополнительного поиска по всей таблице справочника, обратимся к реквизиту ссылки на стороне сервера. Рассмотрим пример обработчика события изменения договора:
&НаКлиенте
Процедура ДоговорКонтрагентаПриИзменении(Элемент)
ДоговорКонтрагентаПриИзмененииНаСервере();
КонецПроцедуры
&НаСервере
Процедура ДоговорКонтрагентаПриИзмененииНаСервере()
Если Не ЗначениеЗаполнено(Объект.ДоговорКонтрагента) Тогда
Возврат;
КонецЕсли;
// На сервере обращение через точку к реквизитам ссылки допустимо
Если Объект.ДоговорКонтрагента.Наименование = "Договор № 61/ВЭ от 10.07.2017" Тогда
// Устанавливаем соответствующий банковский счет
УстановитьБанковскийСчетПоУмолчанию();
КонецЕсли;
КонецПроцедуры
В случаях, когда выполняется поиск конкретного элемента через менеджер справочника, важно сравнивать полученную ссылку со ссылкой в документе, а не с текстом. Проанализируем правильный пример:
&НаСервере
Процедура ПроверитьДоговорИЗаполнитьСчет()
СсылкаНаДоговор = Справочники.ДоговорыКонтрагентов.НайтиПоНаименованию("Договор № 61/ВЭ от 10.07.2017", Истина);
Если ЗначениеЗаполнено(СсылкаНаДоговор) И Объект.ДоговорКонтрагента = СсылкаНаДоговор Тогда
// Действия при совпадении договоров
КонецЕсли;
КонецПроцедуры
Справочник банковских счетов является подчиненным (владельцем выступает организация или контрагент). Если выполнять поиск по наименованию без указания владельца, метод НайтиПоНаименованию вернет пустую ссылку, из-за чего реквизит документа очистится. Кроме того, наименование счета в базе данных (например, «Расчетный в рублях») часто не совпадает с наименованием самого банка.
Посмотрим на корректный поиск банковского счета с явным указанием владельца:
&НаСервере
Процедура УстановитьБанковскийСчетПоУмолчанию()
// Поиск счета с фильтром по владельцу (Объект.Организация)
НайденныйСчет = Справочники.БанковскиеСчетаОрганизаций.НайтиПоНаименованию("Расчетный", Истина, , Объект.Организация);
Если ЗначениеЗаполнено(НайденныйСчет) Тогда
Объект.БанковскийСчетОрганизации = НайденныйСчет;
Иначе
// Если поиск по наименованию не подходит, ищем по номеру счета
НайденныйСчетПоНомеру = Справочники.БанковскиеСчетаОрганизаций.НайтиПоРеквизиту("НомерСчета", "40702810XXXXXXXXXXXX", , Объект.Организация);
Если ЗначениеЗаполнено(НайденныйСчетПоНомеру) Тогда
Объект.БанковскийСчетОрганизации = НайденныйСчетПоНомеру;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Рассмотрим, почему «зашивать» конкретные наименования и коды в программный код не рекомендуется, и какие альтернативы следует использовать:
Справочники.БанковскиеСчетаОрганизаций.ПолучитьСсылку(Новый УникальныйИдентификатор("...")).