Рассмотрим частую и весьма неприятную ситуацию, с которой можно столкнуться при доработке конфигураций на базе 1С:Предприятие (например, в 1С:Управление торговлей 10.3). Допустим, у нас есть доработка, позволяющая прикреплять фотографии к каждой характеристике номенклатуры. Проблема возникает, когда пользователи начинают добавлять новые характеристики копированием существующих: при попытке заменить изображение в новой характеристике, картинка неожиданно меняется и у оригинала, и у всех остальных скопированных элементов.
Давайте подробно разберем по шагам, почему возникает эта ошибка, проанализируем текущий код и найдем правильные способы решения проблемы как на уровне пользователя, так и на уровне программного кода.
В исходной задаче для открытия прикрепленного изображения используется конструкция с обращением к выделенной строке табличной части или списка. Посмотрим на пример кода, который открывает форму картинки:
ТД = ЭлементыФормы.Характеристики.ТекущиеДанные;
Если ТД <> Неопределено Тогда
РаботаСФайлами.ОткрытьФормуИзображения(ЭтаФорма, ТД.ОсновноеИзображение, ТД.Ссылка);
КонецЕсли;
Здесь ТекущиеДанные — это текущая (выделенная) строка таблицы характеристик. Код корректно считывает значение реквизита ОсновноеИзображение и пытается открыть файл. Но почему же при изменении этого изображения страдает оригинал?
Описанная ситуация является классической особенностью платформы 1С:Предприятие при работе со связанными объектами — прикрепленными файлами или картинками. Разберем механику копирования:
ОсновноеИзображение не хранит саму картинку физически. Он хранит лишь ссылку на отдельный объект (например, на элемент справочника ХранилищеДополнительнойИнформации или ПрисоединенныеФайлы).Кроме того, стоит помнить, что при интерактивном копировании до момента записи нового элемента его реквизит Ссылка является пустым. Передача пустой ссылки в процедуру открытия формы может приводить к ошибкам связи объекта с его файлом.
Рассмотрим несколько путей решения: от ручного пользовательского обхода до правильного вмешательства в программный код 1С.
Если нет возможности оперативно внести изменения в конфигурацию, можно воспользоваться простым пользовательским лайфхаком. Поскольку проблема кроется именно в процессе копирования, нам нужно разорвать эту связь.
Пользователю следует удалить скопированную характеристику, а затем добавить её заново (с нуля, без копирования). При создании характеристики «с нуля» реквизит изображения остается пустым. При добавлении фотографии корректно создастся собственная новая запись в хранилище файлов, независимая от других характеристик, и изменения не затронут оригиналы.
Чтобы избежать такого поведения в будущем и облегчить жизнь пользователям, программистам необходимо вмешаться в стандартный процесс копирования. Самый простой и правильный путь — переопределить обработчик события копирования и принудительно очищать реквизит с картинкой у нового объекта.
Разберем подробнее, как это сделать в модуле объекта справочника:
Процедура ПриКопировании(ОбъектКопирования)
// Очищаем ссылку на изображение, чтобы не перезаписать файл оригинала
ЭтотОбъект.ОсновноеИзображение = Справочники.ХранилищеДополнительнойИнформации.ПустаяСсылка();
КонецПроцедуры
Если же мы работаем с табличной частью, аналогичный подход применяется в модуле формы в событии ПриНачалеРедактирования:
Процедура ХарактеристикиПриНачалеРедактирования(Элемент, НоваяСтрока, Копирование)
Если Копирование Тогда
ТД = Элемент.ТекущиеДанные;
// Очищаем картинку в скопированной строке
ТД.ОсновноеИзображение = Справочники.ХранилищеДополнительнойИнформации.ПустаяСсылка();
КонецЕсли;
КонецПроцедуры
В результате при копировании характеристики все текстовые данные скопируются, а поле картинки станет пустым. Пользователь загрузит новое фото, которое создаст новый связанный файл.
Иногда бизнес-логика требует, чтобы при копировании характеристики картинка тоже сохранялась (например, товар выглядит так же), но при этом её можно было бы менять независимо от оригинала. В этом случае в событии ПриКопировании необходимо программно создать новый элемент справочника с файлами.
Посмотрим на примерный алгоритм действий:
ОбъектКопирования.ОсновноеИзображение).ОсновноеИзображение текущего (копируемого) объекта.Таким образом, мы получим две разные ссылки на два разных физических файла, содержащих одинаковое изображение. Их можно будет изменять совершенно независимо друг от друга.
Применяя описанные методы, вы надежно избавитесь от проблемы дублирования ссылок при копировании элементов и обеспечите корректную работу пользователей с прикрепленными файлами.