Как исправить ошибку "Значение не является значением объектного типа (ВысотаТаблицы)" при выводе внешней печатной формы в 1С:ЗУП?

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

При разработке и внедрении внешних печатных форм в конфигурациях 1С, таких как 1С:Зарплата и Управление Персоналом (ЗУП), мы можем столкнуться с различными сложностями. Одной из распространенных проблем является ошибка "Значение не является значением объектного типа (ВысотаТаблицы)". Давайте рассмотрим эту проблему подробно, выясним ее причины и найдем эффективные способы решения.

Анализируем контекст возникновения ошибки

Представим ситуацию, когда мы создали внешнюю печатную форму для документа "Прием на работу" в ЗУП. При попытке ее распечатать, после ввода необходимых данных в форме настроек, система выдает ошибку:

Значение не является значением объектного типа (ВысотаТаблицы) {ОбщаяФорма.ПечатьДокументов.Форма(675)}:ЕстьТабличныеДокументы = ЕстьТабличныеДокументы Или ПечатнаяФорма.ТабличныйДокумент.ВысотаТаблицы <> 0; {ОбщаяФорма.ПечатьДокументов.Форма(67)}:ИсключитьОфисныеДокументыИзКомплектов(КоллекцияПечатныхФорм); {ОбщийМодуль.УправлениеПечатьюКлиент.Модуль(198)}:ОткрытьФорму("ОбщаяФорма.ПечатьДокументов", ПараметрыОткрытия, ВладелецФормы, КлючУникальности); {ВнешняяОбработка.ДоговорПоставкоДем.Форма.ФормаНастроек.Форма(34)}:УправлениеПечатьюКлиент.ПечатьДокументов(МассивПечатныхФорм, ОбъектыПечати, ЭтаФорма); [ОшибкаВоВремяВыполненияВстроенногоЯзыка, ОшибкаИспользованияВстроенногоЯзыка]

Этот стек вызова ошибки очень показателен. Он указывает, что проблема возникает в общей форме


ОбщаяФорма.ПечатьДокументов
при попытке обратиться к свойству

ВысотаТаблицы
у объекта

ПечатнаяФорма.ТабличныйДокумент
. Судя по ошибке "Значение не является значением объектного типа", это означает, что

ПечатнаяФорма.ТабличныйДокумент
в этот момент является

Неопределено
или каким-то другим типом, который не имеет свойства

ВысотаТаблицы
.

Давайте посмотрим на предоставленный код, чтобы выявить причину.

Код формы настроек внешней печатной формы

Начнем с кода формы настроек, который инициирует процесс печати:


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

&НаСервере
Функция ПечатьНаСервере(ОбъектыПечати, ПараметрыПечати)
    ОбработкаОбъект = РеквизитФормыВЗначение("Объект");
    МассивОбъектов = Новый Массив;
    МассивОбъектов.Добавить(ОбъектыПечати[0].Значение);
    КоллекцияПечатныхФорм = УправлениеПечатью.ПодготовитьКоллекциюПечатныхФорм("ТрудовойДоговорДалини");
    ПараметрыВывода = УправлениеПечатью.ПодготовитьСтруктуруПараметровВывода;
    ОбработкаОбъект.Печать(МассивОбъектов, КоллекцияПечатныхФорм, ОбъектыПечати, ПараметрыВывода, ПараметрыПечати);
    МассивПечатныхФорм = ОбщегоНазначения.ТаблицаЗначенийВМассив(КоллекцияПечатныхФорм);
    Возврат МассивПечатныхФорм;
КонецФункции

В этом коде мы видим стандартный вызов серверной функции


ПечатьНаСервере
, которая, в свою очередь, вызывает метод

Печать
модуля внешней обработки. Затем результат передается на клиент в

УправлениеПечатьюКлиент.ПечатьДокументов
. Здесь все выглядит достаточно стандартно.

Код модуля внешней печатной формы

Теперь обратимся к модулю самой внешней печатной формы. Нас интересует процедура


Печать
и функция

СформироватьПечатнуюФорму
:


