* Язык скриптов

Введение

Язык скриптов создан для того чтобы дать возможность разработчикам проектов самим писать программы и выполнить их из Домино.

Одно из прямых значений слова скрипт (script) – это ‘сценарий поведения’. В Домино нет необходимости описывать весь алгоритм работы программы на языке программирования. Стандартный алгоритм Домино подходит для подавляющего большинства разрабатываемых проектов. Различие между проектами заключается в поведении программы в некоторых ключевых местах. Проектировщик помещает в выбранное ключевое место свою процедуру (скрипт), тем самым изменяя стандартный алгоритм на требуемый сценарий.

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

Язык скриптов применяется для написания выражений, функций и процедур. С помощью языка скриптов проектируются сложные выборки данных, которые можно использовать в видах просмотра и отчетах.

Язык скриптов воплощает в себе идеи структурного программирования, модульности и наглядного изображения алгоритмов.

В структурном программировании принято отражать внутреннюю структуру алгоритма в структуре текста программы. В обычных языках программирования это достигается сдвигами строк. В Домино иерархия операторов программы отображается в виде дерева. И благодаря наглядности изображения дерева вложенность операторов видна явно. Более того, часть дерева можно раскрыть дальше вниз или, наоборот, скрыть, что делает просмотр процедур еще более удобным. Такое изображение дерева проекта позволяет понять алгоритмы даже тем проектировщикам, кто не имеет опыта программирования на других языках.

Ключевая идея принципа модульности состоит в том, чтобы заранее заготовить набор часто встречающихся операций, сохранить этот набор в специальном месте (библиотеке) и избежать необходимости повторного программирования этих операций всякий раз, когда они потребуются. В Домино возможна реализация процедур и функций как в динамических библиотеках (dll), так и на языке скриптов. Процедуры и функции описываются в специальных разделах проекта.

Основные конструкции языка

Программа на языке скриптов представляет собой иерархическую последовательность элементов проекта. Иерархия определяет вложенность конструкций языка, а последовательность сверху вниз по дереву проекта задает порядок выполнения конструкций.

В программе существуют конструкции двух видов: данные и операции. Иначе их называют операнды (данные) и операторы (операции).

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

 

Основные конструкции языка

Основные конструкции языка

Данные

Принято различать два вида представления данных: константы и переменные.

Константа имеет постоянное значение, не изменяемое при выполнении программы.

Переменная – это данное, значение которого может меняться в процессе выполнения программы. Переменные всегда имеют имена. Значения переменных устанавливается в операторе присваивания.

Для выделения данных с одинаковыми характеристиками вводится понятие типа данных. Тип данных определяет множество значений и операции, которые могут быть применимы к этим значениям. Каждая переменная имеет единственный тип, который можно узнать из ее описания. Любая операция требует операндов определенного типа и выдает результат тоже определенного типа. В Домино типы данных подразделяются на две группы. Первую группу составляют стандартные типы данных. Вторая группа состоит из производных типов, которые создаются на основе стандартных.

Стандартные типы данных

На рисунке показаны описания стандартных типов данных в дереве проекта.

image-1648656895804.png

Описания всех типов данных расположены в проекте в библиотеке ‘Системная область’ в разделе ‘Классификация значений’. Стандартные типы находятся непосредственно в папке ‘Стандарты’. В остальных папках размещены производные типы. Для описания стандартного типа данных применяется элемент проекта с типом ‘Базовый класс значения’.

Основное преимущество чисел типа number – возможность явного указания десятичной точности результата при выполнении операций.  Это позволяет избежать проблемы накопления ошибок округления. Второе преимущество - большое количество значащих разрядов.

Остальные типы данных являются производными от этих стандартных.

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

В проекте описано множество производных типов данных, и этот список постоянно расширяется.

image-1648656914951.png

В папке ‘Объектные’ расположены производные типы, используемые для переменных, содержащих ссылки на объекты БД. Так тип ‘Объект’ может быть использован для любого из объектных типов. Если точно известен объект БД , то лучше применять типы Пользователь, Каталог, Партнер, Продукт, Документ, Строка, Проводка, Протокол, Контрольная точка. Элементы проекта, описывающие эти типы, ссылаются на соответствующие таблицы БД.

Для хранения списков объектов применяются типы, производные от стандартного типа UIDSET.

image-1648656931694.png

В папке ‘Системные’ находится описание типа данных ‘Код объекта БД’. Это строка длиной 20 символов. При описании параметров таблиц коды объектов имеют данный тип.

image-1648656947347.png

В папке ‘Проектные’ перечислены различные типы проектных элементов. Все они произведены от типа UID.

image-1648656963293.png

Папка ‘Данные’ содержит описания типов, с которыми работают внешние редакторы текстов (Word, Excel).

image-1648656978409.png

