Как исправить ошибку «Метод недоступен на сервере» при вызове метода Напечатать в 1С?

Программист 1С v8.3 (Управляемые формы) 1С:Управление торговлей IT и автоматизация бизнеса
← На главную

При доработке обработок и форм в конфигурациях 1С (например, «Управление торговлей 11») разработчики часто сталкиваются с ошибкой вызова контекста: «Метод недоступен на сервере» при попытке отправить документ или пакет документов на печать. Проанализируем причину этой проблемы и рассмотрим правильные варианты её решения.

Выясним причину ошибки контекста

Разберем технические особенности работы платформы «1С:Предприятие 8». Все процедуры и методы вывода графической информации, взаимодействия с принтерами или физическими устройствами пользователя имеют контекст выполнения &НаКлиенте. К ним относятся:

  1. Метод ТабличныйДокумент.Напечатать()
  2. Метод ПакетОтображаемыхДокументов.Напечатать()
  3. Метод ТабличныйДокумент.Показать()

Серверная служба 1С работает как фоновый сервис в операционной системе и не имеет визуального интерфейса и доступа к локальным принтерам конкретного рабочего места пользователя. Поэтому при вызове метода Напечатать() в процедуре с директивой компиляции &НаСервере или без явной директивы вызов аварийно завершается.

Попытка вызвать процедуру с директивой &НаКлиенте непосредственно из серверного кода также приведет к ошибке: передать управление с сервера на клиент в рамках одного прямого вызова невозможно. Платформа просто не найдет процедуру в контексте сервера и сообщит, что она не определена.

Ошибочная логика переноса кода из общих модулей

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


// ОШИБКА: Вызов метода печати внутри серверного контекста
Процедура РаспечататьТабличныеДокументы(ТабличныеДокументы, ОбъектыПечати) 
    ПакетОтображаемыхДокументов = УправлениеПечатьюВызовСервера.ПакетДокументов(ТабличныеДокументы, ОбъектыПечати);
    // Исключение: Метод недоступен на сервере
    ПакетОтображаемыхДокументов.Напечатать(РежимИспользованияДиалогаПечати.НеИспользовать);
КонецПроцедуры

Разберем правильное решение с использованием БСП

Для корректного решения этой задачи воспользуемся механизмом печати из Библиотеки Стандартных Подсистем (БСП). Вся работа разделяется на два этапа:

  1. На сервере: Подготавливаются данные для печати (макеты, шаблоны этикеток, временные хранилища).
  2. На клиенте: Из вызывающей клиентской процедуры выполняется команда печати через клиентский общий модуль УправлениеПечатьюКлиент.

Посмотрим на пример правильной организации кода в форме обработки:


&НаКлиенте
Процедура СоздатьКоробку(Команда)
    
    ТекстПредупреждения = "";
    СоздатьКоробкуНаСервере(ТекстПредупреждения);
    
    Если ЗначениеЗаполнено(ТекстПредупреждения) Тогда
        ПоказатьПредупреждение(, ТекстПредупреждения);
        Возврат;
    КонецЕсли;
    
    МасУпакЛ = Новый Массив;
    МасУпакЛ.Добавить(ТекущаяКоробка);
    
    // 1. Получаем подготовленные данные с сервера через серверный модуль
    СтруктураВозврата = УправлениеПечатьюУТВызовСервера.ДанныеДляПечатиЭтикетокУпаковочныеЛисты(МасУпакЛ);
    
    // 2. Вызываем печать на клиенте с помощью клиентского модуля БСП
    УправлениеПечатьюКлиент.ВыполнитьКомандуПечатиНаПринтер(
        "Обработка.ПечатьЭтикетокИЦенников",
        "ЭтикеткаУпаковочныеЛисты",
        МасУпакЛ,
        Новый Структура(
            "АдресВХранилище, ШаблонЭтикетки, КоличествоЭкземпляров",
            СтруктураВозврата.АдресВХранилище, 
            СтруктураВозврата.ШаблонЭтикетки, 
            1
        )
    );
    
КонецПроцедуры

В данном сценарии получение макета и данных выполняется серверным вызовом УправлениеПечатьюУТВызовСервера.ДанныеДляПечатиЭтикетокУпаковочныеЛисты(), а отправка на принтер передается функции УправлениеПечатьюКлиент.ВыполнитьКомандуПечатиНаПринтер(), которая штатно работает в контексте &НаКлиенте.

Альтернативный вариант: Возврат сформированного документа на клиент

Если печатная форма формируется вручную без стандартных команд печати БСП, следует применить следующую схему:

  1. Создаем серверную функцию, которая формирует ТабличныйДокумент (или помещает его во временное хранилище через ПоместитьВоВременноеХранилище()) и возвращает адрес или сам объект на клиент.
  2. В клиентской процедуре получаем объект и вызываем метод печати.

Проанализируем пример кода с возвратом хранилища:


&НаСервере
Функция СформироватьДокументНаСервере(МассивОбъектов)
    ТабДок = Новый ТабличныйДокумент;
    // ... заполнение табличного документа ...
    Возврат ПоместитьВоВременноеХранилище(ТабДок, УникальныйИдентификатор);
КонецФункции

&НаКлиенте
Процедура ПечатьНаКлиенте()
    АдресХранилища = СформироватьДокументНаСервере(МассивОбъектов);
    ТабДок = ПолучитьИзВременногоХранилища(АдресХранилища);
    
    // На клиенте метод Напечатать() работает без ошибок
    ТабДок.Напечатать(РежимИспользованияДиалогаПечати.НеИспользовать);
КонецПроцедуры

Соблюдение правил клиент-серверного взаимодействия позволяет избежать ошибок контекста и обеспечивает стабильную работу печатных форм во всех режимах работы платформы.

← На главную