Функции, описанные в данной главе, используются для операций над списками. Список представляет собой строковую переменную (типа STRING), содержащую записи, каждая из которых начинается со специального символа (этот символ определяется пользователем). Максимальный размер списка определяется глобальной константой LIST_LENGTH.
Функции обрабатывают списки через VAR_IN_OUT переменные (входы-выходы) – т.е. на вход функции подается исходный список, и на этот же вход возвращается результат его обработки. Такой подход позволяет обрабатывать списки путем прямых манипуляций с памятью ПЛК и является крайне эффективным, так как не требует копирования содержимого списков.
В рамках рассматриваемых примерах в качестве разделителя используется символ ‘&’ (ASCII-код – 16#26).
Примеры списков:
‘&12&345’ – список с двумя записями (’12’ и ‘345’);
‘’ – список без записей;
‘&&&’ – список с тремя пустыми записями;
‘&12&345&&ABC’ – список с четырьмя записями (’12’, ‘345’, пустая запись, ‘ABC’).
Номера записей отсчитываются с единицы (т.е. первая запись списка имеет номер 1).
LIST_ADD
Тип модуля: функция | Переменная | Тип | Описание |
|---|---|---|---|
Входы | SEP | BYTE | ASCII-код символа-разделителя |
INS | STRING | Добавляемая запись | |
Входы-выходы | LIST | STRING(LIST_LENGTH) | Список |
Выходы | LIST_ADD | BOOL | Флаг завершения операции |
Используемые модули | CHR_TO_STRING | ||
Функция LIST_ADD добавляет в конец списка LIST с разделителем SEP запись INS. После выполнения операции выход функции принимает значение TRUE.
Пример
VAR
(* Список с разделителем '&' (ASCII 16#26) *)
List : STRING(OSCAT_BASIC.LIST_LENGTH) := '&12&345';
(* Разделитель *)
Separator : BYTE := 16#26; (* '&' *)
(* Добавляемая запись *)
NewRecord : STRING := 'ABC';
(* Флаг завершения операции *)
Done : BOOL;
END_VAR
(* Вызов функции LIST_ADD *)
Done := OSCAT_BASIC.LIST_ADD(
SEP := Separator,
INS := NewRecord,
LIST := List
);
(*
Результат:
- List = '&12&345&ABC'
- Done = TRUE
Пояснение:
- Исходный список: '&12&345' (записи '12' и '345')
- Добавляем запись 'ABC' в конец
- Новая запись отделяется разделителем '&'
- Итоговый список: '&12&345&ABC' (записи '12', '345', 'ABC')
*)
END_PROGRAM |
LIST_CLEAN
Тип модуля: функция | Переменная | Тип | Описание |
|---|---|---|---|
Входы | SEP | BYTE | ASCII-код символа-разделителя |
Входы-выходы | LIST | STRING(LIST_LENGTH) | Список |
Выходы | LIST_CLEAN | BOOL | Флаг завершения операции |
Функция LIST_CLEAN очищает список от пустых записей. После выполнения операции выход функции принимает значение TRUE.
Пример
VAR
(* Список с пустыми записями *)
List : STRING(OSCAT_BASIC.LIST_LENGTH) := '&12&345&&ABC';
(* Разделитель *)
Separator : BYTE := 16#26; (* '&' *)
(* Флаг завершения операции *)
Done : BOOL;
END_VAR
(* Вызов функции LIST_CLEAN *)
Done := OSCAT_BASIC.LIST_CLEAN(
SEP := Separator,
LIST := List
);
(*
Результат:
- List = '&12&345&ABC'
- Done = TRUE
Пояснение:
- Исходный список: '&12&345&&ABC' (4 записи: '12', '345', '', 'ABC')
- Пустая запись между '&&' удаляется
- Итоговый список: '&12&345&ABC' (3 записи: '12', '345', 'ABC')
*)
END_PROGRAM |
LIST_GET
Тип модуля: функция | Переменная | Тип | Описание |
|---|---|---|---|
Входы | SEP | BYTE | ASCII-код символа-разделителя |
POS | INT | Номер читаемой записи | |
Входы-выходы | LIST | STRING(LIST_LENGTH) | Список |
Выходы | LIST_GET | STRING(LIST_LENGTH) | Прочитанная запись |
Функция LIST_GET возвращает из списка LIST с разделителем SEP запись с номером POS. Нумерация записей начинается с 1.
Пример
VAR
(* Список с записями *)
List : STRING(OSCAT_BASIC.LIST_LENGTH) := '&12&345&ABC&XYZ';
(* Разделитель *)
Separator : BYTE := 16#26; (* '&' *)
(* Номер читаемой записи *)
RecordNumber : INT := 2;
(* Прочитанная запись *)
Record : STRING(OSCAT_BASIC.LIST_LENGTH);
END_VAR
(* Вызов функции LIST_GET *)
Record := OSCAT_BASIC.LIST_GET(
SEP := Separator,
POS := RecordNumber,
LIST := List
);
(*
Результат: Record = '345'
Пояснение:
- Список: '&12&345&ABC&XYZ'
- Записи: 1='12', 2='345', 3='ABC', 4='XYZ'
- POS = 2 → возвращается вторая запись '345'
*)
END_PROGRAM |
LIST_INSERT
Тип модуля: функция | Переменная | Тип | Описание |
|---|---|---|---|
Входы | SEP | BYTE | ASCII-код символа-разделителя |
POS | INT | Позиция для вставки записи | |
INS | STRING | Добавляемая запись | |
Входы-выходы | LIST | STRING(LIST_LENGTH) | Список |
Выходы | LIST_INSERT | BOOL | Флаг завершения операции |
Используемые модули | CHR_TO_STRING | ||
Функция LIST_INSERT добавляет в список LIST с разделителем SEP запись INS. Запись заменяет существующую запись номер POS, при этом существующая и все последующие записи смещаются. Если POS=0, то запись добавляется в начало списка (так же, как и при POS=1). Если значение POS превышает число существующих записей списка, то список дополняется пустыми записями.
После выполнения операции выход функции принимает значение TRUE.
Пример
VAR
(* Список с записями *)
List : STRING(OSCAT_BASIC.LIST_LENGTH) := '&12&345&ABC';
(* Разделитель *)
Separator : BYTE := 16#26; (* '&' *)
(* Позиция для вставки *)
Position : INT := 2;
(* Вставляемая запись *)
NewRecord : STRING := 'NEW';
(* Флаг завершения операции *)
Done : BOOL;
END_VAR
(* Вызов функции LIST_INSERT *)
Done := OSCAT_BASIC.LIST_INSERT(
SEP := Separator,
POS := Position,
INS := NewRecord,
LIST := List
);
(*
Результат:
- List = '&12&NEW&345&ABC'
- Done = TRUE
Пояснение:
- Исходный список: '&12&345&ABC' (записи '12', '345', 'ABC')
- Вставляем 'NEW' в позицию 2
- Запись '345' и последующие сдвигаются вправо
- Итоговый список: '&12&NEW&345&ABC'
*)
END_PROGRAM |
LIST_LEN
Тип модуля: функция | Переменная | Тип | Описание |
|---|---|---|---|
Входы | SEP | BYTE | ASCII-код символа-разделителя |
Входы-выходы | LIST | STRING(LIST_LENGTH) | Список |
Выходы | LIST_LEN | INT | Число записей в списке |
Функция LIST_LEN возвращает число записей в списке LIST с разделителем SEP.
Пример
VAR
(* Список с записями *)
List : STRING(OSCAT_BASIC.LIST_LENGTH) := '&12&345&ABC&XYZ';
(* Разделитель *)
Separator : BYTE := 16#26; (* '&' *)
(* Число записей в списке *)
RecordCount : INT;
END_VAR
(* Вызов функции LIST_LEN *)
RecordCount := OSCAT_BASIC.LIST_LEN(
SEP := Separator,
LIST := List
);
(*
Результат: RecordCount = 4
Пояснение:
- Список: '&12&345&ABC&XYZ'
- Записи: '12', '345', 'ABC', 'XYZ'
- Всего 4 записи
*)
END_PROGRAM |
LIST_NEXT
Тип модуля: ФБ | Переменная | Тип | Описание |
|---|---|---|---|
Входы | SEP | BYTE | ASCII-код символа-разделителя |
RST | BOOL | Сигнал перезапуска блока | |
Входы-выходы | LIST | STRING(LIST_LENGTH) | Список |
Выходы | LEL | STRING(LIST_LENGTH) | Запись списка |
NUL | BOOL | Флаг «прочитаны все записи» |
Функциональный блок LIST_NEXT используется для чтения записей из списка LIST с разделителем SEP. При каждом последующем вызове блока на выход LEL транслируется следующая запись списка. Когда прочитаны все записи (или в списке их нет), выход NUL принимает значение TRUE. По переднему фронту на входе RST происходит перезапуск блока.
Пример
VAR
fbListNext: OSCAT_BASIC.LIST_NEXT;
sList: STRING(OSCAT_BASIC.LIST_LENGTH) := 's34&sAB&1122sTest';
asListElements: ARRAY [1..10] OF STRING(OSCAT_BASIC.LIST_LENGTH);
iPos: INT;
END_VAR
iPos := 0;
fbListNext(LIST := sList, SEP := 16#26);
WHILE NOT fbListNext.NUL AND iPos <= 10 DO
asListElements[iPos] := fbListNext.LEL;
fbListNext(list := sList);
iPos := iPos + 1;
END_WHILE
END_PROGRAM |
LIST_RETRIEVE
Тип модуля: функция | Переменная | Тип | Описание |
|---|---|---|---|
Входы | SEP | BYTE | ASCII-код символа-разделителя |
POS | INT | Номер вырезаемой записи | |
Входы-выходы | LIST | STRING(LIST_LENGTH) | Список |
Выходы | LIST_RETRIEVE | STRING(LIST_LENGTH) | Вырезанная запись |
Функция LIST_RETRIEVE вырезает из списка LIST с разделителем SEP запись с номером POS. Нумерация запись начинается с 1. Если элемент с данным номером отсутствует, то функция возвращает пустую строку. См. также функцию LIST_RETRIEVE_LAST, которая используется для вырезания последней записи списка.
Пример
VAR
(* Список с записями *)
List : STRING(OSCAT_BASIC.LIST_LENGTH) := '&12&345&ABC&XYZ';
(* Разделитель *)
Separator : BYTE := 16#26; (* '&' *)
(* Номер вырезаемой записи *)
Position : INT := 2;
(* Вырезанная запись *)
RetrievedRecord : STRING(OSCAT_BASIC.LIST_LENGTH);
END_VAR
(* Вызов функции LIST_RETRIEVE *)
RetrievedRecord := OSCAT_BASIC.LIST_RETRIEVE(
SEP := Separator,
POS := Position,
LIST := List
);
(*
Результат:
- RetrievedRecord = '345'
- List = '&12&ABC&XYZ'
Пояснение:
- Исходный список: '&12&345&ABC&XYZ' (записи '12', '345', 'ABC', 'XYZ')
- Вырезаем запись с номером 2 ('345')
- Запись удаляется из списка
- Итоговый список: '&12&ABC&XYZ' (записи '12', 'ABC', 'XYZ')
*)
END_PROGRAM |
LIST_RETRIEVE_LAST
Тип модуля: функция | Переменная | Тип | Описание |
|---|---|---|---|
Входы | SEP | BYTE | ASCII-код символа-разделителя |
Входы-выходы | LIST | STRING(LIST_LENGTH) | Список |
Выходы | LIST_RETRIEVE_LAST | STRING(LIST_LENGTH) | Вырезанная запись |
Функция LIST_RETRIEVE_LASTвырезает из списка LIST с разделителем SEP последнюю запись. См. также функцию LIST_RETRIEVE, которая используется для вырезания заданной записи списка.
Пример
VAR
(* Список с записями *)
List : STRING(OSCAT_BASIC.LIST_LENGTH) := '&12&345&ABC&XYZ';
(* Разделитель *)
Separator : BYTE := 16#26; (* '&' *)
(* Вырезанная запись *)
RetrievedRecord : STRING(OSCAT_BASIC.LIST_LENGTH);
END_VAR
(* Вызов функции LIST_RETRIEVE_LAST *)
RetrievedRecord := OSCAT_BASIC.LIST_RETRIEVE_LAST(
SEP := Separator,
LIST := List
);
(*
Результат:
- RetrievedRecord = 'XYZ'
- List = '&12&345&ABC'
*)
END_PROGRAM |