Запись JEXL-макросов#
Сервис записи JEXL-макросов преобразует действия пользователя в готовые JEXL-скрипты. Инструмент создает сценарии автоматизации без ручного написания кода и глубокого изучения JEXL.
Основные сценарии использования:
Массовое создание объектов — добавление позиций номенклатуры, контрагентов, других сущностей;
Пакетное обновление данных — изменение реквизитов у группы объектов;
Формирование отчетных форм — создание печатных форм с настройкой шаблонов;
Импорт данных из файлов — обработка XLSX-файлов для переноса информации.
Примечание
Записываются только вызовы Api и Pkg. Макросы не содержат вызовы интерактивной логики.
Создание макросов#
Начало записи#
Перейдите в Сервис → Инструменты → Начать запись JEXL-скрипта.
В главном меню появится красный флаг — индикатор записи.
Примечание
Перед записью сохраните или откатите все несохраненные данные во всех формах.
При несохраненных данных система выдаст ошибку о невозможности изменения активности перехвата вызовов методов.
Запись действий#
После начала записи система отслеживает все действия. Выполните операции с данными, которые нужно записать.
Завершение и сохранение#
Остановите запись через:
Красный флаг в главном меню;
Сервис → Инструменты → Закончить запись JEXL-скрипта.
Просмотрите записанный скрипт в появившемся окне.
При закрытии окна подтвердите сохранение.
Выберите папку (по умолчанию — Личные).
Скрипт сохранится в Библиотеке скриптов.
Просмотр и редактирование#
Для работы с сохраненными скриптами:
Перейдите в Настройки и Сервисы.
Выберите Сервисы JEXL → Библиотеки JEXL.
Найдите скрипт в нужной папке.
Доступны просмотр, редактирование и выполнение скриптов.
Примеры скриптов#
Создание печатной формы:
var rop_Rpt_Report1 = Rpt_ReportApi.insert();
Btk_ObjectGroupApi.register(rop_Rpt_Report1, 27851L, 1B, 1B);
Rpt_ReportApi.setsSystemName(rop_Rpt_Report1, 'SomeReportName');
Rpt_ReportApi.setsCaption(rop_Rpt_Report1, 'Отчет');
Rpt_ReportApi.setidModule(rop_Rpt_Report1, 901L);
var rop_Rpt_ReportVersion1 = Rpt_ReportVersionApi.insertByParent(rop_Rpt_Report1);
Rpt_ReportVersionApi.setidReportType(rop_Rpt_ReportVersion1, 451L);
В сформированном скрипте все идентификаторы имеют исходный вид. Если этот скрипт планируется использовать на других базах данных, где идентификаторы будут отличаться, необходимо заменить их получение в скрипте - например, на метод findByMnemoCode.
Видоизмененный скрипт:
var rop_Rpt_Report1 = Rpt_ReportApi.insert();
Btk_ObjectGroupApi.register(rop_Rpt_Report1, 27851L, 1B, 1B);
Rpt_ReportApi.setsSystemName(rop_Rpt_Report1, 'SomeReportName');
Rpt_ReportApi.setsCaption(rop_Rpt_Report1, 'Отчет');
Rpt_ReportApi.setidModule(rop_Rpt_Report1, Btk_ModuleApi.findByMnemoCode('btk'));
var rop_Rpt_ReportVersion1 = Rpt_ReportVersionApi.insertByParent(rop_Rpt_Report1);
Rpt_ReportVersionApi.setidReportType(rop_Rpt_ReportVersion1, Rpt_ReportTypeApi.findByMnemoCode('jasper'));
Обработка данных Excel#
Для работы с xlsx в jexl используется библиотека poi.apache.org.
Для удобства загрузки файлов написана функциональная библиотека Bts_XlsxPkg. Метод uploadParseFiles открывает диалог выбора файла и парсит его, предоставляя разработчику возможность его обработки. Создается объект класса org.apache.poi.ss.usermodel.Workbook.
Для выполнения массовой обработки данных из файлов Excel, вы можете использовать следующий метод:
lib("Btk_XlsxLib").uploadParseFiles(fun);
Где fun - это функция Jexl, которая будет выполняться для обработки данных из Excel.
Пример обработки xlsx:
var fun = x -> {
var sheet = x.getSheet("Материалы");
var lastRowNum = sheet.getLastRowNum();
var i = 1;
while (i <= lastRowNum ){
var svNomName = sheet.getRow(i).getCell(3).getStringCellValue(); // Условное наименование
var idvMSRItem = sheet.getRow(i).getCell(4).getNumberCellValue().toBigDeсimal(); // ЕИ
var idvGost = sheet.getRow(i).getCell(5).getStringCellValue(); // ГОСТ
var idvSortamentType = sheet.getRow(i).getCell(6).getNumberCellValue().toBigDeсimal(); // Тип сортамента
var rop_Bs_Goods1 = Bs_GoodsApi.insert();
Bs_GoodsApi.setsNomName(rop_Bs_Goods1, svNomName); // установка условного наименования
Bs_GoodsApi.setidMeasureItem(rop_Bs_Goods1, idvMSRItem); // установка ЕИ
Bs_GoodsApi.setsGost(rop_Bs_Goods1, svNomName); // установка условного наименования
Bs_GoodsApi.setsNomName(rop_Bs_Goods1, svNomName); // установка условного наименования
commit();
i = i+1;
}
true;
}
lib("Btk_XlsxLib").uploadParseFiles(fun);
Приведенный ниже пример функции fun иллюстрирует, как обработать данные из файла Excel и создать объекты в системе на их основе.
Расширенная обработка с разными типами данных:
var fun = x -> {
// Получение листа "Лист1" из файла Excel
var sheet = x.getSheet("Лист1");
// Определение количества заполненных строк в файле
var lastRowNum = sheet.getLastRowNum();
var i = 0;
while (i <= lastRowNum) {
// Класс для которого мы создаем объекты
var rop_RplTst_AllDbTypes1 = RplTst_AllDbTypesApi.insert();
// Получение значений из ячеек Excel и преобразование их к необходимым типам
// Для получения значения типа Long нужно дополнительно использовать метод toLong
var vjson = sheet.getRow(i).getCell(0).getStringCellValue();
var vsystemname = sheet.getRow(i).getCell(1).getStringCellValue();
var vcaption = sheet.getRow(i).getCell(2).getStringCellValue();
var vgidrefclassany = sheet.getRow(i).getCell(3).getStringCellValue();
var vidobjecttype = sheet.getRow(i).getCell(4).getNumericCellValue().toLong();
var vdate = toDate(sheet.getRow(i).getCell(5).getStringCellValue());
// Преобразование для NNumber
var vNumber = sheet.getRow(i).getCell(6).getNumericCellValue().toBigDecimal();
// Установка значений для созданного объекта
RplTst_AllDbTypesApi.setjJson(rop_RplTst_AllDbTypes1, vjson);
RplTst_AllDbTypesApi.setsSystemName(rop_RplTst_AllDbTypes1, vsystemname);
RplTst_AllDbTypesApi.setsCaption(rop_RplTst_AllDbTypes1, vcaption);
RplTst_AllDbTypesApi.setgidRefAny(rop_RplTst_AllDbTypes1, vgidrefclassany);
RplTst_AllDbTypesApi.setNumber(rop_RplTst_AllDbTypes1, vNumber);
// Проверка и установка idObjectType только если он не равен 0
if (vidobjecttype != 0) {
RplTst_AllDbTypesApi.setidObjectType(rop_RplTst_AllDbTypes1, vidobjecttype);
}
// Установка даты
RplTst_AllDbTypesApi.setdDate(rop_RplTst_AllDbTypes1, vdate);
// Сохранение изменений
commit();
// Увеличение счетчика строк
i = i + 1;
}
// Возврат булевого значения, необходимого для выполнения скрипта
true;
}
Запуск скрипта
После написания функции fun, выполните скрипт, и появится модальное окно для выбора файлов Excel. Выберите необходимые файлы, и функция начнет обработку данных и создание объектов в системе на основе данных из Excel.
С помощью этой библиотеки вы можете эффективно работать с данными Excel и использовать записанные Jexl-скрипты для массовой обработки и создания объектов по сложным сценариям.
Полный тестовый скрипт обработки Excel:
var fun = x -> {
var sheet = x.getSheet("Лист1");
var lastRowNum = sheet.getLastRowNum();
var i = 0;
while (i <= lastRowNum ){
var rop_RplTst_AllDbTypes1 = RplTst_AllDbTypesApi.insert();
var vjson = sheet.getRow(i).getCell(0).getStringCellValue();
var vsystemname = sheet.getRow(i).getCell(1).getStringCellValue();
var vcaption = sheet.getRow(i).getCell(2).getStringCellValue();
var vgidrefclassany = sheet.getRow(i).getCell(3).getStringCellValue();
var vidobjecttype = sheet.getRow(i).getCell(4).getNumericCellValue().toLong();
var vdate = toDate(sheet.getRow(i).getCell(5).getStringCellValue());
RplTst_AllDbTypesApi.setjJson(rop_RplTst_AllDbTypes1, vjson);
RplTst_AllDbTypesApi.setsSystemName(rop_RplTst_AllDbTypes1, vsystemname);
RplTst_AllDbTypesApi.setsCaption(rop_RplTst_AllDbTypes1, vcaption);
RplTst_AllDbTypesApi.setgidRefAny(rop_RplTst_AllDbTypes1, vgidrefclassany);
if (vidobjecttype != 0) RplTst_AllDbTypesApi.setidObjectType(rop_RplTst_AllDbTypes1, vidobjecttype);
RplTst_AllDbTypesApi.setdDate(rop_RplTst_AllDbTypes1, vdate);
commit();
i = i+1;
}
true;
}
lib("Btk_XlsxLib").uploadParseFiles(fun);
Внимание
Пустые ячейки: могут возвращать 0 вместо null — добавляйте проверки.
Типы данных: следите за соответствием типов Excel и системы. В приведенном примере, используется метод getStringCellValue() для получения текстовых значений, и getNumericCellValue().toLong() для числовых значений.
Возвращаемое булево значение: функция должна возвращать true/false.
Работа с файлами#
Загрузка во временный каталог#
files.uploadFileToTemp(res -> {
var file = res.file(); //java.io.File
//чтение содержимого файла
var utils = new('org.apache.commons.io.FileUtils');
var content = utils.readFileToString(file, "UTF-8");
dialogs.showMessage(content);
true;
});
Примечание
Работает только для jexl-скриптов в контексте выборки.
Выгрузка строки как файла#
var text = "Привет!"
files.downloadBytes(text.getBytes("UTF-8"), "Имя_Файла.txt", true, false);
Примечание
Работает только для jexl-скриптов в контексте выборки.
Необходимые права#
Для использования сервиса:
Стандартные права на приложение и доступ к Сервис → Инструменты → Закончить запись JEXL-скрипта;
Привилегия Доступ к инструментам меню Сервиса для объекта
Btk_ManagementPkg.