При сопровождении устаревших конфигураций (например, Бухгалтерия предприятия 2.0, Управление торговлей 10.3 или специализированных отраслевых решений типа Ломбард) программисты часто сталкиваются с необходимостью внедрения механизмов из современных версий БСП (Библиотеки стандартных подсистем). Одной из таких задач является формирование печатных форм в формате Microsoft Word или Excel. Однако попытка вызвать стандартные функции УправлениеПечатью.ИнициализироватьМакетОфисногоДокумента или УправлениеПечатью.ИнициализироватьПечатнуюФорму в обычном приложении приводит к ошибке: «Процедура или функция с указанным именем не определена».
Давайте разберем, почему это происходит, и проанализируем основные способы решения этой проблемы, чтобы успешно реализовать печать документов в режиме обычного приложения.
Проанализируем архитектуру современных версий БСП. Основная причина недоступности методов заключается в настройках Общих модулей. Большинство модулей подсистемы «Печать» имеют установленные флаги «Сервер», «Дистанционное управление» и «Клиент (управляемое приложение)». Однако флаг «Клиент (обычное приложение)» в них зачастую снят. Это осознанное решение разработчиков фирмы «1С», так как библиотека ориентирована на современный интерфейс «Такси» и управляемые формы.
Когда мы пытаемся вызвать метод из кода обработки или документа, запущенного в обычном клиенте, платформа просто «не видит» этот модуль, так как он не скомпилирован для данного типа клиента. Чтобы решить эту задачу, нам потребуется либо адаптировать существующий код, либо использовать альтернативные механизмы работы с COM-объектами.
Рассмотрим наиболее корректный с точки зрения архитектуры способ — создание собственного «моста» между обычным приложением и функционалом БСП. Это позволит нам использовать уже готовые наработки библиотеки, минимизируя дублирование кода.
Выполним следующие шаги:
УправлениеПечатьюОбычноеПриложение.Пример реализации такой функции-обертки может выглядеть следующим образом:
Функция ИнициализироватьМакетОфисногоДокументаОбычное(МакетДокумента, ТипМакета = "") Экспорт
// Вызываем оригинальную функцию БСП через серверный контекст
Возврат УправлениеПечатью.ИнициализироватьМакетОфисногоДокумента(МакетДокумента, ТипМакета);
КонецФункции
Функция ИнициализироватьПечатнуюФормуОбычное(ТипМакета, НастройкиПечати, Макет) Экспорт
Возврат УправлениеПечатью.ИнициализироватьПечатнуюФорму(ТипМакета, НастройкиПечати, Макет);
КонецФункции
Важный момент: Помните, что передаваемые объекты (например, структура Макет) должны быть сериализуемыми, чтобы они могли корректно передаваться между клиентом и сервером. Офисные документы в БСП обычно передаются как ДвоичныеДанные, что вполне подходит для этого метода.
Если конфигурация сильно кастомизирована или использование БСП по каким-то причинам невозможно (например, версия БСП слишком старая), нам придется вспомнить классический метод работы через Automation Server. Функции БСП, по сути, являются сложной «оберткой» над COM-объектами Word.Application и Excel.Application.
Разберем, как самостоятельно инициализировать печатную форму, не прибегая к подсистемам БСП. Рассмотрим пример для Microsoft Word:
Попытка
WordApp = Новый COMОбъект("Word.Application");
Исключение
Сообщить("Не удалось запустить Microsoft Word. Убедитесь, что программа установлена.");
Возврат;
КонецПопытки;
// Создаем документ на основе макета
// Макет в данном случае — это путь к временному файлу, сохраненному из макета конфигурации
WordDoc = WordApp.Documents.Add(ПутьКФайлуШаблона);
WordApp.Visible = Истина; // Делаем окно видимым для пользователя
// Пример замены параметра в тексте (аналог механизмов БСП)
Замена = WordDoc.Content.Find;
Замена.Execute("{НомерДокумента}", Ложь, Истина, Ложь, , , Истина, , , Строка(Номер), 2);
Проанализируем этот подход: он дает полный контроль над процессом, но требует ручного управления временными файлами и очистки памяти. В обычном приложении это стандартная практика, которая использовалась десятилетиями до появления БСП.
Иногда самым быстрым решением «малой кровью» является перенос кода функций ИнициализироватьМакет... непосредственно в модуль вашей обработки или в новый общий модуль. Однако при этом способе мы столкнемся с «эффектом домино».
Рассмотрим подробнее, с чем придется работать:
ИнициализироватьМакетОфисногоДокумента внутри себя обращается к модулю УправлениеПечатьюСлужебный.Чтобы успешно скопировать этот функционал, нам нужно проанализировать зависимости. Если вы работаете в конфигурации типа ВДГБ: Ломбард на базе БП 2.0, проще всего найти в этой же конфигурации любую существующую печатную форму Word и скопировать логику оттуда. Скорее всего, там уже реализованы вспомогательные функции для поиска и замены параметров в офисных документах, которые совместимы с обычным приложением.
Проанализируем технический нюанс, который часто упускают при замене функций БСП. Если ваш сервер 1С работает в 64-битном режиме, а Microsoft Office установлен 32-битный, попытка создать COMОбъект на стороне сервера закончится ошибкой.
Функции БСП решают эту проблему, выполняя часть кода на клиенте. При написании собственной замены для обычного приложения всегда выполняйте инициализацию COM-объектов на стороне клиента (в модуле формы или в модуле объекта, вызванном с клиента). Это гарантирует, что 1С обратится к локально установленному Word или Excel пользователя.
При использовании любого из вышеперечисленных способов важно следить за чистотой системы. Функции УправлениеПечатью автоматически управляют временными файлами. Если мы пишем замену самостоятельно, нам необходимо:
Макет = ПолучитьМакет("ИмяМакета");Путь = КаталогВременныхФайлов() + "template.doc";УдалитьФайлы(Путь);Резюмируем: Для замены функций в обычном приложении наиболее эффективным решением будет создание своего общего модуля с включенным флагом «Клиент (обычное приложение)», который будет выступать посредником. Если же вы хотите полной независимости от БСП — используйте прямое управление через COM-объекты, как это делалось в классических версиях 1С:Предприятие 8.1 и 8.2.