Процедура Печать(МассивОбъектов, КоллекцияПечатныхФорм, ОбъектыПечати, ПараметрыВывода, ПараметрыПечати) Экспорт
    //УправлениеПечатью.ВывестиТабличныйДокументВКоллекцию(КоллекцияПечатныхФорм, "ПФ_Трудовой_Договор_Внешний", "Трудовой договор с водителями", СформироватьПечатнуюФормуДоговора(МассивОбъектов, ОбъектыПечати, ПараметрыВывода));
    Если УправлениеПечатью.НужноПечататьМакет(КоллекцияПечатныхФорм, "ТрудовойДоговорДалини") Тогда
        ПечатьТрудовогоДоговора (МассивОбъектов, КоллекцияПечатныхФорм, ОбъектыПечати, ПараметрыВывода)
    КонецЕсли;
КонецПроцедуры

Процедура ПечатьТрудовогоДоговора (МассивОбъектов, КоллекцияПечатныхФорм, ОбъектыПечати, ПараметрыВывода)
    УправлениеПечатью.ВывестиТабличныйДокументВКоллекцию( 
        КоллекцияПечатныхФорм, 
        "ТрудовойДоговорДалини", 
        НСтр("ru='Трудовой договор с водителями'"), 
        СформироватьПечатнуюФорму(МассивОбъектов, ОбъектыПечати, ПараметрыВывода));
КонецПроцедуры

Функция СформироватьПечатнуюФорму(СсылкаНаОбъект, ОбъектыПечати, ПараметрыПечати)
КонецФункции

Выявляем ключевую проблему: пустая функция формирования печатной формы

При внимательном рассмотрении представленного кода мы замечаем очень важную деталь. Функция


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

Функция СформироватьПечатнуюФорму(СсылкаНаОбъект, ОбъектыПечати, ПараметрыПечати) КонецФункции

В 1С, если функция не содержит оператор


Возврат
, она неявно возвращает значение

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

  1. Из процедуры
    
    ПечатьТрудовогоДоговора
    
    вызывается функция
    
    СформироватьПечатнуюФорму
    
    .
  2. Поскольку функция
    
    СформироватьПечатнуюФорму
    
    пуста, она возвращает
    
    Неопределено
    
    .
  3. Это
    
    Неопределено
    
    передается в процедуру
    
    УправлениеПечатью.ВывестиТабличныйДокументВКоллекцию
    
    в качестве табличного документа.
  4. Процедура
    
    ВывестиТабличныйДокументВКоллекцию
    
    добавляет в коллекцию печатных форм строку, в которой поле для табличного документа содержит
    
    Неопределено
    
    .
  5. Когда общая форма
    
    ПечатьДокументов
    
    пытается обработать эту коллекцию, она обнаруживает, что вместо табличного документа там
    
    Неопределено
    
    . При попытке обратиться к свойству
    
    ВысотаТаблицы
    
    у
    
    Неопределено
    
    возникает ошибка "Значение не является значением объектного типа".

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

Как правильно исправить проблему: шаги к решению

Для исправления этой ошибки нам необходимо гарантировать, что функция


СформироватьПечатнуюФорму
всегда возвращает объект типа

ТабличныйДокумент
.

Шаг 1: Инициализация ТабличногоДокумента

В самом начале функции


СформироватьПечатнуюФорму
мы должны создать новый экземпляр объекта

ТабличныйДокумент
. Это обеспечит, что даже если в процессе формирования возникнут другие ошибки, мы всегда вернем хотя бы пустой табличный документ, который имеет свойство

ВысотаТаблицы
.


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

Шаг 2: Реализация логики формирования печатной формы

Внутри функции


СформироватьПечатнуюФорму
нам необходимо реализовать всю логику по получению данных, загрузке макета, заполнению областей и выводу их в

ТабДок
. Если у вас уже был готовый код, убедитесь, что он раскомментирован и корректно работает. Мы должны использовать методы объекта

ТабличныйДокумент
, такие как

Вывести()
,

ОтображатьСетку()
,

ОтображатьЗаголовки()
и т.д.

Приведем пример структуры функции формирования:


Функция СформироватьПечатнуюФорму(СсылкаНаОбъект, ОбъектыПечати, ПараметрыПечати) Экспорт
    // 1. Создаем табличный документ
    ТабДок = Новый ТабличныйДокумент;
    ТабДок.Очистить(); // Очищаем на всякий случай
    ТабДок.ИмяПараметровПечати = "ПараметрыПечати_ТрудовойДоговорДалини";

    // 2. Получаем объект документа "Прием на работу"
    ДокументОбъект = СсылкаНаОбъект[0].ПолучитьОбъект(); // СсылкаНаОбъект - это массив ссылок

    // 3. Получаем макет печатной формы
    Макет = ПолучитьМакет("ТрудовойДоговорДалини"); // Предполагается, что макет добавлен в обработку
    
    // 4. Определяем области макета
    ОбластьЗаголовок = Макет.ПолучитьОбласть("Заголовок");
    ОбластьДанные = Макет.ПолучитьОбласть("Данные");
    ОбластьПодвал = Макет.ПолучитьОбласть("Подвал");

    // 5. Заполняем параметры макета данными из документа и ПараметровПечати
    // Например, для заголовка:
    ОбластьЗаголовок.Параметры.Заполнить(ДокументОбъект);
    ОбластьЗаголовок.Параметры.ДатаПечати = ТекущаяДата();
    
    // Заполнение параметров из СтруктураДанных, переданной из формы настроек
    ОбластьДанные.Параметры.СерияПаспорта      = ПараметрыПечати.Серия;
    ОбластьДанные.Параметры.НомерПаспорта      = ПараметрыПечати.Номер;
    ОбластьДанные.Параметры.КемВыдан           = ПараметрыПечати.КемВыдан;
    ОбластьДанные.Параметры.ДатаВыдачи         = ПараметрыПечати.ДатаВыдачи;
    ОбластьДанные.Параметры.КодПодразделения   = ПараметрыПечати.КодПодразделения;
    ОбластьДанные.Параметры.ДатаНачалаРаботы   = ПараметрыПечати.ДатаНачалаРаботы;
    ОбластьДанные.Параметры.РазмерТарифнойСтавки = ПараметрыПечати.РазмерТарифнойСтавкий; // Опечатка в названии, исправим на РазмерТарифнойСтавки
    ОбластьДанные.Параметры.ЗаработнаяПлата    = ПараметрыПечати.ЗаработнаяПлата;
    
    // Также заполняем данные из самого документа
    ОбластьДанные.Параметры.НомерДокумента = ДокументОбъект.Номер;
    ОбластьДанные.Параметры.ДатаДокумента = ДокументОбъект.Дата;
    ОбластьДанные.Параметры.Сотрудник = ДокументОбъект.Сотрудник;
    // ... и так далее для всех необходимых полей ...

    // 6. Выводим области в табличный документ
    ТабДок.Вывести(ОбластьЗаголовок);
    ТабДок.Вывести(ОбластьДанные);
    ТабДок.Вывести(ОбластьПодвал);

    // 7. Настраиваем параметры вывода (если необходимо)
    ТабДок.ПараметрыСтраницы.ОриентацияСтраницы = ОриентацияСтраницы.Портрет;
    ТабДок.ПараметрыСтраницы.МасштабПечати = 100;

    // 8. Возвращаем заполненный табличный документ
    Возврат ТабДок;
КонецФункции

Обратите внимание на то, что


СсылкаНаОбъект
в параметрах функции

СформироватьПечатнуюФорму
является массивом ссылок. Если вы ожидаете только один объект, как в данном случае с документом "Прием на работу", то обращайтесь к первому элементу массива:

СсылкаНаОбъект[0].ПолучитьОбъект()
.

Дополнительные причины и как их предотвратить

