При разработке и поддержке конфигураций на платформе 1С:Предприятие 7.7 перед программистом часто возникает задача вынесения тяжелой бизнес-логики или печатных форм во внешние файлы. Это позволяет обновлять отчеты, алгоритмы и печатные формы «на лету», без необходимости монопольного захвата базы данных для изменения конфигурации. Особенно актуально это становится, когда в одной внешней обработке (файл с расширением .ert) содержится множество макетов печатных форм и процедур их заполнения, которые требуется вызывать по нажатию кнопки из стандартного документа или справочника.
В этой статье мы подробно разберем, как связать основную конфигурацию с внешней обработкой, как организовать передачу параметров и получение результатов обратно, а также как правильно работать со встроенными и внешними макетами таблиц (файлами .mxl), сохраняя их оригинальное форматирование.
В отличие от более современной платформы 1С v8, где мы можем легко использовать метод ВнешниеОбработки.Создать() и напрямую обращаться к экспортным методам объекта, в версии 7.7 такой встроенной возможности «из коробки» нет. Функция ОткрытьФорму() предназначена в первую очередь для визуального открытия диалогового окна обработки. Однако, используя определенные архитектурные приемы, мы можем заставить внешнюю обработку выполнять нужные нам алгоритмы в фоновом (скрытом) режиме и закрываться самостоятельно.
Рассмотрим по шагам классический и наиболее надежный способ реализации этой задачи через связку передачи параметров и прерывания открытия формы.
Шаг 1. Настройка вызова в основной конфигурации
Для передачи управления внешней обработке мы будем использовать встроенный объект СписокЗначений. В него мы поместим имя вызываемого действия (какую именно печатную форму из десяти нужно сформировать) и контекст вызывающей формы (например, сам документ, для которого строится печатная форма).
Проанализируем пример кода кнопки на форме документа конфигурации:
Процедура КликНаКнопкеПечати()
// Создаем список значений для передачи параметров
ПараметрыВызова = СоздатьОбъект("СписокЗначений");
ПараметрыВызова.Установить("Действие", "ПечатьНакладной");
ПараметрыВызова.Установить("КонтекстДокумента", Контекст); // передаем контекст текущего документа
// Формируем путь к файлу внешней обработки.
// Использование функции КаталогИБ() гарантирует корректность путей на любом компьютере сети.
ПутьКФайлу = КаталогИБ() + "ExtForms\MyPrintTemplates.ert";
// Проверяем физическое наличие файла обработки
Если ФС.СуществуетФайл(ПутьКФайлу) = 1 Тогда
// Открываем обработку, передавая список параметров во вторую переменную
ОткрытьФорму("Отчет", ПараметрыВызова, ПутьКФайлу);
Иначе
Предупреждение("Не найден файл внешней обработки по пути: " + ПутьКФайлу);
КонецЕсли;
КонецПроцедуры
Шаг 2. Перехват управления во внешней обработке
Теперь перейдем во внешнюю обработку MyPrintTemplates.ert. Вся магия скрытого выполнения происходит в предопределенной процедуре ПриОткрытии() модуля формы внешней обработки. Мы должны прочитать переданный параметр, запустить нужную процедуру печати и сразу же отменить открытие формы на экране с помощью функции СтатусВозврата(0).
Рассмотрим структуру модуля формы внешней обработки:
Процедура ПриОткрытии()
// Получаем переданный параметр из свойства Форма.Параметр
Парам = Форма.Параметр;
// Убедимся, что параметры переданы именно в виде СпискаЗначений
Если ТипЗначенияСтр(Парам) = "СписокЗначений" Тогда
Действие = Парам.Получить("Действие");
КонтекстДок = Парам.Получить("КонтекстДокумента");
// Определяем, какую процедуру запустить в зависимости от переданного действия
Если Действие = "ПечатьНакладной" Тогда
СформироватьПечатьНакладной(КонтекстДок);
ИначеЕсли Действие = "ПечатьАкта" Тогда
СформироватьПечатьАкта(КонтекстДок);
// Здесь могут быть описаны остальные 8 печатных форм
КонецЕсли;
// Критически важный момент: закрываем форму до ее отрисовки на экране
СтатусВозврата(0);
Возврат;
КонецЕсли;
КонецПроцедуры
Благодаря вызову СтатусВозврата(0) форма внешней обработки даже не «мигнет» на экране у пользователя. Алгоритм отработает полностью в фоновом режиме, сформирует печатную форму (таблицу) и выведет ее на экран.
Бывают ситуации, когда внешняя обработка должна не просто напечатать документ, а произвести сложные расчеты и вернуть результат обратно в вызывающую форму конфигурации. Платформа 1С 7.7 позволяет легко сделать это с помощью модального открытия.
Разберем, как передать и вернуть измененный параметр:
Код в основной конфигурации:
Процедура ВыполнитьРасчетВоВнешнейОбработке()
// Создаем переменную, которая будет передана по ссылке
КонтейнерПараметров = СоздатьОбъект("СписокЗначений");
КонтейнерПараметров.Установить("Режим", "РасчетСкидки");
КонтейнерПараметров.Установить("СуммаДокумента", Итог("Сумма"));
КонтейнерПараметров.Установить("Результат", 0); // Сюда обработка запишет ответ
ПутьКФайлу = КаталогИБ() + "ExtForms\Calculator.ert";
// Открываем обработку модально. Код остановится на этой строке до закрытия обработки.
ОткрытьФормуМодально("Отчет", КонтейнерПараметров, ПутьКФайлу);
// После закрытия обработки считываем возвращенное значение
ИтоговаяСкидка = КонтейнерПараметров.Получить("Результат");
Сообщить("Внешняя обработка вернула значение скидки: " + ИтоговаяСкидка);
КонецПроцедуры
Код во внешней обработке (в модуле формы):
Процедура ПриОткрытии()
Парам = Форма.Параметр;
Если ТипЗначенияСтр(Парам) = "СписокЗначений" Тогда
Режим = Парам.Получить("Режим");
Сумма = Парам.Получить("СуммаДокумента");
Если Режим = "РасчетСкидки" Тогда
// Производим вычисления
Скидка = Сумма * 0.10; // Например, 10%
// Записываем результат обратно в переданный параметр
Парам.Установить("Результат", Скидка);
КонецЕсли;
// Закрываем модальное окно
СтатусВозврата(0);
Возврат;
КонецЕсли;
КонецПроцедуры
Многие разработчики интересуются возможностью переноса макетов печатных форм из внешней обработки в общие макеты конфигурации с сохранением оригинальной ширины, высоты строк и столбцов. Выясним, как лучше поступить в этой ситуации.
Вариант А. Копирование макетов в конфигурацию
Перенести макет из обработки в общие макеты конфигурации действительно можно. Для этого выполните следующие действия:
Ctrl + C).Ctrl + V).Важный нюанс: при таком копировании полностью сохраняется все форматирование, включая ширину колонок, высоту строк, шрифты, объединения ячеек и параметры границ. Однако у этого подхода есть существенный недостаток. Каждое минимальное изменение в макете (например, изменение одной буквы в шапке или добавление логотипа) потребует изменения конфигурации и ее сохранения, что крайне неудобно в работающей многопользовательской базе.
Вариант Б. Использование внешних макетов таблиц (Рекомендуемый подход)
Гораздо более гибким решением является хранение макетов печатных форм во внешних файлах с расширением .mxl в каталоге базы данных (например, в папке ExtForms). В этом случае программный код внешней обработки подгружает нужный макет динамически.
Рассмотрим, как это реализовать на практике с помощью встроенного метода ИсходнаяТаблица():
Процедура СформироватьПечатьНакладной(КонтекстДок)
Таб = СоздатьОбъект("Таблица");
// Формируем динамический относительный путь к файлу макета .mxl
ПутьКМакету = КаталогИБ() + "ExtForms\PrnForms\Накладная.mxl";
Если ФС.СуществуетФайл(ПутьКМакету) = 1 Тогда
// Загружаем макет из внешнего файла таблицы
Таб.ИсходнаяТаблица(ПутьКМакету);
Иначе
Предупреждение("Файл макета не найден по пути: " + ПутьКМакету);
Возврат;
EndЕсли;
// Заполняем секции макета данными из контекста документа
Таб.ВывестиСекцию("Шапка");
// Пример обхода строк документа через переданный контекст
КонтекстДок.ВыбратьСтроки();
Пока КонтекстДок.ПолучитьСтроку() = 1 Цикл
// Внутри макета используются переменные, которые берутся из контекста документа
Таб.ВывестиСекцию("Строка");
КонецЦикла;
Таб.ВывестиСекцию("Подвал");
// Выводим готовую печатную форму на экран
Таб.Показать("Печатная форма накладной");
КонецПроцедуры
Преимущества хранения макетов во внешних файлах .mxl:
.mxl прямо в режиме «1С:Предприятие» через меню Файл -> Открыть, изменить шрифт, добавить логотип или скорректировать ширину колонок и сохранить файл. Для этого не нужны права программиста и доступ к конфигуратору.Если вы хотите писать максимально чистый и объектно-ориентированный код на платформе 1С 7.7, стандартных возможностей с использованием ОткрытьФорму() может не хватать. В профессиональной среде для решения этих задач часто применяется популярная внешняя компонента 1С++ (1cpp.dll).
Компонента 1С++ позволяет компилировать файлы внешних обработок .ert как полноценные классы. Вы можете создавать их объекты напрямую в коде конфигурации:
// Пример вызова метода внешней обработки через 1С++
Попытка
МояОбработка = СоздатьОбъект("Класс.МойПринтер");
МояОбработка.ВыполнитьПечать(Контекст, "ПечатьФормы3");
Исключение
Сообщить("Ошибка вызова внешнего класса: " + ОписаниеОшибки());
КонецПопытки
Такой подход полностью избавляет от необходимости использовать костыли с предопределенной процедурой ПриОткрытии() и позволяет вызывать любые экспортные функции и процедуры внешней обработки напрямую.
Подводя итог, отметим, что для большинства стандартных задач связка ОткрытьФорму() с передачей параметров через СписокЗначений и использование внешних файлов макетов .mxl является наиболее простым, надежным и легко поддерживаемым решением в экосистеме 1С 7.7.