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