Даже если мы раскомментируем код или напишем его заново, могут возникнуть другие нюансы, приводящие к аналогичным ошибкам:

  1. Не все ветви кода возвращают табличный документ. Часто разработчики используют условные операторы (
    
    Если ... Тогда ... Иначе ... КонецЕсли;
    
    ) внутри функции формирования. Если оператор
    
    Возврат ТабДок;
    
    находится только в одной из ветвей, а другие ветви не достигают его выполнения, функция все равно может вернуть
    
    Неопределено
    
    .

    Решение: Всегда инициализируйте

    
    ТабличныйДокумент
    
    в начале функции и помещайте
    
    Возврат ТабДок;
    
    в самый конец функции, чтобы гарантировать его выполнение.

  2. Возвращается неверный тип данных. По ошибке или из-за неправильной логики функция может вернуть не
    
    ТабличныйДокумент
    
    , а, например,
    
    Структуру
    
    ,
    
    Массив
    
    или результат запроса. Механизм печати не сможет обработать такой объект, что приведет к той же ошибке "Значение не является значением объектного типа".

    Решение: Всегда проверяйте тип возвращаемого значения в отладчике. Убедитесь, что это именно

    
    ТабличныйДокумент
    
    .

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

    Решение: Используйте отладчик для пошагового выполнения кода внутри функции

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

Эффективная отладка для выявления подобных проблем

Для точного определения места и причины ошибки мы рекомендуем использовать отладчик 1С:

  1. Установите точки останова.
    • Первую точку останова поставьте в процедуре
      
      ПечатьПродолжить
      
      на клиенте, на строке
      
      МассивПечатныхФорм = ПечатьНаСервере(ОбъектыПечати, СтруктураДанных);
      
      .
    • Вторую точку останова поставьте в серверной функции
      
      ПечатьНаСервере
      
      , на строке
      
      ОбработкаОбъект.Печать(МассивОбъектов, КоллекцияПечатныхФорм, ОбъектыПечати, ПараметрыВывода, ПараметрыПечати);
      
      .
    • Третью, и самую важную, точку останова установите в модуле внешней обработки, в процедуре
      
      Печать
      
      (или
      
      ПечатьТрудовогоДоговора
      
      ), перед вызовом
      
      СформироватьПечатнуюФорму
      
      и после него.
    • Четвертую точку останова поставьте внутри самой функции
      
      СформироватьПечатнуюФорму
      
      : в самом начале и непосредственно на строке
      
      Возврат ТабДок;
      
      .
  2. Запустите отладку. Воспроизведите действия, которые приводят к ошибке (печать формы).
  3. Пошаговое выполнение. Используйте клавиши
    
    F10
    
    (шаг через) и
    
    F11
    
    (шаг внутрь) для пошагового прохождения кода.
    • Дойдя до вызова
      
      ПечатьНаСервере
      
      , войдите в нее (
      
      F11
      
      ).
    • Далее, дойдя до вызова
      
      ОбработкаОбъект.Печать
      
      , снова войдите в нее (
      
      F11
      
      ), чтобы попасть в модуль вашей внешней обработки.
    • Пройдите по процедуре
      
      Печать
      
      и
      
      ПечатьТрудовогоДоговора
      
      , пока не дойдете до вызова
      
      СформироватьПечатнуюФорму
      
      . Войдите в эту функцию (
      
      F11
      
      ).
    • Внутри
      
      СформироватьПечатнуюФорму
      
      выполняйте код пошагово. Проверяйте значения всех переменных, особенно
      
      ТабДок
      
      .
  4. Проверка возвращаемого значения.

    После выхода из функции

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

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

    Если

    
    РезультатФормирования
    
    окажется
    
    Неопределено
    
    , то мы точно знаем, что проблема в функции
    
    СформироватьПечатнуюФорму
    
    .

Заключение

Ошибка "Значение не является значением объектного типа (ВысотаТаблицы)" при выводе внешней печатной формы в 1С чаще всего указывает на то, что функция, ответственная за формирование табличного документа, либо не возвращает никакого значения (


Неопределено
), либо возвращает значение некорректного типа. Внимательный анализ кода, особенно функции

СформироватьПечатнуюФорму
, и использование отладчика помогут нам быстро выявить и устранить эту проблему.

Всегда помните о необходимости явного создания объекта


ТабличныйДокумент
и его гарантированного возврата из функции формирования печатной формы. Это ключевой принцип при работе с внешними печатными формами в системе 1С.

← На главную