В практике разработки расширений для типовых конфигураций (например, 1С:Управление торговлей или 1С:ERP) часто встречается задача обогащения данных контрагентов. Одной из таких задач является автоматическое определение географической принадлежности партнера, например, его Федерального округа, на основании введенного ИНН. Давайте подробно разберем, как реализовать этот функционал правильно, избежав распространенных ошибок в коде и методологии.
Рассмотрим типичное требование заказчика: при создании или редактировании карточки партнера (контрагента) система должна автоматически заполнять поле «Федеральный округ». Логика, которую часто предлагают на старте: взять первые две цифры ИНН и по ним определить округ.
Прежде чем приступать к написанию кода, проанализируем "подводные камни" этой задачи, о которых нам говорит опыт и законодательство РФ:
Несмотря на методологические ограничения, если задача стоит жестко, мы должны реализовать ее максимально технически грамотно. Разберем реализацию по шагам.
Первая ошибка, которую часто допускают начинающие разработчики — попытка поместить логику заполнения в событие ПриСозданииНаСервере.
Почему это не сработает корректно?
Решение: Нам необходимо использовать событие элемента формы ПриИзменении (OnChange), привязанное к полю ввода ИНН. Только так мы сможем оперативно реагировать на действия пользователя.
Давайте посмотрим на фрагмент кода, который содержит типичные ошибки при работе с управляемыми формами, и разберем их.
Некорректный подход:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// ... получение данных ...
ЭтаФорма.Элементы.ФедеральныеОкруга = Строка.Наименование; // Ошибка!
КонецПроцедуры
В чем здесь проблемы?
Элементы служат только для отображения. Хранение данных происходит в реквизитах (обычно в реквизите Объект). Пытаться присвоить значение элементу интерфейса (полю ввода) бессмысленно, нужно присваивать значение реквизиту объекта. Правильно: Объект.ФедеральныйОкруг = ....ЭтаФорма часто избыточно, а в некоторых версиях платформы или режимах запуска может вести себя непредсказуемо.&НаСервере нерационально. Эффективнее использовать безконтекстный вызов &НаСервереБезКонтекста.Часто разработчики выгружают весь справочник в таблицу значений и перебирают его в цикле, чтобы найти нужную запись. Это крайне неэффективно, особенно если справочник станет большим.
Неэффективный код (перебор в цикле):
Таблица = Запрос.Выполнить().Выгрузить();
Для каждого Строка Из Таблица Цикл
Если Строка.КодОкруга = Лев(ИНН, 2) Тогда
// Найден
КонецЕсли;
КонецЦикла;
Решение: Всю работу по поиску должна выполнять система управления базами данных (СУБД). Мы должны написать запрос с отбором (параметром) и получить ровно одну ссылку.
Соберем правильное решение. Предположим, у нас есть:
СоответствиеРегионовОкругам, где Ресурс — Округ, а Измерение — КодРегиона.В модуле формы расширения создаем обработчик изменения поля ИНН.
&НаКлиенте
Процедура Расш1_ИННПриИзмененииПосле(Элемент)
// Сразу проверяем заполненность, чтобы не дергать сервер зря
Если ПустаяСтрока(Объект.ИНН) Тогда
Объект.ФедеральныйОкруг = ПредопределенноеЗначение("Справочник.ФедеральныеОкруга.ПустаяСсылка");
Возврат;
КонецЕсли;
// Вычисляем код региона (первые 2 цифры)
КодРегиона = Лев(Объект.ИНН, 2);
// Ищем округ на сервере
НайденныйОкруг = НайтиФедеральныйОкругПоКодуРегиона(КодРегиона);
// Заполняем реквизит ОБЪЕКТА (данные), а не элемент формы
Если ЗначениеЗаполнено(НайденныйОкруг) Тогда
Объект.ФедеральныйОкруг = НайденныйОкруг;
КонецЕсли;
КонецПроцедуры
Используем директиву &НаСервереБезКонтекста, так как нам не нужны данные всей формы, только входной параметр.
&НаСервереБезКонтекста
Функция НайтиФедеральныйОкругПоКодуРегиона(Знач КодРегиона)
// Создаем запрос. Предположим, что у нас есть Регистр Сведений,
// связывающий коды регионов и округа.
// Если структура другая (например, код региона в самом справочнике округов),
// текст запроса нужно скорректировать.
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ ПЕРВЫЕ 1
| Соответствие.ФедеральныйОкруг КАК Округ
|ИЗ
| РегистрСведений.СоответствиеРегионовОкругам КАК Соответствие
|ГДЕ
| Соответствие.КодРегиона = &КодРегиона";
Запрос.УстановитьПараметр("КодРегиона", КодРегиона);
Результат = Запрос.Выполнить();
Если Не Результат.Пустой() Тогда
Выборка = Результат.Выбрать();
Выборка.Следующий();
Возврат Выборка.Округ;
КонецЕсли;
Возврат Неопределено;
КонецФункции
Рассмотрим несколько моментов, которые сделают ваш код профессиональным:
ФедеральныйОкруг в справочнике Партнеры имеет тип СправочникСсылка.ФедеральныеОкруга (или как назван ваш справочник в расширении). Ошибка несоответствия типов — одна из самых частых.Лев(ИНН, 2). Это работает корректно для 10-значных и 12-значных ИНН. Однако стоит помнить про иностранные компании (код 9909...), где логика может отличаться.Используя этот подход, мы получаем быстрое, оптимизированное решение, которое корректно работает с данными формы и не нагружает сервер лишними циклами.