В практике разработки на платформе 1С:Предприятие 8 часто возникает задача по поиску и получению данных из разных источников: справочников базы данных, файловой системы сервера или локального диска пользователя. Начинающие разработчики часто сталкиваются с трудностями при настройке свойств Общих модулей, пытаясь совместить несовместимые контексты выполнения кода. Рассмотрим подробнее, как правильно спроектировать архитектуру такого решения и какие свойства модулей необходимо выставить.
Разберем основную проблему: программный код, выполняющийся на стороне сервера, физически не имеет доступа к локальным дискам клиентского компьютера. Если мы установим у модуля только свойство Сервер, мы сможем прочитать данные из справочника и найти файл на диске сервера, но попытка обратиться к диску C: пользователя вызовет ошибку или вернет пустой результат. И наоборот, код на стороне клиента не имеет прямого доступа к базе данных или файловой системе сервера приложений.
Проанализируем предложенный алгоритм поиска макета:
Для реализации этой цепочки нам потребуется разделить логику на два отдельных общих модуля. Выясним причину: это единственный способ соблюсти требования безопасности и производительности платформы.
Создадим модуль, который будет отвечать за работу с базой данных и файлами сервера. Назовем его, например, РаботаСМакетамиСервер. В его свойствах необходимо установить следующие флаги:
Рассмотрим пример кода для серверного модуля:
Функция ПолучитьМакетНаСервере(ИмяМакета) Экспорт
// 1. Ищем в справочнике
МакетСсылка = Справочники.МакетыПечатныхФорм.НайтиПоНаименованию(ИмяМакета);
Если Не МакетСсылка.Пустая() Тогда
Возврат МакетСсылка.ДанныеМакета.Получить(); // Возвращаем ДвоичныеДанные
КонецЕсли;
// 2. Ищем на диске сервера
ПутьКФайлу = "C:\ServerTemplates\" + ИмяМакета + ".mxl";
ФайлНаДиске = Новый Файл(ПутьКФайлу);
Если ФайлНаДиске.Существует() Тогда
Возврат Новый ДвоичныеДанные(ПутьКФайлу);
КонецЕсли;
Возврат Неопределено;
КонецФункции
Второй модуль будет отвечать за взаимодействие с пользователем и его файловой системой. Назовем его РаботаСМакетамиКлиент. В его свойствах установим:
Посмотрим на пример логики в клиентском модуле, который объединяет все шаги:
Функция НайтиМакетВезде(ИмяМакета) Экспорт
// Сначала идем на сервер (шаги 1 и 2)
ДанныеМакета = РаботаСМакетамиСервер.ПолучитьМакетНаСервере(ИмяМакета);
Если ДанныеМакета <> Неопределено Тогда
Возврат ДанныеМакета;
КонецЕсли;
// 3. Если сервер ничего не нашел, ищем на клиенте
ПутьКФайлу = "C:\LocalTemplates\" + ИмяМакета + ".mxl";
ФайлНаДиске = Новый Файл(ПутьКФайлу);
Если ФайлНаДиске.Существует() Тогда
Возврат Новый ДвоичныеДанные(ПутьКФайлу);
КонецЕсли;
Возврат Неопределено;
КонецФункции
При передаче макета с сервера на клиент важно учитывать тип возвращаемого значения. Рассмотрим подробнее:
ТабличныйДокумент, он также может быть передан, но при очень больших размерах это может вызвать задержку в работе интерфейса.Проанализируем ситуацию, если ваша база работает через браузер. В современных версиях платформы 1С (начиная с 8.3.15) работа с локальными файлами на клиенте должна выполняться асинхронно. Это значит, что вместо прямого вызова Файл.Существует(), нам придется использовать методы НачатьПоискФайлов или новые асинхронные аналоги. Без этого код в веб-клиенте работать не будет, а в тонком клиенте будет выдавать предупреждения.
Выясним причину, по которой поиск на сервере может не работать, даже если файл на диске есть. Процесс 1С (служба usr1cv8) должен иметь права на чтение папки, в которой лежат макеты. Если прав нет, функция Файл.Существует() всегда будет возвращать Ложь. Всегда проверяйте права доступа учетной записи, под которой запущен агент сервера 1С.
Также стоит помнить о нагрузке. Установка флага Вызов сервера на тяжелых модулях (с огромным количеством кода) не рекомендуется. Каждый раз, когда клиент обращается к такому модулю, система тратит ресурсы на его компиляцию в данном контексте. Правильнее использовать небольшие модули-посредники (шлюзы) для перехода с клиента на сервер.
Если макеты запрашиваются часто и меняются редко, мы можем значительно ускорить работу, установив в серверном модуле свойство Повторное использование значений. Если выбрать значение На время сеанса, то при первом обращении 1С найдет макет в базе или на диске и закеширует его. При повторном запросе система мгновенно вернет данные из памяти, не обращаясь к СУБД или файловой системе. Это существенно снижает нагрузку на серверную инфраструктуру.