Как прикрепить файлы к справочнику из расширения в 1С и обойти ошибку проверки типов?

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

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

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

Выясняем причину: почему БСП выдает ошибку?

Рассмотрим детально, как работает механизм прикрепления файлов в БСП. Для хранения файлов создается подчиненный справочник (например, КандидатыПрисоединенныеФайлы для справочника Кандидаты). Чтобы БСП могла единообразно работать со всеми файлами в базе данных, в системе существуют специальные метаданные — Определяемые типы:

  1. ОпределяемыйТип.ПрисоединенныйФайл — содержит список ссылок на все справочники присоединенных файлов в системе.
  2. ОпределяемыйТип.ВладелецПрисоединенныхФайлов — содержит список ссылок на объекты-владельцы (документы, справочники), к которым эти файлы прикрепляются.

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


ОбщегоНазначенияКлиентСервер.ПроверитьПараметр(
    "РаботаСФайлами.ДвоичныеДанныеФайла", 
    "ПрисоединенныйФайл", 
    ПрисоединенныйФайл, 
    Метаданные.ОпределяемыеТипы.ПрисоединенныйФайл.Тип
);

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

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

Решение 1. Использование современных возможностей платформы (начиная с версии 8.3.20)

Если режим совместимости вашей конфигурации установлен в значение 8.3.20.1549 или выше, вам крупно повезло. Фирма «1С» добавила полноценную поддержку определяемых типов в расширениях. Программисту больше не нужно писать сложный обходной код.

Выполним следующие шаги для настройки:

  1. Добавим в наше расширение определяемый тип ПрисоединенныйФайл из основной конфигурации.
  2. Добавим в расширение определяемый тип ВладелецПрисоединенныхФайлов.
  3. В свойствах заимствованных определяемых типов в расширении расширим состав типов:
    • Для ПрисоединенныйФайл добавим ссылку на наш новый справочник присоединенных файлов (например, СправочникСсылка.КандидатыПрисоединенныеФайлы).
    • Для ВладелецПрисоединенныхФайлов добавим ссылку на сам объект-владелец (например, СправочникСсылка.Кандидаты).

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

Решение 2. Программный обход проверки типов через &Вместо (для старых платформ)

Если конфигурация работает в режиме совместимости ниже 8.3.20 (например, 8.3.17 или 8.3.14), расширить определяемые типы напрямую невозможно. В таком случае нам придется программно перехватить вызовы БСП, где происходит проверка типов параметров, используя механизм аннотаций &Вместо.

Проанализируем по шагам, как реализовать этот обход:

Шаг 1. Создание вспомогательной функции для динамического расширения типов

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


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

Шаг 2. Перехват функции проверки двоичных данных

Теперь перехватим функцию ДвоичныеДанныеФайла в общем модуле РаботаСФайлами с помощью аннотации &Вместо. Нам нужно подменить передаваемое описание типов в момент проверки:


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

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

Решение 3. Архитектурный обход через стандартный справочник «ПапкиФайлов»

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

Разберем этот метод подробнее:

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

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

Дополнительные подводные камни при интеграции БСП в расширения

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

1. Ошибки при записи в регистр «ФайлыВРабочемКаталоге»

При открытии файлов на редактирование БСП фиксирует это в регистре сведений ФайлыВРабочемКаталоге. Измерение Файл в данном регистре имеет тип ОпределяемыйТип.ПрисоединенныйФайл. На старых платформах запись в этот регистр для файлов из расширения может завершиться ошибкой базы данных. В этом случае придется также перехватывать процедуры записи в данный регистр через &Вместо или использовать Решение 3 с папками файлов.

2. Отсутствие пиктограмм (иконок) файлов в списках

Иногда файлы, созданные через расширение, отображаются в списках со стандартной «пустой» иконкой вместо значков Word, Excel или PDF. Это происходит из-за того, что при создании записи не заполнился индекс картинки. Чтобы решить эту проблему, в процедуре создания или записи присоединенного файла принудительно вызывайте заполнение индекса:


ПрисоединенныйФайл.ИндексКартинки = РаботаСФайламиСлужебныйКлиентСервер.ПолучитьИндексПиктограммыФайла(ПрисоединенныйФайл.Расширение);

3. Хранение файлов в томах на диске

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

Вывод: выбор решения зависит от версии платформы, на которой работает ваша база 1С. Если есть возможность обновить платформу и режим совместимости до версии 8.3.20 — используйте встроенный механизм определяемых типов в расширениях. Если база работает на старой платформе и изменения основной конфигурации запрещены, оптимальным выбором будет перехват функций через &Вместо или использование архитектурного маневра со справочником-посредником.

← На главную