Особенности работы в системе Global#

Система Global предоставляет расширенные возможности для работы с данными через JEXL-скрипты. В статье описаны основные методы работы с переменными, выборками, данными и внешними сервисами.

Наименование переменных для nullable типов и атрибутов#

Правила именования переменных: [Variable][a][t][Scope][Name][Suffix].

Компоненты именования:

  • [Variable] — определяет тип данных:

    • n — число;

    • s — строка;

    • j — строка в формате JSON;

    • d — дата;

    • r, x — запись;

    • u, cur — курсор;

    • l, blob — бинарные данные;

    • с — символьные данные;

    • b — булево значение;

    • id — идентификатор;

    • gid — глобальный идентификатор.

  • [a] — определяет, является ли переменная последовательностью;

  • [t] — определяет пользовательский тип;

  • [Scope] — область действия:

    • v — переменная процедуры;

    • p — параметр процедуры;

  • [Name] — имя переменной;

  • [Suffix] — суффикс:

    • _dz — системные атрибуты;

    • _z — проектные атрибуты.

Примеры именования параметров:

  • dStart — дата начала в таблице;

  • dvStart — дата начала переменной процедуры;

  • dgMaxDate — максимальная дата переменной пакета;

  • tvdaDate — тип коллекции дат в процедуре;

  • davDate — коллекция дат в процедуре;

  • uvStudents — курсор в процедуре.

Основные методы и принципы работы#

Поиск методов класса#

Для просмотра доступных методов любого класса выполните следующие шаги:

  1. Перейдите в Настройки системыОбозреватель проектов.

  2. Введите имя класса (например, Stm_OrderOut).

  3. Откройте файл с суффиксом Api (например, Stm_OrderOut_Api).

  4. Перейдите на вкладку Методы.

В этом разделе отображаются все доступные методы класса. Большинство классов содержат стандартный набор методов для работы.

Работа с текущей выборкой#

При запуске JEXL-скрипта часто происходит работа внутри существующей выборки (например, при выделении строки в таблице).

С помощью selection.getVar можно получить атрибуты текущей выборки:

var id = selection.getVar("атрибут");
var idvOrder = selection.getVar("id"); // "id" — название атрибута

Загрузка строки через rop#

rop — специальный тип данных для переменных, соответствующий строке объекта в таблице базы данных. Внутри данной строки можно обратиться к любому физическому столбцу. По сути это проводник к строке в базе данных.

Принцип работы:

  1. Сначала проверяет наличие данных в кэше.

  2. Если данных нет — загружает их из базы.

  3. Предоставляет удобный доступ к полям строки.

Получить строку можно с помощью метода load. Полученное значение будет типа rop:

ropOrder = Stm_OrderOutApi.load(idvOrder);

Доступ к атрибутам строки#

Обычные атрибуты (колонки таблицы) доступны напрямую через точку:

var svNumDoc = ropOrder.sNumDoc; // Номер документа
var idvClient = ropOrder.idClient; // ID клиента

Работа с JSON-атрибутами на примере Stm_OrderOut

Получение значений атрибутов:

  1. Получение всего JSON объекта:

var jvParams = ropOrder.jParams_dz; // Получаем полный JSON-объект параметров
  1. Получение конкретного значения по имени атрибута:

var svStation = Stm_OrderOutApi.getObjAttrValue(ropOrder, 'station'); // Получаем значение атрибута 'station'
  1. Получение значения по ID атрибута:

// Получаем ID класса из текущей выборки
var idvClass = selection.getVar('idClass'); // Получим id класса
// Находим ID атрибута по мнемокоду 'station' для указанного класса
var idvAttrStation = Btk_AttributeApi.findByMnemoCode(idvClass, 'station');
// Получаем значение атрибута для указанного заказа
var svStationById = Stm_OrderOutApi.getObjAttrValue(ropOrder, idvAttrStation);

Установка значений атрибутов:

  1. Установка по имени атрибута — передать название класса и название атрибута:

