Как программно вызвать внешнюю обработку и использовать её макеты в 1С 7.7?

Программист 1С v7.7 IT и автоматизация бизнеса
← На главную

При разработке и поддержке конфигураций на платформе 1С:Предприятие 7.7 перед программистом часто возникает задача вынесения тяжелой бизнес-логики или печатных форм во внешние файлы. Это позволяет обновлять отчеты, алгоритмы и печатные формы «на лету», без необходимости монопольного захвата базы данных для изменения конфигурации. Особенно актуально это становится, когда в одной внешней обработке (файл с расширением .ert) содержится множество макетов печатных форм и процедур их заполнения, которые требуется вызывать по нажатию кнопки из стандартного документа или справочника.

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

Проблема: как вызвать процедуру из внешнего файла .ert?

В отличие от более современной платформы 1С v8, где мы можем легко использовать метод ВнешниеОбработки.Создать() и напрямую обращаться к экспортным методам объекта, в версии 7.7 такой встроенной возможности «из коробки» нет. Функция ОткрытьФорму() предназначена в первую очередь для визуального открытия диалогового окна обработки. Однако, используя определенные архитектурные приемы, мы можем заставить внешнюю обработку выполнять нужные нам алгоритмы в фоновом (скрытом) режиме и закрываться самостоятельно.

Способ 1. Программный вызов обработки без показа формы («тихий» режим)

Рассмотрим по шагам классический и наиболее надежный способ реализации этой задачи через связку передачи параметров и прерывания открытия формы.

Шаг 1. Настройка вызова в основной конфигурации

Для передачи управления внешней обработке мы будем использовать встроенный объект СписокЗначений. В него мы поместим имя вызываемого действия (какую именно печатную форму из десяти нужно сформировать) и контекст вызывающей формы (например, сам документ, для которого строится печатная форма).

Проанализируем пример кода кнопки на форме документа конфигурации:


Процедура КликНаКнопкеПечати()
    // Создаем список значений для передачи параметров
    ПараметрыВызова = СоздатьОбъект("СписокЗначений");
    ПараметрыВызова.Установить("Действие", "ПечатьНакладной");
    ПараметрыВызова.Установить("КонтекстДокумента", Контекст); // передаем контекст текущего документа
    
    // Формируем путь к файлу внешней обработки. 
    // Использование функции КаталогИБ() гарантирует корректность путей на любом компьютере сети.
    ПутьКФайлу = КаталогИБ() + "ExtForms\MyPrintTemplates.ert";
    
    // Проверяем физическое наличие файла обработки
    Если ФС.СуществуетФайл(ПутьКФайлу) = 1 Тогда
        // Открываем обработку, передавая список параметров во вторую переменную
        ОткрытьФорму("Отчет", ПараметрыВызова, ПутьКФайлу);
    Иначе
        Предупреждение("Не найден файл внешней обработки по пути: " + ПутьКФайлу);
    КонецЕсли;
КонецПроцедуры

Шаг 2. Перехват управления во внешней обработке

Теперь перейдем во внешнюю обработку MyPrintTemplates.ert. Вся магия скрытого выполнения происходит в предопределенной процедуре ПриОткрытии() модуля формы внешней обработки. Мы должны прочитать переданный параметр, запустить нужную процедуру печати и сразу же отменить открытие формы на экране с помощью функции СтатусВозврата(0).

Рассмотрим структуру модуля формы внешней обработки:


Процедура ПриОткрытии()
    // Получаем переданный параметр из свойства Форма.Параметр
    Парам = Форма.Параметр;
    
    // Убедимся, что параметры переданы именно в виде СпискаЗначений
    Если ТипЗначенияСтр(Парам) = "СписокЗначений" Тогда
        Действие = Парам.Получить("Действие");
        КонтекстДок = Парам.Получить("КонтекстДокумента");
        
        // Определяем, какую процедуру запустить в зависимости от переданного действия
        Если Действие = "ПечатьНакладной" Тогда
            СформироватьПечатьНакладной(КонтекстДок);
        ИначеЕсли Действие = "ПечатьАкта" Тогда
            СформироватьПечатьАкта(КонтекстДок);
        // Здесь могут быть описаны остальные 8 печатных форм
        КонецЕсли;
        
        // Критически важный момент: закрываем форму до ее отрисовки на экране
        СтатусВозврата(0); 
        Возврат;
    КонецЕсли;
КонецПроцедуры

Благодаря вызову СтатусВозврата(0) форма внешней обработки даже не «мигнет» на экране у пользователя. Алгоритм отработает полностью в фоновом режиме, сформирует печатную форму (таблицу) и выведет ее на экран.

Способ 2. Возврат значений из внешней обработки в конфигурацию

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

Разберем, как передать и вернуть измененный параметр:

Код в основной конфигурации:


