Почему возникает ошибка при записи ХранилищаЗначения в табличную часть справочника на управляемой форме?

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

При разработке функционала сохранения файлов в табличные части справочников разработчики часто сталкиваются с ситуацией, когда реквизит с типом ХранилищеЗначения физически присутствует в конфигураторе, но попытка записать в него данные на сервере формы вызывает ошибку «Поле объекта не обнаружено». Кроме того, при дальнейшей работе могут возникать ошибки «Объект недоступен для изменения» при попытке добавить строки в группы справочника.

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

Причина 1. Особенности типа «ХранилищеЗначения» в структуре данных формы

Проанализируем исходную ошибку. На управляемой форме объект Объект (основной реквизит формы) имеет тип ДанныеФормыСтруктура, а его табличные части — ДанныеФормыКоллекция. Платформа 1С оптимизирует объем данных, передаваемых между сервером и клиентом, поэтому бинарные данные и реквизиты с типом ХранилищеЗначения принципиально не включаются в данные формы. В коллекции строк формы реквизита с типом хранилища просто не существует, что и приводит к ошибке «Поле объекта не обнаружено».

Чтобы получить доступ к реальным реквизитам объекта базы данных, необходимо преобразовать данные формы в прикладной объект СправочникОбъект с помощью метода РеквизитФормыВЗначение.

Рассмотрим, как правильно организовать передачу файла и его сохранение в объект:

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

Посмотрим на пример правильной серверной процедуры:


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

Причина 2. Ошибка «Объект недоступен для изменения» у групп справочника

Если справочник является иерархическим с видом иерархии «Иерархия групп и элементов», платформа по умолчанию накладывает ограничения на группы. При попытке программного добавления строк в табличную часть группы (папки) возникает ошибка времени выполнения «Объект недоступен для изменения».

Разберем два способа решения этой проблемы:

  1. Настройка использования табличной части:

    В дереве метаданных конфигуратора откроем свойства нужной табличной части (например, ФайлыДок или Оргполитики) и найдем свойство «Использование». По умолчанию там установлено значение Для элемента. Переключим его в значение «Для элемента и группы» (или «Для группы», если ТЧ требуется только папкам). После этого табличная часть станет доступна для изменения у элементов с признаком ЭтоГруппа = Истина.

  2. Изменение вида иерархии справочника:

    Если в прикладной логике нет необходимости строго разделять папки и элементы (например, любой узел иерархии может содержать одинаковый набор данных и иметь подчиненные элементы), в свойствах справочника на вкладке «Иерархия» можно переключить вид на «Иерархия элементов». В этом случае все элементы иерархии имеют одинаковую структуру и доступность реквизитов.

Рекомендации по архитектуре хранения файлов

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

В реальных проектах рекомендуется использовать следующие альтернативы:

  1. Подчиненный справочник (паттерн присоединенных файлов): вынесение файлов в отдельный справочник, где бинарные данные запрашиваются только при прямом открытии или выгрузке конкретного файла.
  2. Регистр сведений: хранение файлов в ресурсе непериодического регистра сведений с типом ХранилищеЗначения, где в измерениях фиксируются ссылка на владельца и идентификатор файла.
  3. Тома на диске: сохранение файлов в сетевые каталоги с записью в базу только относительных путей, что предотвращает разрастание базы данных.
← На главную