Как реализовать прикрепление файлов к каждой строке табличной части документа в 1С:ERP?

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

В типовых конфигурациях на базе Библиотеки стандартных подсистем (БСП), таких как 1С:ERP или 1С:Комплексная автоматизация, механизм присоединенных файлов штатно работает в привязке к объекту целиком (документу или справочнику). Однако часто возникает бизнес-задача прикрепить файл (скан сертификата, фото дефекта, спецификацию) к конкретной строке табличной части. Рассмотрим, как реализовать этот механизм правильно, сохранив целостность данных и используя возможности БСП.

Проблема уникальной идентификации строки

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

Разберем алгоритм подготовки структуры данных:

  1. В табличную часть нужного документа добавим новый реквизит КлючСвязиСтроки с типом Строка (длина 36 символов) или УникальныйИдентификатор.
  2. Для визуального информирования пользователя добавим в ТЧ реквизит НаличиеФайла (тип Булево) или числовой реквизит для подсчета количества файлов.
  3. В справочник присоединенных файлов, который обслуживает наш документ (например, ПриходныйОрдерНаТоварыПрисоединенныеФайлы), через расширение или в основной конфигурации добавим реквизит КлючСвязиСтроки с тем же типом данных. Это позволит нам фильтровать файлы документа по конкретной строке.

Генерация уникального ключа строки

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


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

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

Интерфейсная часть: кнопка управления файлами

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

Разберем пример кода команды на форме документа:


&НаКлиенте
Процедура КомандаФайлыСтроки(Команда)
    ТекущиеДанные = Элементы.Товары.ТекущиеДанные;
    Если ТекущиеДанные = Неопределено Тогда
        Возврат;
    КонецЕсли;

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

    ОткрытьФормуФайловСтроки(ТекущиеДанные.КлючСвязиСтроки);
КонецПроцедуры

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

Интеграция с подсистемой БСП «Работа с файлами»

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

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

Для этого выполним следующие действия:

  1. В форме списка справочника присоединенных файлов в процедуре ПриСозданииНаСервере считаем переданный параметр УзелФильтрации и сохраним его в переменной формы.
  2. Применим отбор к динамическому списку формы по значению КлючСвязиСтроки = УзелФильтрации.
  3. В модуле справочника присоединенных файлов (в процедуре ПередЗаписью) или в форме элемента обеспечим заполнение ключа связи из параметров формы.

Отображение статуса наличия файлов

Для того чтобы пользователь сразу видел, в каких строках есть вложения, проанализируем ситуацию обновления индикатора. Оптимально обновлять реквизит НаличиеФайла при записи документа или при закрытии формы работы с файлами. Для этого можно использовать Запрос, который проверит наличие записей в справочнике присоединенных файлов по условию Владелец = Объект.Ссылка И КлючСвязиСтроки = .... Для отображения признака наличия вложений в журналах и списках документов можно использовать решение для вывода в табличные формы признака наличия вложенного файла.

Посмотрим на пример функции для обновления индикаторов:


&НаСервере
Процедура ОбновитьПризнакиНаличияФайлов()
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ РАЗЛИЧНЫЕ
        |    Файлы.КлючСвязиСтроки КАК Ключ
        |ИЗ
        |    Справочник.ПриходныйОрдерНаТоварыПрисоединенныеФайлы КАК Файлы
        |ГДЕ
        |    Файлы.Владелец = &Владелец";
    
    Запрос.УстановитьПараметр("Владелец", Объект.Ссылка);
    КлючиСФайлами = Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку("Ключ");
    
    Для Каждого СтрокаТЧ Из Объект.Товары Цикл
        СтрокаТЧ.НаличиеФайла = (КлючиСФайлами.Найти(СтрокаТЧ.КлючСвязиСтроки) <> Неопределено);
    КонецЦикла;
КонецПроцедуры

Безопасность и хранение данных

Рассмотрим вопрос, почему не стоит использовать хранение путей к файлам на диске (через ЗапуститьПриложение()). Как было отмечено в обсуждении на форуме, прямой путь к файлу крайне нестабилен:

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

Резюме по реализации

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

← На главную