Процедура ВыполнитьРасчетВоВнешнейОбработке()
    // Создаем переменную, которая будет передана по ссылке
    КонтейнерПараметров = СоздатьОбъект("СписокЗначений");
    КонтейнерПараметров.Установить("Режим", "РасчетСкидки");
    КонтейнерПараметров.Установить("СуммаДокумента", Итог("Сумма"));
    КонтейнерПараметров.Установить("Результат", 0); // Сюда обработка запишет ответ
    
    ПутьКФайлу = КаталогИБ() + "ExtForms\Calculator.ert";
    
    // Открываем обработку модально. Код остановится на этой строке до закрытия обработки.
    ОткрытьФормуМодально("Отчет", КонтейнерПараметров, ПутьКФайлу);
    
    // После закрытия обработки считываем возвращенное значение
    ИтоговаяСкидка = КонтейнерПараметров.Получить("Результат");
    Сообщить("Внешняя обработка вернула значение скидки: " + ИтоговаяСкидка);
КонецПроцедуры

Код во внешней обработке (в модуле формы):


Процедура ПриОткрытии()
    Парам = Форма.Параметр;
    Если ТипЗначенияСтр(Парам) = "СписокЗначений" Тогда
        Режим = Парам.Получить("Режим");
        Сумма = Парам.Получить("СуммаДокумента");
        
        Если Режим = "РасчетСкидки" Тогда
            // Производим вычисления
            Скидка = Сумма * 0.10; // Например, 10%
            
            // Записываем результат обратно в переданный параметр
            Парам.Установить("Результат", Скидка);
        КонецЕсли;
        
        // Закрываем модальное окно
        СтатусВозврата(0);
        Возврат;
    КонецЕсли;
КонецПроцедуры

Работа с макетами печатных форм (mxl) и сохранение форматирования

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

Вариант А. Копирование макетов в конфигурацию

Перенести макет из обработки в общие макеты конфигурации действительно можно. Для этого выполните следующие действия:

  1. Откройте внешнюю обработку в Конфигураторе и перейдите к таблице (макету).
  2. Выделите всю таблицу целиком. Для этого нажмите на серый прямоугольник на стыке шкал строк и столбцов (в левом верхнем углу таблицы, аналогично выделению всего листа в Microsoft Excel).
  3. Скопируйте содержимое в буфер обмена (комбинация клавиш Ctrl + C).
  4. Откройте дерево метаданных конфигурации, перейдите в ветку «Общие таблицы» и создайте новую таблицу.
  5. Вставьте скопированный макет (комбинация клавиш Ctrl + V).

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

Вариант Б. Использование внешних макетов таблиц (Рекомендуемый подход)

Гораздо более гибким решением является хранение макетов печатных форм во внешних файлах с расширением .mxl в каталоге базы данных (например, в папке ExtForms). В этом случае программный код внешней обработки подгружает нужный макет динамически.

Рассмотрим, как это реализовать на практике с помощью встроенного метода ИсходнаяТаблица():


Процедура СформироватьПечатьНакладной(КонтекстДок)
    Таб = СоздатьОбъект("Таблица");
    
    // Формируем динамический относительный путь к файлу макета .mxl
    ПутьКМакету = КаталогИБ() + "ExtForms\PrnForms\Накладная.mxl";
    
    Если ФС.СуществуетФайл(ПутьКМакету) = 1 Тогда
        // Загружаем макет из внешнего файла таблицы
        Таб.ИсходнаяТаблица(ПутьКМакету);
    Иначе
        Предупреждение("Файл макета не найден по пути: " + ПутьКМакету);
        Возврат;
    EndЕсли;
    
    // Заполняем секции макета данными из контекста документа
    Таб.ВывестиСекцию("Шапка");
    
    // Пример обхода строк документа через переданный контекст
    КонтекстДок.ВыбратьСтроки();
    Пока КонтекстДок.ПолучитьСтроку() = 1 Цикл
        // Внутри макета используются переменные, которые берутся из контекста документа
        Таб.ВывестиСекцию("Строка");
    КонецЦикла;
    
    Таб.ВывестиСекцию("Подвал");
    
    // Выводим готовую печатную форму на экран
    Таб.Показать("Печатная форма накладной");
КонецПроцедуры

Преимущества хранения макетов во внешних файлах .mxl:

Альтернативный вариант для продвинутых разработчиков: использование внешних компонент

Если вы хотите писать максимально чистый и объектно-ориентированный код на платформе 1С 7.7, стандартных возможностей с использованием ОткрытьФорму() может не хватать. В профессиональной среде для решения этих задач часто применяется популярная внешняя компонента 1С++ (1cpp.dll).

Компонента 1С++ позволяет компилировать файлы внешних обработок .ert как полноценные классы. Вы можете создавать их объекты напрямую в коде конфигурации:


// Пример вызова метода внешней обработки через 1С++
Попытка
    МояОбработка = СоздатьОбъект("Класс.МойПринтер");
    МояОбработка.ВыполнитьПечать(Контекст, "ПечатьФормы3");
Исключение
    Сообщить("Ошибка вызова внешнего класса: " + ОписаниеОшибки());
КонецПопытки

Такой подход полностью избавляет от необходимости использовать костыли с предопределенной процедурой ПриОткрытии() и позволяет вызывать любые экспортные функции и процедуры внешней обработки напрямую.

Подводя итог, отметим, что для большинства стандартных задач связка ОткрытьФорму() с передачей параметров через СписокЗначений и использование внешних файлов макетов .mxl является наиболее простым, надежным и легко поддерживаемым решением в экосистеме 1С 7.7.

← На главную