Как исправить изменение картинки у всех скопированных характеристик в 1С?

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

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

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

Проанализируем ситуацию и код

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


ТД = ЭлементыФормы.Характеристики.ТекущиеДанные;
Если ТД <> Неопределено Тогда
    РаботаСФайлами.ОткрытьФормуИзображения(ЭтаФорма, ТД.ОсновноеИзображение, ТД.Ссылка);
КонецЕсли;

Здесь ТекущиеДанные — это текущая (выделенная) строка таблицы характеристик. Код корректно считывает значение реквизита ОсновноеИзображение и пытается открыть файл. Но почему же при изменении этого изображения страдает оригинал?

Выясним причину такого поведения платформы

Описанная ситуация является классической особенностью платформы 1С:Предприятие при работе со связанными объектами — прикрепленными файлами или картинками. Разберем механику копирования:

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

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

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

Рассмотрим несколько путей решения: от ручного пользовательского обхода до правильного вмешательства в программный код 1С.

Решение 1: Ручной обход проблемы пользователем

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

Пользователю следует удалить скопированную характеристику, а затем добавить её заново (с нуля, без копирования). При создании характеристики «с нуля» реквизит изображения остается пустым. При добавлении фотографии корректно создастся собственная новая запись в хранилище файлов, независимая от других характеристик, и изменения не затронут оригиналы.

Решение 2: Программная очистка ссылки при копировании

Чтобы избежать такого поведения в будущем и облегчить жизнь пользователям, программистам необходимо вмешаться в стандартный процесс копирования. Самый простой и правильный путь — переопределить обработчик события копирования и принудительно очищать реквизит с картинкой у нового объекта.

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


Процедура ПриКопировании(ОбъектКопирования)
    // Очищаем ссылку на изображение, чтобы не перезаписать файл оригинала
    ЭтотОбъект.ОсновноеИзображение = Справочники.ХранилищеДополнительнойИнформации.ПустаяСсылка();
КонецПроцедуры

Если же мы работаем с табличной частью, аналогичный подход применяется в модуле формы в событии ПриНачалеРедактирования:


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

В результате при копировании характеристики все текстовые данные скопируются, а поле картинки станет пустым. Пользователь загрузит новое фото, которое создаст новый связанный файл.

Решение 3: Создание физической копии картинки

Иногда бизнес-логика требует, чтобы при копировании характеристики картинка тоже сохранялась (например, товар выглядит так же), но при этом её можно было бы менять независимо от оригинала. В этом случае в событии ПриКопировании необходимо программно создать новый элемент справочника с файлами.

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

  1. Получаем двоичные данные картинки из объекта-оригинала (используя ОбъектКопирования.ОсновноеИзображение).
  2. Программно создаем новый элемент справочника файлов/хранилища.
  3. Записываем полученные двоичные данные в новый элемент.
  4. Присваиваем ссылку на этот новый файл реквизиту ОсновноеИзображение текущего (копируемого) объекта.

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

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

← На главную