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