Stm_OrderOutApi.setObjAttrValue(ropOrder, 'station', "Новая станция");
  1. Установка по ID атрибута:

// Получаем ID класса из текущей выборки
var idvClass = selection.getVar('idClass');
// Находим ID атрибута по мнемокоду 'station' для указанного класса
var idvAttrStation = Btk_AttributeApi.findByMnemoCode(idvClass, 'station');
// Получаем значение атрибута для указанного заказа
var svStationById = Stm_OrderOutApi.getObjAttrValue(ropOrder, svStationById);
Stm_OrderOutApi.setObjAttrValue(ropOrder, svStationById, "Новое значение"); // Установка значения для атрибута с указанным ID

Изменение значений#

Чтобы изменить значение в строке, используйте специальные методы-сеттеры. У каждого класса свои сеттеры (смотрите в методах API):

// Меняем номер документа
Stm_OrderOutApi.setsNumDoc(ropOrder, "НОВЫЙ-001");

// Меняем клиента
Stm_OrderOutApi.setidClient(ropOrder, 12345L);

Поиск по мнемокоду#

Часто нужно получить ID по коду (например, код способа доставки):

// Получаем ID способа доставки "ЖД"
var idvZHD = Bs_DeliveryMethodApi.findByMnemoCode('ZHD');

Внимание

код чувствителен к регистру! „ZHD“ и „zhd“ — разные коды.

Пример полного скрипта:

// 1. Получаем ID из текущей выборки
var idvOrder = selection.getVar("id");

// 2. Загружаем строку заказа
var ropOrder = Stm_OrderOutApi.load(idvOrder);

// 3. Получаем атрибуты
var svNumDoc = ropOrder.sNumDoc; // Номер
var idvStationEndJson = Stm_OrderOutApi.getObjAttrValue(ropOrder, 'idStationEndJson');

// 4. Меняем номер
Stm_OrderOutApi.setsNumDoc(ropOrder, "НОВЫЙ-002");

// 5. Ищем ID способа доставки
var idvDelivery = Bs_DeliveryMethodApi.findByMnemoCode('ZHD');

Доступ к универсальным характеристикам#

Помимо объектных характеристик, к классам могут быть подключены универсальные характеристики (UC). Доступ к ним осуществляется через ClassApi:

  • ClassApi.getUniCharValue(rop, "CharName") — получение по системному имени.

  • ClassApi.getUniCharValue(rop, idAttr) — получение по ID атрибута.

Примечание

Значения UC также могут быть null. Перед использованием применяйте проверку isNotNull() или .nvl().

Преобразование типов данных#

Метод

Пример использования

.asJLong()

"123".asJLong()

.toLong()

"456".toLong()

.toInteger()

"789".toInteger()

.toDouble()

"12.34".toDouble()

.toBigDecimal()

"123.45".toBigDecimal()

.asDate()

"2024-01-01".asDate()

.toDate("формат")

toDate("01.01.24", "dd.MM.yy")

.toString()

123.toString()

.asString()

321.asString()

.asList()

sql("SELECT...").asList()

.asSingle()

sql("SELECT...").asSingle()

.asScala()

[1,2,3].asScala()

.asJava()

scalaSeq.asJava()

.toJObject()

toJObject('{"id":1}')

Работа с датами#

Метод

Описание

Пример

getFirstDayOfMonth

Возвращает дату начала месяца от текущей даты

var a = getFirstDayOfMonth(); var b = getFirstDayOfMonth('27.01.2025 12:42:10');

getFirstDayOfPeriod

Возвращает первый день указанного периода

var a = getFirstDayOfPeriod(sysDate(), 'M'); var b = getFirstDayOfPeriod('27.01.2025 12:42:10', 'Q');

getLastDayOfMonth

Возвращает дату конца месяца от текущей даты

var a = getLastDayOfMonth(); var b = getLastDayOfMonth('27.01.2025 12:42:10');

getLastDayOfPeriod

Возвращает последний день указанного периода

