Почему не работает перемещение файлов в группы в 1С:ERP и как это исправить?

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

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

Анализ исходной ситуации и причины возникновения ошибки

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


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

Проанализируем состояние переменных в момент ошибки через отладчик. Мы обнаружим, что в массиве Файлы, который передается в процедуру, содержатся не ссылки на элементы справочника (например, СправочникСсылка.ЗаказПоставщикуПрисоединенныеФайлы), а обычные Числа. Естественно, у типа Число нет метода ПолучитьОбъект(), что и вызывает исключение.

Почему динамический список возвращает числа вместо ссылок?

Выясним причину такого поведения платформы. В 1С:Предприятии 8.3 объект ДинамическийСписок возвращает коллекцию идентификаторов выделенных строк. Если у списка заполнено свойство ОсновнаяТаблица, платформа автоматически преобразует эти идентификаторы в ссылки на объекты этой таблицы.

Однако, если разработчик модифицирует запрос динамического списка, используя конструкцию ОБЪЕДИНИТЬ ВСЕ (UNION ALL) для вывода данных из нескольких таблиц (например, объединяя файлы разных документов), свойство ОсновнаяТаблица приходится очищать. Рассмотрим пример некорректной модификации процедуры НастроитьДинамическийСписок:


&НаСервере
Процедура НастроитьДинамическийСписок(ИмяСправочникаХранилищаФайлов)
    // ... формирование текста запроса с ОБЪЕДИНИТЬ ВСЕ ...
    
    СвойстваСписка.ОсновнаяТаблица = ПолноеИмяСправочника;
    ОбщегоНазначения.УстановитьСвойстваДинамическогоСписка(Элементы.Список, СвойстваСписка);

    Если ВладелецФайлаДополнительно.Количество > 0 Тогда
        // ОПАСНЫЙ МОМЕНТ: очистка основной таблицы
        Список.ОсновнаяТаблица = ""; 
        Список.ДинамическоеСчитываниеДанных = Истина;
    КонецЕсли;
КонецПроцедуры

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

Варианты решения проблемы

Рассмотрим несколько способов исправления данной ситуации, от простого к сложному.

Способ 1. Получение ссылок через данные строки

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


&НаКлиенте
Процедура СписокВыборЗначения(Элемент, Значение, СтандартнаяОбработка)
    МассивСсылок = Новый Массив;
    Для Каждого ИдентификаторСтроки Из Элементы.Список.ВыделенныеСтроки Цикл
        ДанныеСтроки = Элементы.Список.ДанныеСтроки(ИдентификаторСтроки);
        Если ДанныеСтроки <> Неопределено Тогда
            МассивСсылок.Добавить(ДанныеСтроки.Ссылка);
        КонецЕсли;
    КонецЦикла;
    
    ПереместитьФайлыВГруппу(МассивСсылок, Значение);
    // ... остальной код ...
КонецПроцедуры

Способ 2. Корректная обработка разнородных типов файлов

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


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

Способ 3. Отказ от объединения таблиц в одной форме

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

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

Дополнительные рекомендации

Проанализируем ситуацию, если код кажется верным, но ошибка сохраняется. В этом случае стоит обратить внимание на следующие технические моменты:

  1. Очистка кэша: Иногда платформа "запоминает" структуру динамического списка до внесения изменений в расширение. Попробуйте очистить локальный кэш пользователя.
  2. Версия платформы и БСП: Убедитесь, что используемая версия БСП в вашей ERP (регистр сведений ВерсииПодсистем) соответствует документации. В последних версиях механизм РаботаСФайлами сильно завязан на программную настройку списков через метод ПриСозданииНаСервере.
  3. Проверка через расширения: Если вы модифицируете форму через расширение, убедитесь, что вы не переопределяете ОсновнуюТаблицу в свойствах элемента формы "Список" вручную.

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

← На главную