В папке ‘Числовые’ перечислены различные числовые типы. Типы различаются размером и точностью.

image-1648656993684.png

Строчные типы данных, помещенные в папку ‘Строчные’, различаются только ограничениями на длину (что важно при описании полей БД и при заполнении формы ввода) и форматом отображения колонки в виде просмотра.

image-1648657012694.png

Типы ‘Дата+Время’ и ‘Дата’ отличаются лишь форматом отображения.

image-1648657027706.png

Папка ‘Счета’ содержит типы, выделенные из прочих проектных типов данных.

Ограничения, наложенные на производные типы, влияют на формат создаваемых полей БД, формат отображения данных в колонках видов просмотров и на округление числовых данных при расчетах.

Значение NULL

При выполнении арифметических операций и операций преобразования типов могут происходить ошибки (переполнение, деление на 0 и т.п.). Выполнение программы при этом не должно прерваться, так как такие ошибки не фатальны. Если возникает подобная ошибка, то операция возвращает специальное значение ‘пусто’. 

NULL - специальное значение ‘Пусто’.

Свойства этого значения следующие:

Разработчики нередко используют NULL значение  в качестве результата выполнения функций.

В ДОМИНО понятие NULL значения привнесено из SQL. В SQL значение NULL означает отсутствие значения поля, и NULL-значение может размещаться в поле любого типа.

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

Если операция производится над данными разных типов, то производится автоматическое преобразование данных к одному типу.

Правила преобразования типов следующие:

[число] операция [целое] ->> [число]

[целое] операция [число] ->> [целое]

 

Основные конструкции языка

Переменные

Переменная – это данное, значение которого может меняться в процессе выполнения программы. Переменные всегда имеют имена. Переменными в языке скриптов могут быть:

Глобальные переменные

Глобальный – общий, универсальный.

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

Область видимости глобальной переменной может быть специально ограничена настройщиком проекта.

Обычно глобальные переменные задаются либо в библиотеке ‘Системная область’, раздел ‘Параметры’, папка ‘Глобальные переменные’, либо в библиотеке ‘!Базовый набор’, раздел ‘Параметры’, папка ‘Глобальные переменные’.

image-1648658927312.png

Объяснение предназначения каждой из этих переменных не является целью данного руководства, поэтому лишь замечу, что элементы проекта, описывающие глобальные переменные имеют иконки разного цвета. Цвет иконки зависит от статуса проектного элемента. Если проектировщик присвоил глобальной переменной статус ‘Экспортный (Публичный’), то отображается иконка зеленого цвета. Для непубличных переменных используется иконка синего цвета.

image-1648658947679.png

На данном рисунке в списке глобальных переменных из библиотеки ‘!Базовый набор’ находится подстановка переменной ’Текущее ЦФО’. Определение глобальной переменной ’Текущее ЦФО’ находится выше – в библиотеке ‘Системная область’, что видно на предыдущем рисунке. Подстановку глобальной переменной применяют для назначения переменной начального значения.

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

При завершении работы Домино текущие значения глобальных переменных сохраняются в специальном файле (этот файл называют ‘профиль’). При последующем старте Домино глобальным переменным присваивают сохраненные в профиле значения. Значение из профиля имеет приоритет над значением, заданным в данном атрибуте.

Выражение рассчитывается после присваивания начального значения, указанного в предыдущем атрибуте, и после считывания значения из профиля. Т.е. если для глобальной переменной задан атрибут ‘Выражение’, то значение глобальной переменной при старте Домино всегда будет рассчитано как результат указанного выражения.

Некоторые функции и процедуры используют глобальные переменные как неявные входные и выходные параметры. Например, функции, расположенные в библиотеке ‘Системная область’, раздел ‘Параметры’, папка ‘Стандартные’, папка ‘Функции работы с датой’, папка ‘Начало/конец дня для глобальных дат’:

image-1648658969281.png

Другой пример использования глобальной переменной:

image-1648658984838.png

Функция для расчета курса получает дату из документа. UID требуемого документа считывается из глобальной переменной ‘Документ’.

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

image-1648659002304.png

В форме описано специальное поле для глобальной переменной ‘Партнер для документа’. Это поле является скрытым, т.е. не отображается на экране. Для заполнения этого поля (и, следовательно, глобальной переменной) используется выражение, возвращающее значение предыдущего поля формы. Таким образом проектировщик копирует введенное значение контрагента документа в глобальную переменную. Далее можно использовать эту переменную в процедурах и функциях, вызываемых из формы.

Контекстные переменные

Контекст (от лат. Contextus - тесная связь, соединение) –законченный в смысловом отношении отрывок текста, необходимый для определения смысла входящего в него слова или фразы.

