При разработке расширений для типовых конфигураций 1С (например, Бухгалтерия Предприятия 3.0) мы часто сталкиваемся с задачей добавления функционала присоединенных файлов к объектам, где это штатно не предусмотрено. Например, к Книге учетов доходов и расходов (КУДиР) или специфическим документам. Казалось бы, механизм Библиотеки Стандартных Подсистем (БСП) универсален, однако при его внедрении через расширение можно столкнуться с неочевидной ошибкой.
Рассмотрим ситуацию: мы добавили возможность прикреплять файлы, сам файл успешно сохраняется и отображается в списке — для этой задачи подойдёт отображение значка скрепки в журналах документов 1С. Но при попытке открыть его программа выдает сообщение:
Данные файла недоступны, т.к. возможно файл был очищен как ненужный.
Разберем подробно, почему возникает эта ошибка, как проанализировать стеки вызовов и что именно нужно исправить в коде или настройках расширения — для этого подойдёт инструмент пошаговой отладки и анализа стека вызовов в 1С.
В первую очередь, давайте обратим внимание на текст ошибки. Фраза "файл был очищен как ненужный" — это стандартное сообщение подсистемы "Работа с файлами". Оно появляется, когда в справочнике присоединенных файлов (карточка файла) ссылка существует, но физические данные (Binary Data) получить не удается.
Если мы посмотрим технические подробности (нажав кнопку "Подробно" или анализируя Журнал регистрации), то увидим примерно такой стек вызовов:
{ОбщийМодуль.РаботаСФайламиСлужебный.Модуль(4371)}: ВызватьИсключение СообщениеОбОшибке;
{ОбщийМодуль.РаботаСФайламиВТомахСлужебный.Модуль(54)}: РаботаСФайламиСлужебный.СообщитьОбОшибкеФайлНеНайден(ФайлОбъект, ВызыватьИсключение);
{ОбщийМодуль.РаботаСФайлами.Модуль(75)}: Возврат РаботаСФайламиВТомахСлужебный.ДанныеФайла(ПрисоединенныйФайл, ВызыватьИсключение);
Этот стек говорит нам о том, что система попыталась найти файл, но метод получения данных вернул пустоту или ошибку. Давайте разберем причины, по которым это происходит именно при разработке через расширение.
Как выяснилось в ходе разбора ситуации, самой частой причиной такого поведения является незаполненный реквизит ТипХраненияФайла в справочнике присоединенных файлов.
В БСП существует два режима хранения файлов:
ХранилищеЗначения).За выбор режима отвечает перечисление ТипыХраненияФайлов. В справочниках присоединенных файлов (например, НоменклатураПрисоединенныеФайлы или созданный вами ЗаписьКнигиДоходовИРасходовПрисоединенныеФайлы) обязательно есть реквизит, указывающий, где искать тело файла.
Если этот реквизит пуст (Перечисления.ТипыХраненияФайлов.ПустаяСсылка), подсистема БСП не знает, к какому источнику обращаться за двоичными данными. В результате она считает, что данные отсутствуют, и выдает сообщение об очистке файла.
Чтобы исправить ошибку, нам необходимо убедиться, что при создании записи о файле реквизит ТипХраненияФайла заполняется корректно. Проанализируем, где это может быть упущено.
Если вы создаете файлы программно или вмешиваетесь в процесс записи в своем расширении, убедитесь, что вы явно устанавливаете этот реквизит. Давайте посмотрим на пример правильного заполнения:
НовыйФайл = Справочники.МойОбъектПрисоединенныеФайлы.СоздатьЭлемент();
// ... заполнение владельца и других полей ...
// Обязательно указываем тип хранения!
НовыйФайл.ТипХраненияФайла = Перечисления.ТипыХраненияФайлов.ВИнформационнойБазе;
// Или .ВТомахНаДиске, если используете тома
НовыйФайл.Записать();
Если вы создали новый справочник присоединенных файлов непосредственно в расширении, проверьте палитру свойств реквизита ТипХраненияФайла. Иногда значение заполнения (FillValue) может быть не установлено, и при интерактивном или автоматическом создании оно остается пустым.
Помимо типа хранения, при добавлении механизма присоединенных файлов через расширение, необходимо учитывать еще несколько важных моментов, невыполнение которых может привести к похожим ошибкам или некорректной работе.
БСП должна "знать", что ваш документ или справочник (например, КУДиР) умеет хранить файлы. Для этого необходимо расширить процедуру в общем модуле РаботаСФайламиПереопределяемый. Используйте аннотацию &После:
&НаСервере
&После("ОпределитьОбъектыСПрисоединеннымиФайлами")
Процедура Расш1_ОпределитьОбъектыСПрисоединеннымиФайлами(Объекты)
// Добавляем наш объект, к которому мы прикрутили файлы
Объекты.Вставить(Метаданные.Документы.ЗаписьКнигиДоходовИРасходовИП.ПолноеИмя(),
Метаданные.Справочники.ЗаписьКнигиДоходовИРасходовПрисоединенныеФайлы.ПолноеИмя());
КонецПроцедуры
Создаваемый вами справочник для хранения файлов должен структурно соответствовать стандартам БСП. Самый простой способ не ошибиться — скопировать существующий справочник (например, ПапкиФайлов или _ДемоНоменклатураПрисоединенныеФайлы) и перенастроить тип владельца.
Обратите внимание на реквизит СтатусИзвлеченияТекста. Если он не заполняется, это также может сигнализировать о нарушении логики работы подсистемы, хотя и не всегда приводит к критической ошибке открытия файла.
Стоит упомянуть, почему ошибка говорит про "очистку". В 1С существует регламентное задание, которое удаляет файлы, не привязанные к владельцам (мусор). Если при записи файла связь с владельцем (документом) не была установлена корректно или транзакция записи владельца откатилась, а файл остался — система может пометить его как "ненужный" и удалить тело файла, оставив пустую ссылку. Однако в случае, который мы разбираем (ошибка сразу после добавления), причиной в 99% случаев является именно неопределенный тип хранения.
Если вы добавили присоединенные файлы через расширение и получаете ошибку при открытии:
ТипХраненияФайла у созданного элемента справочника присоединенных файлов (можно использовать консоль запросов или отладчик) — для этого подойдут инструменты для разработки и анализа объектов 1С.Перечисления.ТипыХраненияФайлов.ВИнформационнойБазе.