Массивы |
Язык VIP обладает средствами работы с одномерными массивами. Количество элементов массива не может быть больше 16000. Начиная с Атлантис 5.XX это ограничение снято.
Массивы должны быть объявлены до их использования.
<описание-массива> = <имя-массива> : array [[<левая-граница>.. ] <правая-граница>] of <тип> ;
<имя-массива> = <идентификатор> <левая-граница> = <целое-число> <правая-граница> = <целое-число>
Обращение к элементу массива:
<обращение-к-элементу-массива> = <имя-массива> [<индекс>]
<имя-массива> = <объявленное-имя-массива> <индекс> = <выражение>
Индекс элемента массива может быть выражением, приводящимся к целому типу.
Индекс элемента массива не должен выходить за левую границу массива. Если массив объявлен в поле таблицы, то индекс элемента массива не должен выходить ни за левую, ни за правую границы массива.
Описание каждого массива начинается служебным словом array.
Всем массивам присваивается тип данных. Все элементы массива имеют один тип. Перед типом стоит служебное слово of. Возможные типы данных массива те же, что и для переменных.
Массив имеет левую и правую границы. Левая граница по умолчанию равна 1, при этом правая граница совпадает с количеством элементов массива. Если заданы левая и правая границы, то они разделяются двумя точками.
Массивы языка VIP делятся на два класса:
статические массивы;
динамические массивы.
Статические массивы (см. пример 1) - массивы, используемые в описании таблиц БД, таблиц в памяти и структур данных, соответствующих буферам этих таблиц. Диапазон индексов этих элементов фиксирован и не может быть изменён после компиляции. Обращение к элементам, индекс которых выходит за границу массива вызовет ExVip.ExArrayRangeError, с завершением выполнения текущего блока программы. Попытка обработки _retry этого исключения вернёт неинициализированное поле.
Пример 1.
table struct ValuesList ( ID : longInt "Идентификатор записи", sValues : array [1..10] of string "Строковые значения", lValues : array [1..10] of longInt "Числовые значения" ) with index ( byID = ID (AutoInc, Unique) ); var aVL : record as table ValuesList; // массивы табличных полей ValuesList.sValue и ValuesList.lValues, // а также поля aVL.sValue и aVL.lValue будут статическими. aVL.lValues[11] := 4; // Ошибка при компиляции idx := 12; aVL.lValues[idx] := idx; // исключение ExArrayRangeError
Динамические массивы (см. пример 2) - массивы, используемые при описании остальных типизированных идентификаторов языка. Описание переменной такого типа приведёт к выделению памяти для размещения необходимого количества элементов, указанных как базовый тип массива. Инициализация элементов таких массивов производится при первом обращении к ним. Левая граница динамических массивов фиксирована, а правая может быть изменена путём обращения к элементу за праой границей или вызовом функции SetLimit. Исключение ExVip.ExArrayRangeError выбрасывается только при обращении к элементам за левой границей.
Пример 2.
const maxValueNum = 10; end; Type RValuesList = record ID : longInt; sValues : array [1..maxValueNum] of string; lValues : array [1..maxValueNum] of longInt; end; var arVL : RValuesList; lValues : array [1..maxValueNum] of longInt; // массивы полей arVL.sValue и arVL.lValue будут динамическими. arVL.lValues[11] := 4; arVL.lValues[0] := 0; // исключение ExArrayRangeError
В конце описания ставится точка с запятой.
В целом, использование переменных и полей таблиц типа массив в языке VIP никак не отличается от использования переменных и полей других типов. Возможно присваивание, передача в функции, возвращать как разультат функции и т.д. (с учётом совместимости типов). Совместимыми считаются массивы у которых совпадает левая и правая границы, и базовый тип. Динамичесие и статические массивы не совместимы. Преобразование типов для массивов приведено в разделе "Преобразование типов данных. ".
Копирование массивов (при присвоении и передаче в функции) осуществляется поэлементно. Копируются только проинициализированные элементы, значения элементов в целевом массиве, соответствующие неинициализированным элементам копируемого сбрасываются в значения по умолчанию. Размер целевого динамического массива при необходимости изменяется. Левая граница не изменяется.
Пример 3.
type TLongStrArray = array [1..3] of String; TShortStrArray = array [0..1] of String; var lSA : TLongStrArray; sSA : TShortStrArray; lSA[1] := 'LSA[1]'; lSA[2] := 'LSA[2]'; lSA[3] := 'LSA[3]'; sSA := TShortStrArray(lSA); // получим : // sSA[0] = 'LSA[1]' // sSA[1] = 'LSA[2]' // sSA[2] = 'LSA[3]' // Count(sSA) = 3; ArrAtDelete (sSA, 1); lSA := TLongStrArray(sSA); // получим : // lSA[1] = 'LSA[1]' // lSA[2] = 'LSA[3]' // Count(lSA) = 2;
Обращения к элементам массивов в структурах, унаследованных от структур таблиц, записываются как обычные обращения к элементам массива. Старый синтаксис ($<индекс>) поддерживается с выдачей предупреждения.
Пример 4.
aVL.sValues[1] := 'Один'; aVL.sValues[j] := 'J'; aVL.sValues$3 := 'Три'; // предупреждение при компиляции
Ограничения:
Описание переменных типа массив (и структур с массивами) в логической таблице запрещено;
Доступ к элементам массива-свойства возможен только на чтение (при наличии у свойства доступа на чтение);
Массивы и структуры не приводятся к типу variant;
Не работает передача массивов и структур через OLE;
Функция SetLeftBound не регистрируется.
Функции для работы с массивами. .
Начиная с Атлантис 5.XX снято ограничение на размер массива.