Почему автоматически заполненный код основного средства не выводится в печатную форму и отчеты?

Программист Бухгалтерский учет IT и автоматизация бизнеса
← На главную

В практике разработки на платформе «1С:Предприятие 8.3» часто возникает ситуация: программист добавляет в документ поле, которое должно отображать код или инвентарный номер основного средства. На форме документа всё выглядит идеально — при выборе объекта ОС его код появляется в нужной колонке. Однако при попытке сформировать печатную форму, построить отчет или проверить движения по регистрам накопления выясняется, что это поле остается пустым.

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

Разберем причину проблемы: визуальное отображение против физического хранения

Проанализируем ситуацию, описанную в теме. Разработчик использовал механизм платформы под названием «Путь к данным» (PathToData). В свойствах элемента формы табличной части было указано значение вида Объект.Расш1ТабЧасть.НаименованиеОС.Код.

Что происходит в этот момент внутри системы? Платформа видит, что поле НаименованиеОС является ссылкой на справочник ОсновныеСредства. Через «точку» она обращается к реквизиту этого справочника Код и динамически выводит его на экран пользователя.

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

Шаг 1. Создание физического реквизита в метаданных

Чтобы данные попадали в печатную форму и регистры, мы должны «приземлить» их в базу данных. Рассмотрим алгоритм действий:

  1. Перейдем в дерево метаданных (Конфигуратор).
  2. Найдем наш документ и его табличную часть.
  3. Добавим новый реквизит табличной части (например, ИнвОС) с типом Строка (или тем типом, который соответствует коду в справочнике ОС).
  4. На форме документа заменим «путь к данным» для элемента формы. Теперь он должен указывать не на НаименованиеОС.Код, а на наш новый реквизит Объект.Расш1ТабЧасть.ИнвОС.

После этого данные смогут храниться в документе, но их нужно туда программно записать.

Шаг 2. Правильное получение кода из справочника

Посмотрим на типичную ошибку при попытке автоматизировать заполнение. Использование метода НайтиПоНаименованию является крайне нежелательным:


Функция ПолучитьИнвОС(НаименованиеОС)
    Возврат Справочники.ОсновныеСредства.НайтиПоНаименованию(НаименованиеОС).Код;
КонецФункции

Выясним причину, почему это плохо:

Правильный подход — получать данные напрямую из ссылки, которая уже выбрана в поле НаименованиеОС. Рассмотрим, как это сделать наиболее эффективно с использованием механизмов БСП (Библиотеки стандартных подсистем).

Шаг 3. Реализация заполнения через обработчик «ПриИзменении»

Чтобы код заполнялся сразу при выборе основного средства, нам нужно прописать логику в модуле формы документа. Рассмотрим пример кода для события ПриИзменении в табличной части:


&НаКлиенте
Процедура Расш1ТабЧастьНаименованиеОСПриИзменении(Элемент)
    
    СтрокаТЧ = Элементы.Расш1ТабЧасть.ТекущиеДанные;
    
    Если СтрокаТЧ <> Неопределено Тогда
        // Вызываем серверную функцию для получения кода
        СтрокаТЧ.ИнвОС = ПолучитьКодОСНаСервере(СтрокаТЧ.НаименованиеОС);
    КонецЕсли;
    
КонецПроцедуры

&НаСервереБезКонтекста
Функция ПолучитьКодОСНаСервере(СсылкаНаОС)
    
    Если СсылкаНаОС.Пустая() Тогда
        Возврат "";
    КонецЕсли;
    
    // Используем типовой метод БСП для быстрого получения реквизита
    Возврат ОбщегоНазначения.ЗначениеРеквизитаОбъекта(СсылкаНаОС, "Код");
    
КонецФункции

Проанализируем этот код. Использование функции ОбщегоНазначения.ЗначениеРеквизитаОбъекта() — это оптимальный способ. В отличие от получения всего объекта через Ссылка.ПолучитьОбъект(), этот метод выполняет легкий SQL-запрос только к одной конкретной колонке таблицы справочника, что значительно ускоряет работу системы.

Шаг 4. Обновление запроса печатной формы

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


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |   Расш1АрендованныеОС.Ссылка КАК Ссылка,
    |   Расш1АрендованныеОС.Расш1ТабЧасть.(
    |       НомерСтроки КАК НомерСтроки,
    |       НаименованиеОС КАК НаименованиеОС,
    |       ИнвОС КАК ИнвОС, // Теперь это поле реально существует в ТЧ
    |       СтоимостьОСпо01Счету КАК Стоимость
    |   ) КАК ТабЧасть
    |ИЗ
    |   Документ.Расш1АрендованныеОС КАК Расш1АрендованныеОС
    |ГДЕ
    |   Расш1АрендованныеОС.Ссылка В (&МассивСсылок)";

Запрос.УстановитьПараметр("МассивСсылок", Ссылка);

Обратите внимание: теперь поле ИнвОС — это не виртуальная ссылка через точку, а реальное поле таблицы Расш1ТабЧасть. Оно будет мгновенно извлечено запросом и выведено в макет печатной формы или в отчет.

Важность фиксации данных для истории учета

Помимо технического удобства вывода в отчеты, есть еще одна критически важная причина, по которой данные (такие как Код, Артикул или Цена) нужно копировать в документ из справочника, а не просто отображать «через точку».

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

Резюме

Подведем итоги нашего разбора. Если данные «видны на форме, но не видны в отчете», выполните следующие действия:

  1. Проверьте, является ли поле реквизитом документа или это просто «путь к данным» через ссылку.
  2. Если это не реквизит — создайте его в табличной части.
  3. Обеспечьте заполнение реквизита при изменении связанного поля (используйте ОбщегоНазначения.ЗначениеРеквизитаОбъекта).
  4. Убедитесь, что в запросах для отчетов и печатных форм вы обращаетесь именно к новому реквизиту табличной части.

Соблюдение этих правил сделает вашу конфигурацию надежной, а отчеты — точными.

← На главную