var a = getLastDayOfPeriod(sysDate(), 'M'); var b = getLastDayOfPeriod('27.01.2025 12:42:10', 'Q');

nanoTime

Получить значение System.nanoTime()

var a = nanoTime();

sysDate

Возвращает текущую дату

var a = sysDate();

toDate

Переводит строку в дату по указанному формату

var a = toDate("27.02.2020 12:42:10"); var b = toDate("27.02.2020 12:42:10", "dd.MM.yyyy HH:mm:ss");

truncDate

Получение даты на начало дня от переданной

var a = truncDate(sysDate());

truncYear

Получение даты на начало года от переданной

var a = truncYear(sysDate());

-

Вычитает из даты указанное количество дней

var dYesterday = sysDate() - 1;

+

Добавляет к дате указанное количество дней

var dTomorrow = sysDate() + 1;

Работа в контексте выборки#

Контекст выборки (JexlSelScript) расширяет контекст бизнес-логики возможностью работы с выборками и пользовательским интерфейсом. Используется в тех случаях, когда необходимо получить данные из полей для пользовательского ввода.

Метод

Описание

Пример использования

varExists(name)

Проверяет существование переменной в текущей и мастер-выборках

if (varExists("client_id")) { ... }

selfVarExists(name)

Проверяет существование переменной только в текущей выборке

if (selection.selfVarExists("temp_value")) { ... }

getVar(name)

Получает значение переменной из текущей или мастер-выборки

var id = selection.getVar("doc_id").asLong();

getSelfVar(name)

Получает значение только из текущей выборки

var code = selection.getSelfVar("product_code");

setVar(name, value)

Устанавливает значение переменной (ищет в иерархии выборок)

selection.setVar("status", "approved");

setSelfVar(name, value)

Устанавливает значение только в текущей выборке

selection.setSelfVar("comment", "Не заполнено");

addVar(name, value, FieldType)

Добавляет новую переменную в текущую выборку

selection.addVar("id", 1, FieldType.ftFloat());

newForm()

Создает новую форму

Act_DocEdit.newForm().params(...).open();

.form()

Возвращает форму текущего контекста

selection.form();

.opers('Операция')

Возвращает указанную операцию для дальнейшего выполнения

selection.opers("CREATESTMORDERIN");

.execute()

Выполняет ранее полученную операцию

selection.opers("CREATESTMORDERIN").execute();

Работа с формой выборки#

Создание и настройка формы:

var res = Btk_ClassAvi // Класс, предоставляющий форму выбора
.list() // Инициализация формы списка (табличное отображение)
.newForm() // Создание новой формы
.params({ // Передача параметров в форму в виде мапы
    "one": 1,
    "two": 2,
    "three": 3,
    "more": "many more"
})
.locates({"id": 146800}) // Выбор строки
.results(["id", "idClass"]) // Какие поля вернуть после выбора
.openLookup(); // Открытие окна

Метод

Описание

.list()

Форма будет отображаться как таблица (список записей). Возможные отображения можно посмотреть в обозревателе проекта в классе с расширением Avi

.newForm()

Создает новую формы

.params()

Передает параметры в форму (могут использоваться для фильтрации/логики)

.locates()

Установка строки на активную

.results()

Задает поля, которые вернутся после выбора

.openLookup()

Открывает окно выбора

.findSelection('Отображение')

Ищет и возвращает выборку, содержащую указанное отображение

.baseRep()

Возвращает ссылку на объект, к которому был вызван метод

Пример: Поиск и выполнение операций в связанной выборке

Демонстрирует, как найти выборку, связанную с конкретным документом, и выполнить в ней операцию.

var sel = selection.form() // получает форму по выделенному элементу
.findSelection(Stm_OrderOutAvi.Card() // Ищет и возвращает **выборку**, содержащую указанное отображение
.baseRep()); // возвращает базовое представление объекта (ссылку)

if (sel != null) { // если выборка найдена, то выполняет действие
    sel.opers("CREATESTMORDERIN").execute(); // выполняет переданную операцию
}

