Как программно заполнить реквизиты контрагентов по ИНН без открытия форм в управляемом приложении 1С?

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

При переходе с обычных форм на управляемые многие разработчики сталкиваются с концептуальной трудностью. Пытаясь автоматизировать рутинные действия, они часто пытаются повторить интерактивный сценарий работы пользователя: программно открыть форму элемента, найти на ней нужную кнопку, сымитировать её нажатие и затем закрыть форму. Такой подход в корне неверен для платформы 1С:Предприятие 8.3.

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

Анализ проблемы: почему код с эмуляцией нажатия кнопки не работает?

Рассмотрим код, который часто пытаются использовать начинающие разработчики:


&НаКлиенте
Процедура ЗаполнитьПоИНН(Команда)
    Для Каждого стр Из СП_Контрагенты Цикл
        ПараметрыФормы = Новый Структура("Ключ", стр.Значение);
        СпрФорма = ПолучитьФорму("Справочник.Контрагенты.Форма.ФормаЭлемента", ПараметрыФормы);
        Кнопка = СпрФорма.Элементы.КнопкаЗаполнитьРеквизитыПоИНН;
        СпрФорма.Открыть();
        СпрФорма.ЗаполнитьРеквизитыПоИНН(Неопределено); // Попытка вызова процедуры кнопки
        СпрФорма.Закрыть();
    КонецЦикла;
КонецПроцедуры

Данный код неизбежно завершится ошибкой. Проанализируем ключевые причины, почему этот метод считается антипаттерном:

  1. Асинхронность клиент-серверного взаимодействия. Метод Открыть() управляемой формы выполняется асинхронно. Форма не инициализируется мгновенно в той же строке кода. Платформа отправляет команду клиенту на отрисовку интерфейса, но выполнение кода продолжается. Следующие строки (вызов процедуры заполнения и закрытие формы) выполняются до того, как форма реально будет создана и подготовлена к работе на клиенте.
  2. Область видимости процедур модуля формы. Процедура-обработчик нажатия кнопки (например, ЗаполнитьРеквизитыПоИНН) обычно компилируется без ключевого слова Экспорт. Она инкапсулирована внутри модуля конкретной формы и недоступна для вызова из внешних обработок или других форм.
  3. Колоссальная нагрузка на клиентское приложение. Даже если бы платформа позволяла такой вызов, открытие и мгновенное закрытие сотен форм в цикле привело бы к зависанию интерфейса, перегрузке оперативной памяти и постоянным задержкам из-за сетевого обмена (клиент-серверного пинга).

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

Как устроено заполнение по ИНН в типовых конфигурациях

Разработчики Библиотеки стандартных подсистем (БСП) давно вынесли логику отправки запросов к веб-сервисам ФНС и разбора ответов в специализированные общие модули. Форма элемента справочника Контрагенты лишь обращается к этим модулям. Нам не нужно дублировать сложный код разбора XML или JSON.

В зависимости от версии БСП и возраста вашей конфигурации, функции получения данных по ИНН могут располагаться в разных общих модулях:

  1. Современные конфигурации (БП 3.0, ERP 2.5, КА 2.5, УТ 11.5 и актуальные версии УНФ): Вся логика работы с веб-сервисами перенесена в библиотеку интернет-поддержки пользователей. Используется общий модуль РаботаСКонтрагентами. Основные методы: РаботаСКонтрагентами.РеквизитыЮридическогоЛицаПоИНН() и РаботаСКонтрагентами.РеквизитыПредпринимателяПоИНН().
  2. Конфигурации средних релизов: Использовался общий модуль ДанныеЕдиныхГосРеестров с аналогичными методами.
  3. Устаревшие редакции (например, УПП 1.3 или БП 2.0): Запросы отправлялись через общий модуль СервисДанныхЕдиныхГосРеестров.

Все эти методы принимают на вход строку с ИНН, отправляют запрос к серверам «1С:Контрагент» и возвращают готовую структуру со всеми заполненными реквизитами (краткое и полное наименование, КПП, ОГРН, юридический адрес, телефон, ФИО руководителя и т.д.). Наша задача — просто перенести эти значения в объект контрагента на сервере.

Правильный шаблон решения: массовое заполнение на сервере

Для реализации задачи массового заполнения реквизитов по списку ИНН мы должны перенести всю обработку на сервер. Никакие формы открывать не нужно. Мы будем получать объекты контрагентов, вызывать методы БСП и записывать изменения напрямую в базу данных.

Рассмотрим подробный программный код серверной процедуры:


&НаСервере
Процедура ЗаполнитьКонтрагентовПоИНННаСервере()
    
    Для Каждого СтрокаСписка Из СП_Контрагенты Цикл
        
        СсылкаКонтрагента = СтрокаСписка.Значение;
        
        // Получаем ИНН и очищаем его от случайных пробелов
        ИНН = СокрЛП(СсылкаКонтрагента.ИНН);
        Если ПустаяСтрока(ИНН) Тогда
            Продолжить;
        КонецЕсли;
        
        // Получаем объект для редактирования реквизитов
        КонтрагентОбъект = СсылкаКонтрагента.ПолучитьОбъект();
        
        // Определяем юридический статус (Юр.лицо или ИП/Физ.лицо)
        ЭтоЮридическоеЛицо = (КонтрагентОбъект.ЮрФизЛицо = Перечисления.ЮрФизЛицо.ЮрЛицо); 
        
        Данные = Неопределено;
        Попытка
            // Используем актуальные методы БСП для получения структуры данных
            Если ЭтоЮридическоеЛицо Тогда
                Данные = РаботаСКонтрагентами.РеквизитыЮридическогоЛицаПоИНН(ИНН);
            Иначе
                Данные = РаботаСКонтрагентами.РеквизитыПредпринимателяПоИНН(ИНН);
            КонецЕсли;
        Исключение
            // Обрабатываем возможные сетевые сбои или отсутствие лицензии
            ЗаписьЖурналаРегистрации(
                "ЗаполнениеПоИНН", 
                УровеньЖурналаРегистрации.Ошибка,
                ,, 
                ПодробноеПредставлениеОшибки(ИнформацияОбОшибке())
            );
            Продолжить;
        КонецПопытки;
        
        // Если сервис успешно вернул структуру с данными, переносим их в объект
        Если Данные <> Неопределено Тогда
            
            // Заполняем наименования
            КонтрагентОбъект.Наименование       = Данные.НаименованиеСокращенное;
            КонтрагентОбъект.НаименованиеПолное = Данные.НаименованиеПолное;
            
            // Заполняем специфические реквизиты в зависимости от типа лица
            Если ЭтоЮридическоеЛицо Тогда
                КонтрагентОбъект.КПП  = Данные.КПП;
                КонтрагентОбъект.ОГРН = Данные.ОГРН;
            Иначе
                КонтрагентОбъект.ОГРНИП = Данные.ОГРН;
            КонецЕсли;
            
            // Записываем измененный объект контрагента в базу данных
            Попытка
                КонтрагентОбъект.Записать();
            Исключение
                ВызватьИсключение "Не удалось записать контрагента с ИНН " + ИНН;
            КонецПопытки;
            
        КонецЕсли;
        
    КонецЦикла;
    
КонецПроцедуры

Тонкости и нюансы программного заполнения, о которых важно помнить

При использовании программного серверного заполнения существует несколько важных технологических аспектов, которые необходимо учесть заранее:

  1. Сетевой доступ сервера 1С. При интерактивном заполнении с компьютера пользователя запрос к сервису заполнения уходит с локального ПК. При серверном коде запрос выполняется непосредственно с физического сервера, на котором развернут кластер 1С:Предприятия (если база клиент-серверная). Убедитесь, что служба сервера (обычно это пользователь usr1cv8) имеет доступ к интернету и не блокируется брандмауэром или прокси-сервером организации.
  2. Лимиты сервиса «1С:Контрагент». Программный опрос сервиса тратит суточные лимиты вашей подписки 1С:ИТС. При слишком частом обращении к сервису в цикле учетная запись может быть временно заблокирована за превышение лимитов интенсивности запросов. Перед массовым заполнением тысяч контрагентов обязательно согласуйте этот вопрос с администратором ИТС.
  3. Альтернативные варианты без ИТС. Если у вашей организации нет действующей подписки на сервис «1С:Контрагент», стандартные функции БСП вернут ошибку авторизации. В таких ситуациях разработчики используют сторонние API (например, dadata.ru, egrul.itsoft.ru и другие). Для этого пишется собственный код отправки HTTP-запроса через объект HTTPСоединение с последующим разбором JSON/XML ответа.
  4. Заполнение контактной информации. Юридический и фактический адреса контрагентов в современных базах хранятся не в простых реквизитах справочника, а в табличной части КонтактнаяИнформация (или в одноименном регистре сведений). Чтобы корректно записать адрес в формате ФИАС/КЛАДР, используйте стандартные программные интерфейсы БСП. Например, методы общего модуля УправлениеКонтактнойИнформацией, которые преобразуют текстовый адрес в структурированный вид.

Теоретический вопрос: как все-таки программно вызвать метод формы?

Для расширения кругозора разберем вопрос автора темы: «Как на будущее программно обработать кнопку с формы?». Если перед вами действительно стоит задача, требующая обращения к логике открытой формы, это можно сделать двумя корректными способами:

Способ 1: Использование экспортного метода формы.

В модуле формы, логику которой вы хотите вызвать, процедура должна быть объявлена как клиентская и иметь ключевое слово Экспорт:


// В модуле управляемой формы элемента справочника Контрагенты
&НаКлиенте
Процедура ЗаполнитьРеквизитыПоИННЭкспорт() Экспорт
    // Здесь размещается логика заполнения
КонецПроцедуры

В таком случае из внешней обработки вы сможете обратиться к форме следующим образом:


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

Способ 2: Передача параметров при открытии формы.

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


// В коде внешней обработки
ПараметрыФормы = Новый Структура;
ПараметрыФормы.Вставить("Ключ", СсылкаНаКонтрагента);
ПараметрыФормы.Вставить("АвтозаполнениеПоИННПриОткрытии", Истина;

ОткрытьФорму("Справочник.Контрагенты.Форма.ФормаЭлемента", ПараметрыФормы);

В самой форме контрагента в обработчике ПриОткрытии (или ПриСозданииНаСервере) мы анализируем переданные параметры:


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

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

← На главную