При организации обмена данными между 1С:Бухгалтерия 3.0 и интернет-магазином часто возникает необходимость строго регламентировать параметры загружаемых изображений. Большие файлы могут замедлять работу сайта и раздувать размер базы данных, а неподдерживаемые расширения — некорректно отображаться в браузере. В этой статье мы разберем, как внести изменения в типовой механизм работы с файлами Библиотеки стандартных подсистем (БСП), чтобы контролировать процесс добавления картинок в справочник Номенклатура.
В современных конфигурациях 1С для работы с присоединенными файлами используется общая подсистема. Проанализируем путь, по которому проходит файл при нажатии кнопки «Добавить» в карточке номенклатуры. Основная логика сосредоточена в общем модуле РаботаСФайламиКлиент. Рассмотрим ключевую процедуру ДобавитьФайлы, которая инициирует процесс выбора файла пользователем:
Процедура ДобавитьФайлы(Знач ВладелецФайла, Знач ИдентификаторФормы, Знач Фильтр = "", ГруппаФайлов = Неопределено, ОбработчикРезультата = Неопределено) Экспорт
// Подготовка параметров для выбора файла
Параметры = Новый Структура;
Параметры.Вставить("ВладелецФайла", ВладелецФайла);
Параметры.Вставить("ИдентификаторФормы", ИдентификаторФормы);
Параметры.Вставить("Фильтр", Фильтр);
ОписаниеОповещения = Новый ОписаниеОповещения("ДобавитьФайлыРасширениеПредложено", РаботаСФайламиСлужебныйКлиент, Параметры);
РаботаСФайламиСлужебныйКлиент.ПоказатьВопросОбУстановкеРасширенияРаботыСФайлами(ОписаниеОповещения);
КонецПроцедуры
Параметр Фильтр в данной процедуре определяет, какие типы файлов пользователь увидит в диалоговом окне выбора. Чтобы ограничить выбор только изображениями, нам необходимо правильно сформировать эту строку.
Выясним, как работает фильтрация. Формат строки фильтра соответствует стандарту платформы 1С. Для того чтобы разрешить загрузку только популярных форматов (JPG, PNG, BMP), мы должны передать строку в следующем виде: "Изображения (*.jpg, *.png)|*.jpg;*.png". Проанализируем ситуацию: если мы хотим жестко задать список расширений в коде, мы можем перехватить вызов этой процедуры в расширении конфигурации.
Рассмотрим пример установки фильтра:
// В расширении для процедуры ДобавитьФайлы
&Перед("ДобавитьФайлы")
Процедура Расш_ДобавитьФайлы(ВладелецФайла, ИдентификаторФормы, Фильтр, ГруппаФайлов, ОбработчикРезультата)
Если ТипЗнч(ВладелецФайла) = Тип("СправочникСсылка.Номенклатура") Тогда
Фильтр = "Изображения (jpg, png)|*.jpg;*.png;*.jpeg";
КонецЕсли;
КонецПроцедуры
Одной фильтрации по расширению недостаточно, так как файл формата JPG может весить несколько десятков мегабайт. Разберем, как проверить размер файла на клиенте перед его передачей на сервер. Для этого используется объект Файл. Нам необходимо найти место в коде, где выбранные файлы уже получены, но еще не записаны в базу данных.
Обычно это происходит в обработчиках оповещения после закрытия диалога выбора файла. Чтобы реализовать проверку, выполним следующие шаги:
Файл, передав в конструктор путь к выбранному файлу.Размер(), который возвращает размер в байтах.Пример кода для проверки размера:
МаксимальныйРазмер = 1024 * 1024; // 1 Мегабайт
ВыбранныйФайл = Новый Файл(ПутьКФайлу);
Если ВыбранныйФайл.Размер() > МаксимальныйРазмер Тогда
ОбщегоНазначенияКлиентСервер.СообщитьПользователю("Файл слишком велик! Максимальный размер — 1Мб.");
Возврат; // Прерываем процесс добавления
КонецЕсли;
Для SEO-оптимизации сайта или просто для порядка в системе часто требуется переименовывать загружаемые картинки по шаблону «Артикул_Наименование». Посмотрим на распространенную ошибку: попытку обратиться к реквизитам ВладелецФайла (который является ссылкой на Номенклатуру) напрямую в клиентском общем модуле.
В 1С:Предприятие 8.3 на клиенте реквизиты ссылочных объектов недоступны. Чтобы получить Код или Артикул номенклатуры, необходимо выполнить серверный вызов. Разберем правильный подход с использованием функций общего модуля:
// Неправильно (вызовет ошибку):
// ИмяФайла = ВладелецФайла.Артикул;
// Правильно (используем вызов сервера):
СтруктураРеквизитов = ОбщегоНазначенияВызовСервера.ЗначенияРеквизитовОбъекта(ВладелецФайла, "Артикул, Наименование");
НовоеИмя = Строка(СтруктураРеквизитов.Артикул) + "_" + СтруктураРеквизитов.Наименование;
Проанализируем ситуацию: использование ОбщегоНазначенияВызовСервера.ЗначенияРеквизитовОбъекта является наиболее оптимальным, так как оно позволяет получить несколько полей за один вызов сервера, что критично для производительности клиент-серверного взаимодействия.
Если мы хотим гарантированно ограничить размер файла независимо от того, как он добавляется (через форму, программно или через обработку), наиболее надежным способом будет использование подписки на событие ПередЗаписью для справочника НоменклатураПрисоединенныеФайлы.
Рассмотрим этот вариант подробнее:
Размер.
Процедура ПередЗаписьюПрисоединенногоФайла(Источник, Отказ) Экспорт
Если Источник.ОбменДанными.Загрузка Тогда
Возврат;
КонецЕсли;
// Проверка размера (в справочнике размер хранится в байтах)
МаксРазмер = 2 * 1024 * 1024; // 2 Мб
Если Источник.Размер > МаксРазмер Тогда
ТекстСообщения = СтрШаблон("Файл %1 превышает лимит (2Мб)", Источник.Наименование);
ОбщегоНазначенияКлиентСервер.СообщитьПользователю(ТекстСообщения, , , , Отказ);
КонецЕсли;
КонецПроцедуры
Посмотрим, что предлагает типовой функционал без программирования. В разделе Администрирование — Настройки файлов можно установить глобальное ограничение на размер загружаемых файлов для всей системы. Однако это неудобно, если для первичных документов (сканов договоров) нужны большие объемы, а для товаров — маленькие. В этом случае программный метод, описанный выше, остается приоритетным.
Также стоит рассмотреть возможность автоматического изменения размера изображений (ресайз). С помощью объекта Картинка в 1С можно программно уменьшить разрешение изображения перед сохранением. Это позволит пользователям загружать даже фотографии с камер высокого разрешения, а система сама приведет их к нужному стандарту для сайта:
КартинкаОбъект = Новый Картинка(ПутьКФайлу);
Если КартинкаОбъект.Ширина() > 1000 Тогда
// Примерная логика преобразования
НоваяКартинка = КартинкаОбъект.Преобразовать(ФорматКартинки.JPEG);
// Далее сохранение уменьшенного варианта
КонецЕсли;
Подводя итог, отметим, что для качественной подготовки данных к выгрузке на сайт в 1С:Бухгалтерия 3.0 лучше всего использовать сочетание фильтра в диалоге выбора (для удобства пользователя) и проверки в подписке на событие (для надежности данных в базе).