Замысел появления контекста в Домино заключался в том, чтобы с помощью контекста точнее понимать смысл действий программы в отношении обрабатываемых данных. Иными словами, проектировщик, анализируя контекст, понимает какие именно объекты обрабатываются в рассматриваемом  месте программы. Для того чтобы контекстом было удобно пользоваться, контекст должен содержать как можно меньше частей. Этого можно добиться, если для каждого объекта завести свою переменную, в которую записывать UID текущей записи объекта.

Контекст в Домино – набор значений специальных (контекстных) переменных, содержащих идентификаторы текущих записей основных объектов БД.

Контекстные переменные перечислены в библиотеке ‘Системная область’, раздел ‘Параметры’, папка ‘Контекстные переменные’.

image-1648659021421.png

Список содержит контекстные переменные по всем объектам.

В папке ‘Прочие’ находятся дополнительные контекстные переменные. Дополнительные контекстные переменные были созданы до того, как в Домино появились локальные переменные и формальные параметры. В настоящее время имеются более удобные и понятные средства для реализации тех задач, в которых могут потребоваться эти переменные, поэтому использование дополнительных контекстных переменных не рекомендуется.

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

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

Контекстным переменным отводится следующая роль.

Несмотря на то, что на уровне ядра Домино имеется полная поддержка контекстных переменных, использование контекста не является общим для всех компонент программы. Контекстные переменные поддерживаются во всех видах просмотра. Разработчики других компонент (форм, методов акцепта, процедур и т.д.) посчитали излишним обеспечение контекста в своих компонентах.

Рассмотрим подробнее механизм формирования контекста.

Набор значений контекстных переменных, заполненных при старте Домино, называется глобальный контекст. Глобальный контекст существует автономно от начала и до конца работы программы.

При вызове компоненты (процедуры, функции, отчета), если это предусмотрено разработчиком компоненты, создается копия глобального контекста.  Такая копия называется локальным контекстом. Локальный контекст присоединяется к списку локальных переменных компоненты, и, таким образом, контекстные переменные становятся доступными внутри компоненты. Компонента работает только со своей (локальной) копией контекста и не может изменить контекст других компонент или глобальный контекст.

Не рекомендуется создавать контекстные переменные без острой необходимости, поскольку обслуживание контекста требует значительных ресурсов.

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

image-1648659040651.png

Обычно применяется следующая цепочка вызовов: вид просмотра документов –> форма документа –>  вид просмотра строк. При формировании заголовка  окна, содержащего вид просмотра строк, удобно использовать контекстную переменную <<Документ>>, поскольку эта переменная содержит UID именно того документа, строки которого отображаются.

Локальные переменные

Локальная переменная – переменная действующая только внутри процедуры, функции или выражения.

При описании процедуры (функции, выражения) можно указать необходимые локальные переменные в разделах ‘Локальные переменные’ или ‘Формальные параметры’. Здесь же задаются начальные значения переменных.

При запуске процедуры (функции, выражения) ядро программы создает указанные локальные переменные и присваивает им начальные значения. По завершении процедуры все локальные переменные удаляются.

Пример описания локальных переменных для процедуры:

image-1648659062645.png

Для процедуры указаны четыре локальные переменные. Две переменные расположены в разделе  для описания формальных параметров. Для одной переменной задано начальное значение.

Если локальные переменные расположены в разделе ‘Формальные параметры’, то это означает, что процедура имеет соответствующие параметры для вызова.

Значения формальных параметров, указанные при вызове процедуры, имеют приоритет над начальными значениями в описании. Т.е. при старте процедуры в локальную переменную (являющуюся формальным параметром) будет записано значение при вызове, а если таковое отсутствует, то будет записано начальное значение из описания.

image-1648659078129.png

Функция ‘День’ возвращает номер дня недели. При вызове функции требуется указать значение формального параметра ‘Дата’.

image-1648659095108.png

При вызове функции 'День' формальный параметр ‘Дата’ заполняется датой документа.

 

Основные конструкции языка

Операции

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

В языке скриптов имеются операции всех перечисленных видов.

Оператор Присвоить

Операция присваивания применяется для записи значения в переменную. Значение может быть указано либо явно (с помощью константы), либо в виде выражения. Во втором случае сначала будет рассчитано выражение, затем полученный результат будет занесен в переменную. Также произойдет приведение типа результата выражения к типу переменной.

image-1648745571065.png

Разные варианты присваивания значений переменным (константы, результата выражения).

Операции, используемые  в выражениях

Выражение состоит из одного или нескольких операндов и знаков операций. Операндами выражения могут быть константы, локальные переменные, глобальные и контекстные переменные, другие выражения, а также - функции. Операции выполняются над операндами в порядке их описания. Для изменения порядка выполнения операций используются вложенные выражения.

Подробнее о выражениях написано ниже.

Истинное и ложное значения операндов

Для логических операций имеются понятия истинного и ложного значений. Коротко истинное значение называют TRUE, а ложное – FALSE.