Для работы с текущей выборкой можно использовать сокращенный синтаксис:

selection.opers("CREATESTMORDERIN").execute();

Обработка результата:

if (res.getLookupResult() == LookupResult.ok()) {
    // Пользователь выбрал значение и нажал "OK"
    for(var i: 1 .. res.size()) { // Цикл по всем выбранным записям
        dialogs.showMessage("id " + res.getData(i, 0) + " idClass " + res.getData(i, 1));
    }
} else {
    // Пользователь закрыл форму или нажал "Отмена"
    dialogs.showMessage("Значение не было выбрано");
}
  • res.getLookupResult() — проверяет, как закрыли форму:

    • LookupResult.ok() — нажали «Выбрать»;

    • LookupResult.cancel() — нажали «Отмена» или закрыли окно.

  • res.size() — количество выбранных записей (если форма поддерживает множественный выбор).

  • res.getData(i, 0) — доступ к данным:

    • i — номер строки (начинается с 1);

    • 0 — индекс поля (соответствует порядку в .results([«id», «idClass»])).

Пример работы с мастер-выборками:

// Получаем значение из атрибута "id" выборки, приводим его к типу NString и пишем в переменную idTree
var idTree = getVar("id").asNString();

// Получаем атрибут DGLOBALENDDATE из мастер-выборки
var dEndDate = getVar("super$DGLOBALENDDATE").asNDate();

// Вызываем метод из пакета с передачей параметров
// Обратите внимание, для обращения к Api или пакетам используются их короткие имена (без скобок)
var fltCond = Act_UniversalReportPkg.getUniFilterCondByIdTree(idTree, dEndDate);

// Вызывается ещё один метод, возвращающий объект scala-класса immutable.Map[NString, Any]
var filters = Act_UniversalReportPkg.getFilterValues(idTree);

/* Определение Map-ы внутри jexl-скрипта. Отметим, что Map внутри jexl и объект scala-класса
Map (неважно mutable или immutable) - это разные объекты. Наиболее важным
фактом является то, что передать scala-объект Map, полученный в предыдущей
строке,
в пакетный метод, принимающий scala-объект Map, в jexl-скрипте напрямую нельзя,
именно поэтому приходится получать значения из переменной filters,
перезаписывать
их в jexl-Map param и потом передавать param в scala-метод. */

var param = {
    "flt_idDepOwner" : filters['flt_idDepOwner'],
    "flt_idAcc" : filters['flt_idAcc'],
    "flt_dFrom" : filters['flt_dFrom'],
    "flt_dTo" : filters['flt_dTo'],
    "flt_idAdjustMethod" : filters['flt_idAdjustMethod'],
    "flt_idAccCor" : filters['flt_idAccCor'],
    "uniFilterCondition_dz": fltCond
};

// Открываем новую форму с переданными параметрами
Act_TransAvi.defList().newForm().params(param).open();

Мастер-выборки:

  • Доступ через префикс super$.

  • Пример: getVar("super$PARENT_ID").

Типизация:

  • Используйте .asString(), .asDate() для явного преобразования.

  • Для чисел: .asBigDecimal(), .asJLong().

Дополнительные методы работы с формой выборки#

Открывает мастер пользовательского ввода по указанному идентификатору формы:

Btk_WizardLib().launch(getSelfVar("id").asNLong); // В качестве параметра передается id формы.

Работа с SQL#

Для работы с SQL используются команды:

  1. Для запросов на чтение:

sql(sqlText:String)
  1. Для запросов на запись:

tsql(sqlText:String).execute()

Методы обработки для sql:

Метод

Описание

Пример

.asList()

Вернуть список записей

sql("SELECT * FROM users").asList()

.asSingle()

Вернуть одну запись

sql("SELECT * FROM users WHERE id=1").asSingle()

Методы обработки для tSql:

Метод

Описание

Пример

.execute()

Выполнить запрос

tsql("DELETE FROM temp").execute()

Примеры:

Простые запросы:

// Чтение
var activeUsers = sql("SELECT name FROM users WHERE is_active=true").asList();

