Как правильно прочитать дополнительные реквизиты документа во внешней печатной форме 1С:ЗУП 3.1?

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

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

Суть проблемы: почему ДополнительныеРеквизиты пусты?

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

Давайте посмотрим на пример кода, который использовался:


ТЗ_ДопРеквизиты = Док.ДополнительныеРеквизиты.Выгрузить; 
ДопРеквизит = ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.НайтиПоНаименованию("Причина отсутствия"); 
ПричинаОтсутствия = ТЗ_ДопРеквизиты.Найти(ДопРеквизит, "Свойство"); 

В этом примере переменная ТЗ_ДопРеквизиты оказалась пустой, хотя реквизит на форме был заполнен. Это распространенная ловушка при работе с дополнительными реквизитами.

Почему прямой доступ к ДополнительныеРеквизиты не работает?

Для понимания причин, по которым прямой доступ к табличной части ДополнительныеРеквизиты может возвращать пустые значения, необходимо разобраться, как устроено хранение этих данных в 1С:

  1. Хранение в отдельной табличной части: В отличие от обычных реквизитов объекта, которые являются полями основной таблицы базы данных, дополнительные реквизиты хранятся в специальной табличной части объекта. Эта табличная часть обычно называется ДополнительныеРеквизиты или ДополнительныеСведения. Она содержит колонки, такие как Свойство (ссылка на элемент плана видов характеристик ДополнительныеРеквизитыИСведения) и Значение (собственно, значение реквизита).
  2. Заполнение после записи в базу данных: Критически важный момент заключается в том, что эта табличная часть заполняется и становится доступной только после того, как объект (документ, справочник и т.д.) был записан в базу данных. Если вы пытаетесь получить значение дополнительного реквизита у нового, еще не записанного документа (например, в событии "ПриОткрытии" формы или после интерактивного заполнения до сохранения), табличная часть ДополнительныеРеквизиты будет пустой. Внешняя печатная форма всегда работает с уже записанными в базу данными, но это не исключает других ошибок.
  3. Незаполненные реквизиты не сохраняются: Система 1С оптимизирует хранение данных. Если дополнительный реквизит не заполнен (его значение пусто), то соответствующая строка не будет записана в табличную часть ДополнительныеРеквизиты. Это означает, что если вы ищете реквизит, который фактически не имеет значения, он не будет найден.
  4. Особенности типа "Булево": Для дополнительных реквизитов с типом "Булево" значение "Ложь" часто интерпретируется как незаполненное и также не сохраняется в табличной части ДополнительныеРеквизиты. Если вам нужно сохранять "Ложь" как значимое состояние, рекомендуется использовать другие типы данных, например, "Число" (0 для "Ложь", 1 для "Истина") или элемент перечисления.

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

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

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

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

Функция УправлениеСвойствами.ЗначениеСвойства()

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


// Возвращает значение свойства.
//
// Параметры:
//  ВладелецСвойств - Ссылка.
//  СсылкаНаСвойство - ПланВидовХарактеристикСсылка.ДополнительныеРеквизитыИСведения.
//  Или
//  НаименованиеСвойства - Строка - Наименование свойства.
//
// Возвращаемое значение:
//  Произвольный.
//
// Функция ЗначениеСвойства(ВладелецСвойств, СсылкаНаСвойство = Неопределено, НаименованиеСвойства = "") Экспорт

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

Пример корректного кода для внешней печатной формы:

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


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

// 1. Сначала найдем ссылку на сам дополнительный реквизит по его наименованию.
// Это более надежный способ, чем передача наименования строкой, так как исключает опечатки.
ДопРеквизитСсылка = ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.НайтиПоНаименованию("Причина отсутствия");

// 2. Проверим, что реквизит найден, чтобы избежать ошибок.
Если НЕ ДопРеквизитСсылка.Пустая() Тогда
    // 3. Используем функцию УправлениеСвойствами.ЗначениеСвойства для получения значения.
    ЗначениеПричиныОтсутствия = УправлениеСвойствами.ЗначениеСвойства(СсылкаНаДокумент, ДопРеквизитСсылка);

    // Теперь ЗначениеПричиныОтсутствия содержит нужное значение.
    // Мы можем его использовать, например, для вывода в печатную форму.
    Если ЗначениеПричиныОтсутствия <> Неопределено И ЗначениеПричиныОтсутствия <> "" Тогда
        Сообщить("Причина отсутствия: " + Строка(ЗначениеПричиныОтсутствия));
    Иначе
        Сообщить("Дополнительный реквизит 'Причина отсутствия' не заполнен или не найден.");
    КонецЕсли;
Иначе
    Сообщить("Дополнительный реквизит 'Причина отсутствия' не найден в ПланеВидовХарактеристик.");
КонецЕсли;

Этот подход является предпочтительным, поскольку он использует стандартные механизмы БСП, разработанные для корректной работы с дополнительными реквизитами в различных сценариях.

Решение проблемы автора: "Задвоение реквизитов"

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

  1. Повторное создание реквизита: Возможно, реквизит с таким же наименованием уже существовал ранее (например, был создан, удален или деактивирован, а затем создан заново с тем же именем, но уже как новый объект в базе).
  2. Ошибки при переносе данных: При обновлении конфигурации или переносе данных из других баз могли возникнуть дублирующие записи в ПланеВидовХарактеристик ДополнительныеРеквизитыИСведения.
  3. Некорректная настройка: Иногда пользователь мог создать реквизит, который по наименованию совпадает с системным или уже существующим, но неактивным реквизитом.

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

Как проверить и исправить "задвоение реквизитов":

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

  1. Перейдите в список дополнительных реквизитов: Откройте раздел "НСИ и администрирование" (или аналогичный), затем "Настройка и администрирование" → "Общие настройки" → "Дополнительные реквизиты и сведения".
  2. Проверьте План видов характеристик: Также желательно проверить сам ПланВидовХарактеристик.ДополнительныеРеквизитыИСведения. Для этого вам может понадобиться открыть его через "Все функции" (меню "Сервис" → "Параметры" → установить флажок "Отображать команду 'Все функции'"). В списке выберите ПланыВидовХарактеристик и найдите ДополнительныеРеквизитыИСведения.
  3. Найдите дубликаты: Отсортируйте список по наименованию. Внимательно просмотрите, нет ли нескольких элементов с одинаковым наименованием, но, возможно, с разными внутренними идентификаторами или датами создания.
  4. Идентификация активного реквизита: Если вы обнаружили дубликаты, выясните, какой из них является "правильным" или активно используемым. Часто это можно определить по дате создания, наличию ссылок на него в других объектах или путем тестирования.
  5. Удаление или деактивация дубликатов: "Неправильные" или неиспользуемые дубликаты следует пометить на удаление или деактивировать (если такая функция предусмотрена для данного типа объекта). Будьте очень осторожны при удалении, так как это может повлиять на уже введенные данные. Лучше предварительно сделать резервную копию базы.
  6. Пересоздание при необходимости: В некоторых случаях, если задвоение сильно запутано, проще удалить все дубликаты и пересоздать реквизит заново, убедившись, что его наименование уникально и соответствует всем требованиям.

После устранения задвоенных реквизитов, код, использующий УправлениеСвойствами.ЗначениеСвойства(), должен начать корректно получать значения.

Другие возможные причины проблем

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

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

Заключение

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

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

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

← На главную