Считается, что числовой операнд имеет истинное значение, если число не равно ни 0, ни  NULL. Числовой операнд имеет ложное значение в противном случае (т.е. равен либо 0, либо NULL).

Операнд типа Строка имеет истинное значение, если строка не пустая. Операнд типа Строка имеет ложное значение в противном случае. Хвостовые пробелы при сравнении строк игнорируются.

Операнд типа UID объекта имеет истинное значение, если UID не равен NULL. Операнд типа UID объекта имеет ложное значение, если UID равен NULL.

При написании выражений применяются следующие операции:

Если между строчными операндами не указать операцию, то программа выполнит такую запись как конкатенацию строк.

Для переменных типа UIDSET (список уникальных идентификаторов) перечисленные операции имеют следующий смысл:

Оператор Выбора и Условный оператор, используемые в выражениях, отличаются от  операторов IF и CASE, являющихся отдельными конструкциями языка. Операторы для выражений имеют более простой синтаксис. 

Условный оператор (Оператор IF)

‘Условный оператор’ позволяет указать, какую из двух ветвей программы выполнить в зависимости от значения (истинное или ложное) указанного условия.

Структура:

Условие - это переменная (выражение или функция), имеющая либо истинное, либо ложное значение.

THEN - последовательность операторов данного раздела выполняется если условие имеет истинное значение.

ELSE - последовательность операторов данного раздела выполняется если условие имеет ложное значение.

Обязательное наличие сразу обоих разделов THEN и ELSE не требуется.

Для разделов THEN и ELSE рекомендуется заполнять поле ‘Описание’, которое будет высвечено в качестве комментария к оператору IF.

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

image-1648745631039.png

Если переменная ‘Устройство вывода отчетов’ имеет значение ‘В файл’, то выполняется группа операторов, расположенная в разделе THEN. В противном случае выполняются операторы раздела ELSE.

 Оператор выбора (Оператор CASE)

‘Оператор выбора’ позволяет указать, какую из нескольких ветвей программы выполнить в зависимости от значения указанного условия.

Структура:

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

OF – значение ключа, под которым описана соответствующая ему последовательность операторов. Значения ключа последовательно сравниваются со значением условия до первого совпадения.

ELSE - Если ни одно из значений ключа не совпало со значением условием, то выполняется последовательность операторов из данного раздела.

Не рекомендуется использовать оператор CASE вместо оператора IF. Данная конструкция удобна для сравнения условия с набором явно заданных констант, классификаторов и кодификаторов.

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

image-1648745686364.png

Функция ‘Месяц по дате’ возвращает название месяца. В условии оператора Выбора задан номер месяца. Значениями ключей являются числа от 1 до 12. Если номер месяца не совпадет ни с одним ключом (видимо на вход функции передана неверная дата), то функция возвращает значение NULL.

Оператор цикла (Оператор WHILE)

‘Оператор цикла’ обеспечивает многократное выполнение последовательности операторов до тех пор, пока выполняется указанное условие. Если условие имеет истинное значение, то последовательность операторов будет повторена. Как только условие примет ложное значение, то управление будет передано оператору, следующему за оператором цикла.

Циклом в языках программирования называют группу операторов, выполняемых многократно. Итерацией называют один проход через цикл.

Структура

Условие - это переменная (выражение или функция), имеющая либо истинное, либо ложное значение. Условие вычисляется в начале каждой итерации.

Блок действий – Последовательность операторов программы, выполняющаяся на каждой итерации цикла.

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

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

image-1648745748911.png

Указанный цикл будет повторен i раз. Счетчик i уменьшается на 1 в начале каждой итерации.

Изменить порядок выполнения цикла можно с помощью операторов CONTINUE, BREAK, EXIT, RETURN.

image-1648745766459.png

Бесконечный цикл прерывается оператором BREAK.

 Оператор продолжить (Оператор CONTINUE)

‘Оператор продолжить’ изменяет последовательность выполнения операторов в зависимости от значения указанного условия. Если условие имеет ложное значение, то оператор CONTINUE не выполняет никаких действий. Если условие имеет истинное значение, то оператор выполняет действия в зависимости от места вызова:

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

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

image-1648745784095.png

Перебираются данные из таблицы. Оператор CONTINUE позволяет пропустить обработку запрещенных записей. Если считанная запись содержится в списке запрещенных, то оператор CONTINUE прерывает обработку текущей записи, и  программа  считывает следующую запись.

Оператор прервать (Оператор BREAK)

‘Оператор прервать’ изменяет последовательность выполнения операторов в зависимости от значения указанного условия. Если условие имеет ложное значение, то оператор BREAK не выполняет никаких действий. Если условие имеет истинное значение, то оператор выполняет действия в зависимости от места вызова:

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

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