// Запись
tsql("UPDATE orders SET status='done' WHERE id=42").execute();

Обработка результатов:

// Вывод имен пользователей
sql("SELECT name FROM users").foreach(row -> {
    logInfo("User: " + row.name);
});

// Подсчет суммы
var total = 0;
sql("SELECT amount FROM payments").foreach(p -> {
    total = total + p.amount;
});

Параметризация:

var productId = selection.getVar('id');
var product = sql("SELECT * FROM products WHERE id=${productId}").asSingle();

var productId = selection.getVar('id');
var sSqlText = ''; // объявляем переменную, в которой будем собирать sql-выражение
sSqlText = "SELECT * FROM products WHERE id="; //
sSqlText += toString(productId);
sSqlText += "\r\n order by id";
var product = sql(sSqlText).asSingle();

var productId = selection.getVar('id');
var product = sql(`
    SELECT *
    FROM products
    WHERE id=${productId}`)
.asSingle();

Особенности работы с JexlSqlRow#

Результат sql().asList() возвращает список объектов типа JexlSqlRow.

Доступ к данным осуществляется следующими способами:

  • row.fieldName — по имени колонки из SELECT;

  • row.getValue("fieldName") — безопасный доступ (рекомендуется при динамических именах);

  • row.containsKey("fieldName") — проверка наличия поля перед обращением;

Примечание

Поля в JexlSqlRow формируются строго из запроса. Обращение к несуществующему полю или к полю со значением NULL через точечную нотацию вызовет ошибку выполнения скрипта.

Поведение NULL при интерполяции#

JEXL-интерполяция ${variable} преобразует значение null в пустую строку "", а не в SQL-NULL. Выражение WHERE id=${nullField} сгенерирует WHERE id=, что вызовет синтаксическую ошибку PostgreSQL.

Перед подстановкой в SQL всегда проверяйте значение на null:

if (row.fieldName.isNotNull) {
sql("SELECT * FROM table WHERE col=${row.fieldName}").asList()

Либо используйте параметризованный запрос через on(Symbol("param") -> value).


## Дополнительные методы

| Метод | Описание | Пример использования |
|-------|----------|---------------------|
| `lpad(str, len, ch)` | Дополнение строки слева | `lpad("5", 3, "0") → "005"` |
| `rpad(str, len, ch)` | Дополнение строки справа | `rpad("5", 3, "0") → "500"` |
| `flush()` | Синхронизация с БД | `flush()` |
| `commit()` | Подтверждение транзакции | `commit()` |
| `nvl(a, b)` | Возвращает a, если не null, иначе b | `nvl(var, "default")` |
| `isNull(x)` | Проверка на null | `isNull(obj)` |
| `isNotNull(x)` | Проверяет, что переданное значение не null | `isNotNull(obj)` |
| `pgArrayToNLongList` | Конвертация массива в список | `pgArrayToNLongList(arr)` |
| `parseId(gid: Object): Long` | Получение идентификатора объекта из NGid-а Работает для строкового или NGid-значения | `var sGid = "14323/44334"; var id = parseId(sGid);` |
| `parseIdClass(gid: Object): Long` | Получение идентификатора класса из NGid-а Работает для строкового или NGid-значения | `var sGid = "14323/44334"; var idClass = parseIdClass(sGid);` |
| `toJRops(rops: Traversable[Rop]): JexlToJRops` | Обход записей, возвращенных объектным запросом, например byParent Выполняет запрос на чтение к базе данных и позволяет обойти записи | `var l = toJRops(Btk_SomeEntityApi.byParent(rop)).asList(); for(r:l){ logInfo(r.id); logInfo(r.sSystemName); }` |
| `toJObject(json: String): JexlToJObject` | Парсинг json-объекта | `var jData = toJObject('{"id": 1}'); logInfo(jData.getLong("id"));` |

## Работа с BTS процедурами

**Переход в раздел процедур:**

Для того чтобы открыть перечень BTS-процедур, перейдите в **Настройки системы** → **Настройки и сервисы** → **Процедуры**. Здесь можно просмотреть различные варианты существующих процедур. Можно перейти в карточку любой процедуры и посмотреть, какие действия там описаны.

Выберите в фильтре **Тип: Процедура для сбыта** и создайте новую тестовую процедуру, нажав кнопку **Создать**. Введите наименование и код процедуры.

**Написание JEXL-кода:**

Предположим, мы хотим рассчитать некоторую формулу на основе входящих параметров. Чтобы процедура вернула значение, объявим раздел с результатом и вернем соответствующее значение. Объявим входные параметры и расчетную формулу:

var nvParam1 = npInParam1; var nvParam2 = npInParam2; var nvParam3 = npInParam3; var nvSum = (npInParam1 + npInParam2) * npInParam3;

// Для того чтобы процедура вернула значение, добавим возврат результата: return nvSum;

Сохраните код.

**Вызов процедуры через JEXL-редактор:**

Перейдите в отдельный редактор JEXL. Объявите служебную функцию для типизации данных. Данная функция будет возвращать тип данных scala.Tuple2, состоящий из двух переменных.

var tuple2 = (v1, v2) -> { return new(scala.Tuple2, v1, v2); };

Заведите массив параметров, в котором запишите входящие значения. В нем будет объявлен массив Scala (это делается за счет указания последнего элемента с троеточием). Первые три элемента будут объявлены с помощью функции tuple2. В каждом таком элементе массива будет указано название параметра и его значение.

var tuple2Params = asScala([ tuple2(«npInParam1», 10l), tuple2(«npInParam2», 125l), tuple2(«npInParam3», 1000l), … ]);

Объявите переменную, в которую при помощи API-функции findByMnemoCode поместите идентификатор ранее созданной процедуры:

val idvBtsProcedure = Bts_ProcedureApi.findByMnemoCode(Sale_Test1);

Далее вызовите конструкцию для расчета значения BTS-процедуры и запишите результат в переменную. Для этого используйте API-метод Bts_ProcedureLib, передав в него:
- идентификатор процедуры;
- массив параметров;
- дополнительный контекст выборки для расчета.

var nvSumCalc = Bts_ProcedureLib.execById(idvBtsProcedure, tuple2Params, selection.coreRep());

Метод `Bts_ProcedureLib.execById` ожидает параметры в формате, который понимает Scala, поэтому мы используем кортеж. Кортежи здесь — это "мост" между JEXL и Scala, обеспечивающий четкую, безопасную и удобную передачу параметров.

Верните результат процедуры и выведите его на экран.

dialogs.showMessage(toString(nvSumCalc));

Аналогичным образом можно создавать и более сложные BTS-процедуры.

## Работа с мониторингом сессий сервера приложений

Система автоматически ведет метаинформацию о сессиях всех пользователей. Доступ к этой информации организован следующим образом:

**Настройки системы** → **Сервис** → **Инструменты** → **Мониторинг сессий сервера приложений**.

В списке отображаются все активные сессии с указанием последнего выполненного действия для каждого пользователя.

Для работы с сессионными данными текущего пользователя предусмотрены следующие методы:

Получение текущего действия:

session.applicationInfo().action();

Обновление информации о действии:

session.applicationInfo().action_$eq(«Значение текущего действия»);

Пример использования:

for (ropWW: ropaIntWar) { session.applicationInfo().action_$eq(Phosagro_SB0205_NEW - ВП - ${toString(ropWW.gid)}); Stk_InternalWarrantApi.setdExecDateOut(ropWW, cDate); session.applicationInfo().action_$eq(Phosagro_SB0205_NEW - выполняем ВП - ${toString(ropWW.gid)}); Stk_InternalWarrantApi.setidStateOut(ropWW, idvStateIntWar); session.applicationInfo().action_$eq(Phosagro_SB0205_NEW - Создаем РСО); var ropWarOut = Stk_WarrantOutApi.createWarrantOutByInternalWarrant(ropWW); // Заполняем даты исполнения Stk_WarrantOutApi.setdDocDate(ropWarOut, cDate); Stk_WarrantOutApi.setdExecDate(ropWarOut, cDate); // Выполняем РСО session.applicationInfo().action_$eq(Phosagro_SB0205_NEW - выполняем ВП - ${toString(ropWarOut.gid)}); Stk_WarrantOutApi.setidState(ropWarOut, idvStateWarr); };

**Метод setUniCharValue** используется для установки значения универсальной характеристики (универсального атрибута) объекта в системе.

setUniCharValue(rop: ApiRop, idpUniChar: Long, pValue: Any): Unit

| Параметр | Тип (Scala) | Описание |
|----------|-------------|----------|
| rop | Rop | Контекст выполнения операции (объект, к которому применяется изменение) |
| idpUniChar | Long | Идентификатор универсальной характеристики |
| pValue | Any | Новое значение характеристики (может быть Long, String и др) |

Пример использования:

// 1. Получаем GID значения «.» из справочника val gidChr = sql(«»» SELECT r.gid FROM Btk_UniversalReference r JOIN btk_objecttype b ON r.idobjecttype = b.id WHERE r.sSystemname = „.“ AND b.scode = „ur_O2C_sort_type“ «»»).asSingle();

Stm_OrderOutApi.setUniCharValue(rop, „O2C_sort_type“, gidChr.gid);

## Работа с печатью

Пользователь может:
- Сформировать отчёт по его системному имени.
- Запустить JEXL-скрипт печатной формы, привязанной к типу объекта.

Создание отчета происходит с помощью следующего метода:

Rpt_Lib.createReportExJexl( reportName: String, reportVersionDate: Date, postBuildAction: PostBuildAction, propertyMap: Map[String, Any], idpObjectTypePrintForm: NLong = None.nl ): Unit

| Параметр | Тип (Scala) | Описание |
|----------|-------------|----------|
| idpObjectTypePrintForm | Long | id ПФ на типе объекта. Может быть null |
| reportName | String | Имя отчета |
| reportVersionDate | Date | Дата |
| postBuildAction | PostBuildAction | Действие, которое необходимо произвести после заполнения отчёта |
| propertyMap | Map[String, Any] | Карта входящих параметров |

Пример использования:

var idvOrderClass = selection.getVar(«idClass»); var idvOrder = selection.getVar(«id»);

var NLong = function(number) { // локальная функция для преобразования Long в NLong return new («ru.bitec.app.gtk.lang.NLong», number); };

var spReportName = «Stm_InvoiceOut»; var dpReportVersionDate = sysDate(); var vPostBuildAction = session .sbtClassLoader() .loadClass(„ru.bitec.app.gtk.gl.postbuildaction.PostBuildAction“) .design();

var propertyMap = { «idSrcObject» : NLong(idvOrder), «idSrcClass» : NLong(idvOrderClass) };

var idpObjectTypePrintForm = null;

Rpt_Lib.createReportExJexl( spReportName, dpReportVersionDate, vPostBuildAction, asScala(propertyMap), idpObjectTypePrintForm );

**Тип PostBuildAction:**

PostBuildAction — это перечисление (enum) из класса ru.bitec.app.gtk.gl.postbuildaction.PostBuildAction, определяющее действия после построения отчета.

**Доступные значения:**
- `.show()` — загружает отчет на клиент;
- `.save()` — сохраняет отчет;
- `.print()` — загружает отчет на клиент и, если в конфигурации системы включена опция печати (Configuration.Printing.enableNetworkPrinting), печатает отчет на локальном (для сервера) принтере.

**Примечание:**
Для `.print()` поведение зависит от конфигурации сервера. Если печать не настроена, отчет просто загружается на клиент.

**Особенности:**
- Для работы с ID используется тип NLong (внутренний класс системы).
- asScala() преобразует Java-коллекции в Scala-совместимые.
- Если idpObjectTypePrintForm = null — отчёт строится по reportName.