Загрузка прайс-листов из Excel — это стандартная задача для любого специалиста 1С, однако появление в этих листах изображений часто ставит разработчика в тупик. Основная сложность заключается в том, что в структуре Excel картинки не хранятся непосредственно в ячейках; они «парят» над сеткой листа как графические объекты (шейпы). Тем не менее, платформа 1С предоставляет механизмы для сопоставления этих объектов с координатами строк и колонок.
В данной статье мы разберем несколько эффективных способов извлечения графических данных и их последующего сохранения в информационную базу 1С.
Это самый простой и рекомендуемый способ, который не требует установленного Microsoft Excel на стороне сервера и работает быстрее, чем прямое COM-соединение. Суть метода заключается в том, чтобы прочитать файл .xls или .xlsx во временный табличный документ 1С. Платформа при чтении автоматически преобразует графические объекты Excel в объекты типа РисунокТабличногоДокумента.
Рассмотрим пошагово реализацию этого алгоритма:
ТабличныйДокумент.
// Создаем объект для чтения файла
ТабДок = Новый ТабличныйДокумент;
// Читаем файл Excel.
// Важно использовать параметр СпособЧтенияЗначенийТабличногоДокумента.Значение
// для корректного распознавания типов данных.
Попытка
ТабДок.Прочитать(ПутьКФайлуЭксель, СпособЧтенияЗначенийТабличногоДокумента.Значение);
Исключение
Сообщить("Не удалось прочитать файл: " + ОписаниеОшибки());
Возврат;
КонецПопытки;
// Перебираем строки табличного документа
Для НомерСтроки = 1 По ТабДок.ВысотаТаблицы Цикл
// Определяем область поиска (например, картинка должна быть в 3-й колонке)
// Формат адреса: R (строка), C (колонка)
АдресОбласти = "R" + Формат(НомерСтроки, "ЧГ=0") + "C3";
ОбластьЯчейки = ТабДок.ПолучитьОбласть(АдресОбласти);
// В полученной области проверяем коллекцию Рисунки
Для Каждого Рисунок Из ОбластьЯчейки.Рисунки Цикл
// Проверяем, является ли объект картинкой
Если Рисунок.ТипРисунка = ТипРисункаТабличногоДокумента.Картинка Тогда
ОбъектКартинка = Рисунок.Картинка;
// Теперь у нас есть объект типа Картинка, который можно сохранить или вывести на форму
// Пример: сохранение в Таблицу Значений на форме
НоваяСтрокаТЗ = ТЗДанных.Добавить();
НоваяСтрокаТЗ.НоменклатураНаименование = ТабДок.Область(НомерСтроки, 1).Текст;
НоваяСтрокаТЗ.Фото = ОбъектКартинка;
// Если нашли картинку в строке, прерываем поиск для этой строки
Прервать;
КонецЕсли;
КонецЦикла;
КонецЦикла;
Важное примечание: При использовании этого метода стоит помнить, что если картинка в Excel немного смещена и пересекает границы нескольких ячеек, 1С может отнести её к той области, где находится большая часть изображения или левый верхний угол. Рекомендуем расширять область поиска до нескольких колонок, если верстка файла нестабильна.
Современные файлы .xlsx представляют собой ZIP-архивы. Если ваша задача — быстро выгрузить тысячи картинок, метод с табличным документом может потреблять слишком много оперативной памяти. В таком случае проанализируем альтернативный подход — работу с внутренним хранилищем архива.
Рассмотрим алгоритм действий:
ЧтениеZipФайла для открытия .xlsx файла.xl/media/.xl/drawings/.Этот метод считается наиболее «нативным» для систем на базе Linux, так как он не зависит от библиотек Windows или установленных офисных пакетов.
Если вы уже используете Excel.Application для загрузки данных, вы можете столкнуться с проблемой: объект Shape (рисунок) в Excel нельзя напрямую передать в переменную 1С как файл. Выясним причину: COM-интерфейс предоставляет ссылку на объект, но не его двоичные данные.
Проанализируем техническую хитрость для решения этой проблемы:
// Пример логики экспорта через временную диаграмму
Для Каждого ТекущийРисунок Из ExcelЛист.Shapes Цикл
// Копируем рисунок в буфер обмена
ТекущийРисунок.Copy();
// Создаем временную диаграмму (Chart) того же размера
ВременнаяДиаграмма = ExcelЛист.ChartObjects().Add(0, 0, ТекущийРисунок.Width, ТекущийРисунок.Height);
ВременнаяДиаграмма.Chart().Paste();
// Экспортируем диаграмму в файл
ИмяФайла = КаталогВременныхФайлов() + "temp_img.jpg";
ВременнаяДиаграмма.Chart().Export(ИмяФайла);
// Загружаем файл в 1С
НужныеДанныеКартинки = Новый Картинка(ИмяФайла);
// Удаляем временные объекты
ВременнаяДиаграмма.Delete();
КонецЦикла;
Внимание: Не забывайте корректно завершать работу COM-объекта. В коде обязательно должны присутствовать инструкции Excel.Quit() и обнуление переменных, иначе процесс EXCEL.EXE останется висеть в памяти сервера, блокируя файл.
После того как мы извлекли объект Картинка, его необходимо поместить в справочник. В современных конфигурациях (УТ 11, ERP, КА 2, БП 3.0) для этого используется механизм присоединенных файлов. Просто записать картинку в реквизит недостаточно.
Рассмотрим стандартный алгоритм сохранения (на примере БСП):
Картинка в ДвоичныеДанные.НоменклатураПрисоединенныеФайлы.ФайлКартинки в основной карточке товара.Посмотрим на пример кода:
// Преобразуем картинку для сохранения
ДвоичныеДанныеФайла = ОбъектКартинка.ПолучитьДвоичныеДанные();
// Параметры для создания файла (структура БСП)
ПараметрыФайла = Новый Структура;
ПараметрыФайла.Вставить("Автор", Пользователи.ТекущийПользователь());
ПараметрыФайла.Вставить("Владелец", СсылкаНаНоменклатуру);
ПараметрыФайла.Вставить("ИмяБезРасширения", "Фото_" + СсылкаНаНоменклатуру.Код);
ПараметрыФайла.Вставить("Расширение", "jpg");
// Вызов стандартной функции БСП (если используется)
// РаботаСФайлами.ДобавитьФайл(ПараметрыФайла, ДвоичныеДанныеФайла);
Во время работы с картинками из Excel обратите внимание на следующие моменты:
EMF или WMF. Перед сохранением в базу 1С рекомендуется принудительно преобразовывать их в PNG или JPG методом Картинка.Преобразовать(), чтобы избежать проблем с отображением в мобильном приложении или веб-клиенте.Картинка.Вид(). Иногда объекты Shapes в Excel — это не фотографии, а прозрачные кнопки или автофигуры, которые не нужно загружать как фото товара.Таким образом, мы проанализировали основные способы автоматизации загрузки графического контента. Наиболее стабильным и универсальным для платформы 8.3 является метод с использованием ТабличныйДокумент, так как он обеспечивает баланс между простотой разработки и скоростью выполнения задачи.