к оглавлению

Объявление объектов Clarion

Составные структуры данных

GROUP (составная структура данных)

метка GROUP( [ группа ] ) [,PRE( )] [,DIM( )] [,OVER( )] [,NAME( )] [,EXTERNAL] [,DLL] [,STATIC]

[,THREAD] [,BINDABLE] [, TYPE] [,PRIVATE] [,PROTECTED]

объявления

END

GROUP Объявляет составную структуру данных.

группа Метка ранее объявленной группы или очереди, от которой данная группа наследует структуру. Это может быть GROUP или QUEUE с атрибутом TYPE.

PRE Объявление префикса для переменных из этой структуры. Недопустим для группы внутри структуры FILE.

DIM Размерность, если это массив переменных такого типа.

OVER Использование памяти, выделенной другой переменной или структурой.

NAME Указывает альтернативное “внешнее” имя для переменной.

EXTERNAL Указывает на то, что переменная объявляется, а память для нее выделяется во внешней библиотеке. Не допустим в объявлениях внутри структур FILE, QUEUE или GROUP.

DLL Указывает, что переменная определена в библиотеке DLL. В дополнение к этому атрибуту обязателен атрибут EXTERNAL.

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

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

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

TYPE Указывает, данная группа является объявлением типа для групп, передаваемых в качестве параметров.

PRIVATE Указывает на то, что GROUP и все поля компонентов GROUP невидимы вне модуля, содержащего методы CLASS. Действительно только в CLASS.

PROTECTED Указывает на то, что переменная невидима вне методов основного или производного CLASS. Действительно только в CLASS.

объявления данных Несколько последовательных объявлений переменных.

Структура GROUP позволяет ссылаться на несколько переменных по одному имени. Таким способом удобно организовать массив для набора переменных, присваивать значения или сравнивать наборы переменных в одном операторе. В больших сложных программах структура GROUP полезна для хранения данных, имеющих нечто объединяющее. Объявление группы должно заканчиваться точкой или оператором END.

Начало структуры группы, объявляемой с параметром группа, точно совпадает со структурой этой группы; объявляемая группа наследует структуру полей группы, указанной параметром группа. Кроме них в объявляемой группе могут быть свои собственные объявления данных, которые идут следом за наследуемыми полями. Если параметр группа указывает на структуру QUEUE или RECORD, то наследуется только состав полей, но не функциональное назначение этих структур.

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

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

Переменные из группы с атрибутом BINDABLE можно использовать в динамических выражениях. Значение атрибута NAME всех этих переменных является логическим именем, используемым в динамических выражениях. Если атрибут NAME не указан, то используется имя переменной (включая префикс). Для имен всех переменных структуры в EXE-модуле резервируется место. Таким образом, создается программа большего размера, которая использует больше памяти. Поэтому атрибут BINDABLE в группе следует использовать только в том случае, если большую часть составляющих ее полей вы собираетесь использовать в динамических выражениях.

Для группы с атрибутом TYPE памяти не распределяется вообще; это только определение типа для групп, передаваемых в качестве параметров в процедуры. Такой способ позволяет принимающей параметр процедуре адресоваться непосредственно к полям в переданной группе. Объявление параметра в операторе PROCEDURE позволяет устанавливать для передаваемой группы локальный префикс, поскольку он указывает имя, используемое в данной процедуре, для передаваемой группы, однако, если используется синтаксис уточнения имен, то в объявлении префикса нет необходимости. Например, в операторе PROCEDURE(LOC:PassedGroup) объявляется, что для непосредственного обращения к полям - компонентам переданной в качестве параметра группы, в данной процедуре используется префикс LOC: (наряду с именами полей, использованными в определении типа).

На элементы данных GROUP с атрибутом DIM (структурированный массив) можно ссылаться путем применения стандартного синтаксиса Уточнения имени к каждому элементу массива, указанному в GROUP на том уровне, на котором он определен.

Процедуры WHAT и WHERE предоставляют доступ к полям по своему относительному размещению в структуре GROUP.

Пример:

PROGRAM

PassGroup GROUP,TYPE !Определение типов для параметров

F1 STRING(20) !Первое поле

F2 STRING(1) !Среднее поле

F3 TRING(20) !последнее поле

END

MAP

MyProc1(PassGroup) ! Обрабатывает GROUP, определенную так же, как и PassGroup

END

NameGroup GROUP !Название группы

First STRING(20) !Первое имя

Middle STRING(1) !Среднее имя

Last STRING(20) !последнее имя

END !Конец объявления группы

NameGroup2 GROUP(PassGroup) !Группа, наследующая поля PassGroup

!результирующие поля NameGroup2.F1, NameGroup2.F2,

!и NameGroup2.F3,

END !заявленные в этой группе

DateTimeGrp GROUP,DIM(10) !Массив Дата/Время

Date LONG ! со ссылкой DateTimeGrp[1].Date

StartStopTime LONG,DIM(2) ! со ссылкой

DateTimeGrp[1].Time[1]

END ! конец объявления группы

FileNames GROUP,BINDABLE ! Связываемая группа

FileName STRING(8),NAME('FILE') ! Динамическое имя: FILE

Dot STRING(‘.’) ! Динамическое имя: Dot

Extension STRING(3),NAME(‘EXT’) ! Динамическое имя: EXT

END

CODE

MyProc1(NameGroup) ! вызов proc, использующей NameGroup как параметр

MyProc1(NameGroup2) ! вызов proc использующей NameGroup2 как параметр

MyProc1 PROCEDURE(PassedGroup) ! Proc получающая параметр GROUP

LocalVar STRING(20)

CODE

LocalVar = PassedGroup.F1 ! назначить значение в первом поле LocalVar

! из использованного параметра

Смотри также: Уточнение имени переменной, WHAT, WHERE

 

CLASS (объявление объекта)

метка CLASS( [ родительский класс ] ) [,EXTERNAL] [,IMPLEMENTS] [,DLL] [,STATIC] [,THREAD]

[,BINDABLE] [,MODULE( )] [, LINK( )] [, TYPE]

[ данные и методы ]

END

CLASS Объект, содержащий данные и методы, которые манипулируют данными.

родительский класс Метка ранее объявленного класса, данные и методы которого наследует новая структура CLASS. Это может быть структура CLASS с атрибутом TYPE.

EXTERNAL Указывает, что объект определен во внешней библиотеке и там ему выделена память.

IMPLEMENTS Указывает INTERFACE для класса. Добавляет дополнительные методы к реализации класса.

DLL Указывает, что переменная определена в библиотеке DLL. В дополнение к этому атрибуту обязателен атрибут EXTERNAL.

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

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

BINDABLE Указывает, что все переменные, принадлежащие к этому классу можно использовать в динамических выражениях.

MODULE Указывает модуль исходного текста, содержащий определения процедур - методов данного класса. Этот атрибут служит для того же, что и структура MODULE в структуре MAP. Будучи пропущенным, определения модуля PROCEDURE должны быть в том же модуле исходного кода, который содержит объявление CLASS.

LINK Указывает, что модуль исходного кода, содержащий определения PROCEDURE данного класса автоматически добавляется в список связей компилятора. Это избавляет от необходимости отдельно добавлять файл к проекту.

TYPE Указывает, что данная структура CLASS представляет собой определение типа.

данные и методы Объявления данных и прототипы процедур. Элементы данных могут быть только те, которые могут объявляться в структуре GROUP и могут иметь ссылки на тот же самый класс (рекурсивные классы). Процедуры WHAT и WHERE дают доступ к элементам данных по их относительным позициям в структуре CLASS.

Структура CLASS объявляет объект, который содержит данные (свойства) и методы (процедуры), которые манипулируют этими данными. Структура CLASS должна заканчиваться точкой или оператором END.

Производные классы (наследование)

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

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

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

Свойства объектов (инкапсуляция)

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

К методам структуры CLASS с атрибутом TYPE нельзя обращаться непосредственно (как ClassName.Method), а только через методы объектов, объявленных как тип (как Object.Method).

Виртуальные методы (полиморфизм)

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

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

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

Об областях действия

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

Объект определяет, как:

Методы, прототипированные в объявлении производного CLASS в секции локальных данных процедуры - это локальные производные методы, имеющие общую область объявления процедуры со всеми объявлениями локальных данных и подпрограмм. Методы должны быть определены в том же модуле исходного кода, в котором объявлен CLASS и должны следовать сразу за процедурой в этом источнике - то есть, они должны идти после всех ROUTINE и перед всеми остальными процедурами, которые могут быть в том же самом исходном модуле. Это значит, что все ROUTINE и объявления локальных данных процедуры и подпрограммы видимы, и на них могут быть организованы ссылки внутри этих методов.

Например:

SomeProc PROCEDURE

MyLocalVar LONG

MyDerivedClass CLASS(MyClass) ! Объявленный класс с виртуальным методом

MyProc PROCEDURE,VIRTUAL

END

CODE

! Здесь идет основной исполняемый код

! Здесь идет ROUTINE

MyRoutine ROUTINE

! Здесь идет код Routine

! Немедленно следуют методы MyDerivedClass:

MyDerivedClass.MyProc PROCEDURE

CODE

MyLocalVar = 10 ! MyLocalVar в области действия и доступна для использования

DO MyRoutine ! MyRoutine в области действия и доступна для использования

!Здесь идут все остальные процедуры этого

!модуля, вслед за методами произведенных

!классов

 

Подтверждения

Вы объявляете экземпляр CLASS (объекта), просто именуя CLASS как тип данных нового экземпляра, или исполняя процедуру NEW в выражении адресации ссылки к ссылочной переменной для этого именованного CLASS. В любом случае, новый экземпляр наследует все методы и члены данных того объекта CLASS, экземпляром которого он является. Все атрибуты CLASS кроме MODULE и TYPE действительны в объявлении экземпляра.

При отсутствии атрибута TYPE у структуры CLASS, класс сам объявляет и CLASS, и его объектный экземпляр. CLASS с атрибутом TYPE не создает объектного экземпляра этого класса.

Например, следующее объявление CLASS объявляет CLASS как тип данных и объект этого типа:

MyClass CLASS !Объявление типа данных и объектного примера.

MyField LONG

MyProc PROCEDURE

END

тогда как это объявляет CLASS только как тип данных:

MyClass CLASS,TYPE !Только объявление типа данных

MyField LONG

MyProc PROCEDURE

END

Прямое объявление объектных экземпляров типа данных CLASS предпочтительнее, чем ссылка на CLASS. Смысл в том, что код становится меньше, быстрее и не требует использования NEW и DISPOSE для явного создания и уничтожения объектных элементов. Преимущество же использования NEW и DISPOSE - в четком контроле над циклом жизни объекта. Например:

MyClass CLASS,TYPE

MyField LONG

MyProc PROCEDURE

END

OneClass MyClass !Объявленный объектный экземпляр, меньший и более быстрый

TwoClass &MyClass !Объектная ссылка, должна использовать New и DISPOSE

CODE

!Исполнение некоторого кода

TwoClass &= NEW(MyClass) !Здесь начинается цикл жизни объекта

! Исполнение некоторого кода

DISPOSE(TwoClass) ! и длится до этого места

! Исполнение некоторого кода

Другое преимущество объявления объекта - это способность объявлять объект с любым из атрибутов, доступных для объявления непосредственно CLASS (кроме TYPE и MODULE). Например, вы можете объявить объект с атрибутом THREAD вне зависимости от того, объявлен ли с этим атрибутом CLASS или нет.

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

Цикл жизни объекта зависит от того, как он создан:

 

Инициализация данных (свойств)

Элементы простых типов данных объекта автоматически размещаются в памяти и инициализируются пробелом или нулем (если только не указан атрибут AUTO), когда объект активизируется. Распределенная таким образом память возвращается системе, как только объект становится неактивным.

Ссылочные переменные данных объекта не инициализируются и не размещаются в памяти, когда активизируется объект - вы должны специально выполнить адресацию переменной в выражении NEW. Когда объект перестает быть активным, эти ссылочные переменные не освобождают память автоматически, так что ко всем свойствам, к которым вы применили NEW, вы теперь должны применить DISPOSE.

Конструкторы и деструкторы

Метод структуры CLASS, помеченный “Construct” является методом-конструктором, который автоматически вызывается при активизации объекта, немедленно после размещения и инициализации членов данных объекта. Метод “Construct” не может получать какие бы то ни было параметры или быть виртуальным (VIRTUAL). Вы можете явно вызвать метод “Construct” в дополнение к автоматическому вызову.

Если объект является экземпляром производного класса, и как сам производный CLASS, так и родительский содержат конструкторы, а конструктор производного класса не имеет атрибута REPLACE, тогда конструктор родительского класса автоматически вызывается в начале конструктора производного класса. Если конструктор производного класса не имеет атрибута REPLACE, то автоматически вызывается только конструктор производного класса (метод конструктора производного класса может явно вызвать PARENT.Construct в случае надобности).

Метод класса, помеченный “Destruct” является методом-деструктором, который автоматически активизируется при деактивизации объекта, непосредственно перед уничтожением в памяти данных объекта. Метод “Destruct” не может получать какие бы то ни было параметры. Вы можете явно вызвать метод “Destruct” в дополнение к автоматическому вызову.

Если объект является экземпляром производного класса, и как сам производный CLASS, так и родительский содержат деструкторы, а деструктор производного класса не имеет атрибута REPLACE, тогда деструктор родительского класса автоматически активизируется в конце деструктора производного класса. Если деструктор производного класса имеет атрибут REPLACE, то автоматически вызывается только деструктор производного класса (метод деструктора производного класса может явно вызвать PARENT.Destruct в случае надобности).

Public, PRIVATE, и PROTECTED (инкапсуляция)

Общие методы и данные, принадлежащие CLASS или производному CLASS объявляются как без атрибута PRIVATE, так и без атрибута PROTECTED. Общие методы и данные видны (доступны) для всех методов объявляемого CLASS, производных классов и любого кода, в области действия которого находится объект.

Частные методы и члены данных объявляются с атрибутом PRIVATE. Частные методы и данные видны только методам того CLASS, в котором они объявлены, а также любой процедуре, содержащейся в том же модуле исходного кода.

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

Определение метода

Процедурное (PROCEDURE) определение метода (его исполняемый код, а не прототип) является внешним по отношению к структуре CLASS. В определении метода имя класса должно быть связано с именем процедуры или имя CLASS (с меткой SELF) должно передаваться процедуре как первый (безусловный) параметр в списке параметров процедуры.

Помните, что в операторе определения PROCEDURE вы адресуете ссылки для использования в методе ко всем используемым параметрам, так что, так как метка CLASS является типом данных первого безусловного параметра, вы должны использовать SELF как метку для имени параметра CLASS. Например, в следующем определении CLASS:

MyClass CLASS

MyProc PROCEDURE(LONG PassedVar) !Метод берет 1 параметр

END

Вы можете определить MyProc PROCEDURE либо как:

MyClass.MyProc PROCEDURE(LONG PassedVar) !Prepend (соотнести) имя CLASS

CODE ! с меткой метода

Либо как:

MyProc PROCEDURE(MyClass SELF, LONG PassedVar) !Имя CLASS является

CODE ! типом данных первого

!безоговорочного параметра,

!помеченного SELF

Ссылки на свойства объектов и методы в вашей программе

Вы должны обращаться к элементам данных в структуре CLASS, используя синтаксис уточнения полей Clarion. Для этого вы соотносите метку CLASS (если это объектный экземпляр самого класса) или метку объектного экземпляра CLASS метке элемента данных.

Например, для следующего объявления CLASS:

MyClass CLASS !без TYPE,это тоже объектный экземпляр

MyField LONG ! в дополнение к объявлению типа класса

MyProc PROCEDURE

END

MyClass2 MyClass !Объявляется другой объектный экземпляр MyClass

Вы должны организовать ссылку двух переменных от процедуры, внешней к объекту, как:

MyClass.MyField = 10 ! Организует ссылку объекта объявления CLASS MyClass

MyClass2.MyField = 10 ! Организует ссылку объекта объявления MyClass2

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

Например, для следующего объявления CLASS:

MyClass CLASS

MyProc PROCEDURE

END

Вы можете вызвать MyProc PROCEDURE либо как:

CODE

MyClass.MyProc

или как:

CODE

MyProc(MyClass)

SELF и PARENT

Внутри методов класса элементы данных текущего экземпляра объекта связываются с использованием SELF с их именами вместо имени класса. Это позволяет методам в общем образовывать ссылки для методов и членов данных выполняемого в данный момент экземпляра CLASS, вне зависимости от того, исполняется ли родительский класс, производный класс или любой их экземпляр. Этот механизм также позволяет родительскому классу вызывать виртуальные методы производного класса.

Например, расширяя следующий пример, ссылка MyField организуется в методе MyClass.MyProc следующим образом:

MyClass.MyProc PROCEDURE

CODE

SELF.MyField = 10 !присвоить свойству текущего объектного экземпляра

Для методов и элементов данных родительского класса ссылки могут быть организованы напрямую из методов производного класса с помощью атрибута PARENT, указанного перед их метками вместо SELF.

Например:

MyDerivedClass.MyProc PROCEDURE

CODE

!исполнить некоторый код

PARENT.MyProc !вызов метода базового класса

!исполнить еще код

Методы порожденных классов не могут иметь формальный параметр с меткой PARENT и к тому же никакой метод не может иметь явный формальный параметр с меткой SELF.

Например:

MyDerivedClass.MyProc PROCEDURE(MyDerivedClass Parent) !Неправильное использование Parent

Компилятор генерирует предупреждение "Redefining system intrinsics" для любой явной попытки объявить данные с метками SELF или PARENT, используемые в этом контексте.

Концептуальный пример CLASS:

!Файл ClassPrg.CLW содержит:

PROGRAM

MAP. !Структура MAP требуется только для BUILTINS.CLW

OneClass CLASS !Базовый класс

NameGroup GROUP !Ссылаться как к OneClass.NameGroup

First STRING(20) ! ссылаться как к OneClass.NameGroup.First

Last STRING(20) ! ссылаться как к OneClass.NameGroup.Last

END

BaseProc PROCEDURE(REAL Parm) !Объявление прототипа метода

Func FUNCTION(REAL Parm),STRING,VIRTUAL!Объявление прототипа виртуального метода

Proc PROCEDURE(REAL Parm),VIRTUAL ! Объявление прототипа виртуального метода

END !Конец объявления класса

TwoClass CLASS(OneClass),MODULE(’TwoClass.clw’) !Производный от OneClass

Func FUNCTION(LONG Parm),STRING замещает OneClass.Func

Proc PROCEDURE(STRING Msg,LONG Parm) !функционально перегружаемая

END

ClassThree CLASS(TwoClass),MODULE(‘Class3.CLW’) !Производный от TwoClass

Func FUNCTION(<STRING Msg>,LONG Parm),STRING,VIRTUAL

Proc PROCEDURE(REAL Parm),VIRTUAL

END

ClassFour LIKE(ClassThree) !Объявить экземпляр класса ClassThree

ClassFive ClassThree !Объявить экземпляр класса ClassThree.116 CLARION 4 ОПИСАНИЕ ЯЗЫКАCODE

OneClass.NameGroup = ‘|OneClass Method’ !Присвоить значения каждому

!экземпляру NameGroup

TwoClass.NameGroup = ‘|TwoClass Method’

ClassThree.NameGroup = ‘|ClassThree Method’

ClassFour.NameGroup = ‘|ClassFour Method’

MESSAGE(OneClass.NameGroup & OneClass.Func(1.0)) !Обращение к OneClass.Func

MESSAGE(TwoClass.NameGroup & TwoClass.Func(2)) !Обращения к TwoClass.Func

MESSAGE(ClassThree.NameGroup & ClassThree.Func(‘|Call ClassThree.Func’,3.0))

! Обращения к ClassThree.Func

MESSAGE(ClassFour.NameGroup & ClassFour.Func(‘|Call ClassFour.Func’,4.0))

!Также обращение ClassThree.Func

OneClass.BaseProc(5) !BaseProc обращается к OneClass.Proc и Func

BaseProc(TwoClass,6) !BaseProc также обращается к OneClass.Proc и Func

TwoClass.Proc(‘Second Class’,7) !обращается к TwoClass.Proc (перегруженной)

ClassThree.BaseProc(8) !BaseProc обращается к ClassThree.Proc и Func

ClassFour.BaseProc(9) !BaseProc также обращается к ClassThree.Proc и Func

Proc(ClassFour,’Fourth Class’,10) !обращение к TwoClass.Proc (перегруженной)

OneClass.BaseProc PROCEDURE(REAL Parm) !определение OneClass.BaseProc

CODE

MESSAGE(Parm & SELF.NameGroup &’|BaseProc executing|calling SELF.Proc Virtual method’)

SELF.Proc(Parm) !обращение к виртуальному методу

MESSAGE(Parm & SELF.NameGroup&’|BaseProc executing|calling SELF.Func Virtual method’)

MESSAGE(SELF.NameGroup & SELF.Func(Parm)) ! обращение к виртуальному методу

OneClass.Func FUNCTION(REAL Parm) !Определение OneClass.Func

CODE

RETURN(‘|Executing OneClass.Func – ‘ & Parm)

Proc PROCEDURE(OneClass SELF,REAL Parm) ! Определение OneClass.Proc

CODE

MESSAGE(SELF.NameGroup & ‘ |Executing OneClass.Proc – ‘ & Parm)

!Файл TwoClass.CLW содержит:

MEMBER(‘ClassPrg’)

Func FUNCTION(TwoClass SELF,LONG Parm) ! Определение TwoClass.Func

CODE

RETURN(‘|Executing TwoClass.Func – ‘ & Parm)

TwoClass.Proc PROCEDURE(STRING Msg,LONG Parm) ! Определение TwoClass.Proc

CODE

MESSAGE(Msg & ‘|Executing TwoClass.Proc – ‘ & Parm)

! Файл Class3.CLW содержит:

MEMBER(‘ClassPrg’)

ClassThree.Func FUNCTION(<STRING Msg>,LONG Parm) ! Определение

ClassThree.Func

CODE

SELF.Proc(Msg,Parm) !Обращение к TwoClass.Proc (перегруженной)

RETURN(Msg & ‘|Executing ClassThree.Func – ‘ & Parm)

ClassThree.Proc PROCEDURE(REAL Parm) !Определение ClassThree.Proc

CODE

SELF.Proc(‘Called from ClassThree.Proc’,Parm) !обращение к TwoClass.Proc

MESSAGE(SELF.NameGroup &’ |Executing ClassThree.Proc – ‘ & Parm)

Смотри также: Уточнение имени перменной, MODULE, Прототипы процедур, Перегрузка процедур, WHAT, WHERE

 

INTERFACE (определение поведения класса)

метка INTERFACE ( [ родительский интерфейс ] ) [, TYPE]

[методы ]

END

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

родительский интерфейс

Метка ранее объявленной структуры INTERFACE, чьи методы унаследованы новым INTERFACE. Он может иметь атрибут TYPE.

TYPE Указывает, что INTERFACE может быть только определением типа. INTERFACE неявно имеет TYPE, но может быть объявлен и явно.

COM Указывает, что все определенные в интерфейсе методы используют соглашение PASCAL о передаче параметров. Используется для реализации COM.

методы Прототипы процедуры.

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

Производные интерфейсы (Наследование)

INTERFACE объявленный с параметром родительский интерфейс создает производный интерфейс, который наследует все методы, принадлежащие родительскому интерфейсу. Производный интерфейс может также содержать свои собственные методы.

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

Смотри также раздел Реализация интерфейсов в производных классах для более детальной информации об этой теме.

Виртуальные методы (Полиформизм)

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

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

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

Определение метода

Процедура определения методов (исполняемый код, а не прототип) определяется классом, которые выполняет INTERFACE. Все методы для интерфейса должны быть определены в выполняющем классе.

Обращение к методам INTERFACE в вашем коде

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

Например, используя следующие объявления INTERFACE и CLASS:

MyInterface INTERFACE

MyProc PROCEDURE

END

MyClass CLASS,IMPLEMENTS(MyInterface)

END

Вы можете вызвать процедуру MyProc как:

CODE

MyClass.MyInterface.MyProc

Смотри также: IMPLEMENTS, Реализация интерфейсов в производных классах

 

Файловые структуры

FILE (объявить структуру файла данных)

метка FILE,DRIVER( ) [,CREATE] [,RECLAIM] [,OWNER( )] [,ENCRYPT] [,NAME()] [,PRE( )]

[,BINDABLE] [,THREAD] [,EXTERNAL] [,DLL] [,OEM]

метка [INDEX( )]

метка [KEY( )]

метка [MEMO( )]

метка [BLOB]

[метка] RECORD

[метка] поля

END

END

метка Допустимая метка Clarion для FILE, INDEX, KEY, MEMO, BLOB, RECORD или поля (PROP:Label).

FILE Объявляет файл данных.

DRIVER Указывает тип файла данных (PROP:DRIVER). Атрибут DRIVER обязателен для объявления любого файла.

CREATE Разрешает создание файла во время выполнения программы оператором CREATE (PROP:CREATE).

RECLAIM Задает повторное использование пространства, занимаемого логически удаленными записями (PROP:RECLAIM).

OWNER Задает ключевое слово для шифрования данных (PROP:OWNER).

ENCRYPT Шифрует данные в файле (PROP:ENCRYPT).

NAME Указывает спецификацию файла (путь в структуре каталогов и имя) (PROP:NAME).

PRE Объявляет префикс для имен в данной структуре.

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

THREAD Указывает, что, при открытии файла в исполняемом процессе память для буфера записи файла выделяется отдельно для каждого процесса (PROP:THREAD).

EXTERNAL Указывает, что структура FILE описывается во внешней библиотеке и там же для нее выделяется буфер.

DLL Указывает, данная структура FILE описывается в библиотеке DLL. Этот атрибут дополнительно требует атрибута EXTERNAL

OEM Указывает, что строковые данные при чтении с диска преобразуются из OEM ASCII в ANSI, а при записи, наоборот, из ANSI в OEM ASCII (PROP:OEM).

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

KEY Объявляет динамически обновляемый ключ доступа для файла данных.

MEMO Объявляет текстовое поле переменной длины (до 64 К байт).

BLOB Объявляет мемо-поле переменной длины, которое может быть больше 64К.

RECORD Объявляет структуру записи файла, состоящую из полей. Структура RECORD обязательна для любого объявления файла.

поля Элементы данных в структуре RECORD.

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

Все атрибуты операторов FILE, KEY, INDEX, MEMO, операторов объявления полей и типы данных, которые может содержать структура FILE, зависят от поддержки файловым драйвером (значения атрибута DEVICE). Любые атрибуты и типы данных в объявлении файла, которые не поддерживается файловой системой, указанной атрибутом DRIVER, приведут к появлению сообщений об ошибке, выдаваемого файловым драйвером при открытии файла. Исключения в атрибутах и/или типах данных перечисляются в документации по файловым драйверам.

Во время выполнения программы структуре RECORD назначается области памяти, используемой в качестве буфера данных, в котором прочитанные с диска записи могут обрабатываться исполняемыми операторами. Буферная запись всегда располагается в области статической памяти, даже если FILE объявлен в секции локальных данных. В структуре FILE обязательно должна присутствовать структура RECORD. Память для буфера данных любых MEMO полей выделяется, когда файл открывается и освобождается при его закрытии. Память для полей BLOB выделяется по мере необходимости при открытии файла.

Структура FILE с атрибутом BINDABLE предполагает, что все переменные из структуры RECORD доступны для использования в динамических выражениях, без обязательного выполнения оператора BIND для каждого поля (позволяя выполнить один оператор BIND(файл), чтобы сделать все доступными все поля файла). Содержимое параметра NAME для каждой переменной является логическим именем, используемым в динамическом выражении. Если атрибут NAME не указан, то используется имя переменной (включая префикс). Для имен всех переменных структуры в EXE-модуле резервируется память. Это увеличивает размер программы и затраты оперативной памяти. Поэтому атрибут BINDABLE следует применять только когда большую часть составляющих структуру полей планируется использовать в динамических выражениях.

Атрибут THREAD указывает, что для каждого исполняемого процесса, в котором открывается файл, выделяется отдельный буфер для записи и блок управления файлом (FCB). Если в процессе файл не открывается, то для него и не выделяется буфер записи. Если для файла указан атрибут NAME, объявленный как “STRING, STATIC”, то необходимо указывать атрибут THREAD, если различные файлы будут открыты для каждого исполняемого процесса (также можно использовать свойство PROP:Name для указания имени файла).

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

Файл с атрибутом EXTERNAL объявляется и его можно использовать в исполняемых операторах, но память для него не выделяется. Память для буфера записи этого файла резервируется во внешней библиотеке. Это позволяет программе на языке Clarion использовать файлы, объявленные как общие во внешней библиотеке.

Связанные процедуры:

BUFFER, BUILD, CLOSE, COPY, CREATE, EMPTY, FLUSH, LOCK, NAME,

OPEN, PACK, RECORDS, REMOVE, RENAME, SEND, SHARE, STATUS,

STREAM, UNLOCK, ADD, APPEND, BOF, BYTES, DELETE, DUPLICATE,

EOF, GET, HOLD, NEXT, NOMEMO, POINTER, POSITION, PREVIOUS, PUT,

RELEASE, REGET, RESET, SET, SKIP, WATCH

Пример:

Names FILE,DRIVER('Clarion') !Объявление структуры файла

Rec RECORD !Обязательная структура record

Name STRING(20) ! содержащая один или более элемент данных

END

END !Конец объявлений записи и файла

Смотри также: KEY, INDEX, MEMO, BLOB, RECORD

 

INDEX (объявить статический ключ доступа к записям файла)

метка INDEX([-/+][поле],...,[-/+][поле]) [,NAME( )] [,NOCASE] [,OPT]

метка Метка индекса (PROP:Label).

INDEX Объявляет статический ключ доступа для файла данных.

-/+ Знак “-” (минус) перед полем - компонентом индекса указывает убывающий порядок сортировки для этого компонента. Если минус опущен или указан символ + (плюс), то упорядочение по этой составляющей производится в порядке возрастания значений.

поле Метка поля в структуре RECORD структуры FILE, в которой объявляется индекс. Поле представляет собой компонент индекса. В качестве составляющей индекса не может использоваться поле, объявленное с атрибутом DIM (массив).

NAME Задает спецификацию дискового файла для индекса (PROP:NAME).

OPT Исключает из индекса те записи, в которых все поля-компоненты имеют пустые (нулевые или пробельные) значения (PROP:OPT).

NOCASE Указывает независимость сортировки индекса от регистра букв (прописные - строчные) (PROP:NOCASE).

Оператор INDEX объявляет “статический” ключ в структуре FILE. Индексный файл строится и обновляется только посредством выполнения оператора BUILD. Индекс используется для доступа к записям данных в логической последовательности отличной от физического расположения их в файле.

Он может использоваться или для последовательной обработки файла, или прямого (произвольного) доступа к записям. В индексе всегда допускается наличие дублирующихся значений. Индекс может иметь несколько составляющих полей. Порядок следования полей-компонент в индексе определяет порядок его упорядочения. Первый компонент наиболее значим, последний - наименее. В общем случае файл данных может иметь до 255 индексов (и/или ключей), а каждый индекс может состоять из полей, сумма длин которых не может превышать 255 байт, но точное значение этих величин зависит от конкретного файлового драйвера.

Индекс, объявленный без составляющих его полей, создает “динамический индекс”. В динамическом индексе в качестве составляющих может использоваться любое поле (или поля) из структуры RECORD за исключением массивов. Поля-компоненты динамического индекса определяются во время выполнения программы вторым параметром оператора BUILD. Один и тот же динамический индекс можно строить, используя каждый раз различные поля-компоненты.

Пример:

Names FILE,DRIVER('TopSpeed'),PRE(Nam)

NameNdx INDEX(Nam:Name),NOCASE ! Объявить индекс по полю Name

NbrNdx INDEX(Nam:Number),OPT ! Объявить индекс по полю Number

DynamicNdx INDEX() ! Объявить динамический индекс

Rec RECORD

Name STRING(20)

Number SHORT

END

END

Смотри также: SET, GET, KEY, BUILD

 

KEY (объявить динамический ключ доступа к записям файла)

метка KEY([-/+]поле,...,[-/+][поле]) [,DUP] [,NAME( )] [,NOCASE] [,OPT] [,PRIMARY]

метка Метка ключа (PROP:Label).

KEY Объявляет динамически обновляемый ключ доступа к файлу данных.

-/+ Знак “-” (минус) перед полем-компонентом ключа указывает убывающий порядок сортировки для этого компонента. Если минус опущен или указан символ + (плюс), то упорядочение по этой составляющей производится в порядке возрастания значений.

поле Метка поля в структуре RECORD структуры FILE, в которой объявляется ключ. Поле представляет собой компонент ключа. В качестве составляющей ключа не может использоваться поле, объявленное с атрибутом DIM (массив).

NAME Задает спецификацию дискового файла для ключа (PROP:NAME).

DUP Допускает наличие в файле записей, имеющих одинаковые значения полей, составляющих ключ (PROP:DUP).

NOCASE Указывает независимость сортировки ключа от регистра букв (прописные - строчные) (PROP:NOCASE).

OPT Исключает из ключа те записи, в которых все поля-компоненты имеют пустые (нулевые или пробельные) значения (PROP:OPT).

PRIMARY Указывает, что данный ключ является первичным ключом в связи между файлами (уникальным ключом содержащимся в каждой записи файла) (PROP:PRIMARY).

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

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

Пример:

Names FILE,DRIVER('Clarion'),PRE(Nam)

NameKey KEY(Nam:Name),NOCASE,DUP ! Объявить ключ по полю Name

NbrKey KEY(Nam:Number),OPT ! Объявить ключ по полю Number

Rec RECORD

Name STRING(20)

Number SHORT

END

END

CODE

Nam:Name = 'Clarion Software' ! Присвоить значение ключевому полю

GET(Names,Nam:NameKey) ! Прочитать запись

SET(Nam:NbrKey) ! Установить последовательную обработку по номеру

Смотри также: SET, GET, INDEX, BUILD, PACK

 

MEMO (объявить текстовое поле)

метка MEMO(длина) [,BINARY] [,NAME( )]

метка Метка MEMO-поля (PROP:Label).

MEMO Объявляет строку фиксированной длины, которая хранится на диске в виде строки переменной длины.

длина Числовая константа, которая определяет максимальное число символов в поле. Диапазон возможных значений неограничен в 32-х разрядных приложениях (зависит от поддержки MEMO файловым драйвером).

BINARY Объявляет, что MEMO-поле предназначено для хранения двоичных данных (PROP:BINARY).

NAME Задает имя файла, в котором хранится MEMO-поле (PROP:NAME).

Оператор MEMO объявляет строковое поле фиксированной длины, которое на диске хранится в виде записей переменной длины. Параметр длина определяет максимальный размер данных в этом поле. MEMO-поле должно объявляться перед структурой RECORD. Память для буфера MEMO-поля выделяется при открытии файла, а при закрытии она освобождается. MEMO-поле обычно отображается в поле типа TEXT структуры SCREEN (наверно WINDOW, прим. пер.) или REPORT.

В общем случае в структуре FILE может объявляться до 255 MEMO-полей, но точное их число и способ хранения на диске зависят от файлового драйвера.

Пример:

Names FILE,DRIVER('Clarion'),PRE(Nam)

NameKey KEY(Nam:Name)

NbrKey KEY(Nam:Number)

Notes MEMO(4800) ! Memo-поле длиной 48OO байт

Rec RECORD

Name STRING(20)

Number SHORT

END

END

 

BLOB (объявить поле переменной длины)

метка BLOB [,BINARY] [,NAME( )]

метка Метка поля BLOB (PROP:Label).

BLOB Объявляет поле переменной длины, которое может быть больше 64К.

BINARY Объявляет, что в этом поле хранятся двоичные данные (PROP:BINARY).

NAME Указывает имя дискового файла для этого BLOB-поля (PROP:NAME).

Оператор BLOB (Binary Large OBject - большой двоичный объект) объявляет строковое поле переменной длины которое может быть более чем 64К. Поле BLOB должно объявляться до структуры RECORD. В общем случае в структуре FILE может быть объявлено до 255-ти полей типа BLOB. Точное число таких полей и способ их хранения на диске зависят от файлового драйвера.

Такое поле нельзя использовать так же как обычную переменную - нельзя указать ее в качестве USE-переменной и напрямую присваивать или получать с него данные. Можно использовать свойство PROP:Handle, чтобы получить идентификационный номер (handle) Windows для объекта BLOB. Таким образом обеспечивается единственный способ присвоения значения одного поля BLOB другому: получить для обоих полей идентификационные номера объектов Windows, а затем присвоить один номер другому. Поле BLOB нельзя обрабатывать “целиком”; нужно использовать либо синтаксис “части строки” для доступа к данным, либо свойство PROP:ImageBLOB. Отдельные байты данных в BLOB нумеруются начиная с ноля (0), а не с единицы (1).

Для текущей прочитанной в память записи длину поля BLOB можно получить с помощью функции SIZE. Кроме того, можно получить (и установить) размер BLOB-поля с помощью свойства PROP:BlobSize. Вы можете установить размер BLOB перед присвоением данных в новое поле BLOB, но в этом нет необходимости, так как размер автоматически устанавливается операцией “части строки”. Вы можете также использовать PROP:ImageBLOB для хранения и извлечения графической информации без начальной установки PROP:Size. Хорошей идеей является установка PROP:Size в нулевое значение перед присваиванием данных в BLOB, содержащего предыдущие данные, чтобы очистить от “отходов” оставшихся от предыдущих данных. При присвоении данных одного BLOB другому, вам возможно понадобится применить PROP:Size, чтобы приравнять размер принимающей данные BLOB размеру источника данных. Свойство PROP:Touched может быть использовано для определения того, изменилось ли содержимое BLOB со времени его загрузки с диска.

Пример:

ArchiveFile PROCEDURE

Names FILE,DRIVER('TopSpeed')

NaneKey KEY(Name)

Notes BLOB !Может быть больше 64K

Rec RECORD

Name STRING(20)

END

END

ArcNames FILE,DRIVER('TopSpeed')

Notes BLOB

Rec RECORD

Name STRING(20)

END

END

CODE

SET(Names)

LOOP

NEXT(Names)

IF ERRORCODE() THEN BREAK.

ArcNames.Rec = Names.Rec !присвоить данные rec Archive

ArcNames.Notes{PROP:Handle} = Names.Notes{PROP:Handle}

!Присвоить BLOB Archive

IF ERRORCODE() = 80

MESSAGE(‘BLOB size is too large’)

BREAK

END

ArcNames.Notes{PROP:Size} = Names.Notes{PROP:Size}

! и выровнять размер

ADD(ArcNames)

END

StoreFileInBlob PROCEDURE !Хранит любые файлы в BLOB

DosFileName STRING(260),STATIC

LastRec LONG

SavPtr LONG(1) !начинается с 1

FileSize LONG

DosFile FILE,DRIVER('DOS'),PRE(DOS),NAME(DosFileName)

Record RECORD

F1 STRING(2000)

END

END

BlobStorage FILE,DRIVER('TopSpeed'),PRE(STO)

File BLOB,BINARY

Record RECORD

FileName STRING(64)

END

END

CODE

IF NOT FILEDIALOG('Choose File to Store',DosFileName,,0010b) THEN RETURN.

OPEN(BlobStorage) !Открыть файл BLOB

STO:FileName = DosFileName ! и сохранить имя файла

OPEN(DosFile) !Открыть файл

FileSize = BYTES(DosFile) !получить размер файла

STO:File{PROP:Size} = FileSize! и установить BLOB для хранения файла

LastRec = FileSize % SIZE(DOS:Record)

!проверить запись в конце файла

LOOP INT(FileSize/SIZE(DOS:Record)) TIMES

GET(DosFile,SavPtr) !получить каждую запись

ASSERT(NOT ERRORCODE())

STO:File[SavPtr - 1 : SavPtr + SIZE(DOS:Record) - 2] = DOS:Record

!Данные по частям в BLOB

SavPtr += SIZE(DOS:Record) !вычислить номер следующей записи

END

IF LastRec !если последняя запись файла

GET(DosFile,SavPtr) !получить последнюю запись

ASSERT(BYTES(DosFile) = LastRec)

! размер чтения должен соответствовать вычисленному размеру

STO:File[SavPtr - 1 : SavPtr + LastRec - 2] = DOS:Record

END

ADD(BlobStorage)

ASSERT(NOT ERRORCODE())

CLOSE(DosFile);CLOSE(BlobStorage)

Смотри также: PROP:ImageBlob, PROP:Size , Неявно объявленные массивы и части строк, BLOBtoFILE,

FILEtoBLOB

 

RECORD (объявить структуру записи файла)

[метка] RECORD [,PRE( )] [,NAME( )]

поля

END

RECORD Объявляет начало структуры данных внутри объявления файла.

поля Множественное объявление переменных.

PRE Указывает префикс для переменных в данной структуре.

NAME Задает внешнее имя для данной структуры RECORD

Оператор RECORD объявляет начало структуры данных в объявлении файла. Структура RECORD обязательно должна присутствовать. Каждое поле является элементом структуры RECORD. Длина структуры RECORD представляет собой сумму длин составляющих ее полей. Когда метка структуры RECORD используется в операторе присвоения, выражении или списке параметров, то эта структура рассматривается как группа (тип данных GRОUР).

Во время выполнения программы в качестве буфера для структуры RECORD выделяется статическая память. Поля в буфере записи доступны независимо от того, открыт файл или закрыт.

Если поля представляют собой объявления переменных с присвоением начального значения, то эти начальные значения используются только для определения размера переменных, а в буфер записи эти значения не заносятся. Например объявление STRING(‘abc’) создает трехбайтовую строку, но пока исполняющие операторы не присвоят это значение, строка автоматически не инициализируется этим значением.

Операторами NEXT, PREVIOUS, GET или REGET записи из файла данных на диске считываются в буфер записи. Данные в полях обрабатываются, а затем как единая запись заносятся операторами ADD, APPEND или PUT в файл данных на диске или удаляются из него оператором DELETE.

Процедуры WHAT и WHERE позволяют получить доступ к полям относительно их позиции в структуре RECORD.

Пример:

Names FILE,DRIVER(‘Clarion’ ! Объявить структуру файла

Record RECORD ! Начало объявления структуры записи

Name STRING(20) ! Объявить поле Name

Number SHORT ! Объявить поле Number

END

END !Конец объявления структуры записи и файла.

Смотри также: FILE, NEXT, PREVIOUS, GET, REGET, ADD, APPEND, PUT, DELETE, WHAT, WHERE

 

Обработка фиктивных данных

“Фиктивное” значение в поле файла данных означает, что пользователь совсем не ввел данные в это поле. Фиктивность реально означает, что значение поля “не известно”. Это в корне отличается от того, что поле имеет пробельное или нулевое значение, и делает возможным определить разницу между тем, что данные в поле не введены и тем, что поле имеет действительно пробельное или нулевое значение.

В выражении фиктивное значение не равно нулевому или пробельному. Поэтому любое выражение, в котором сравнивается значение поля файла данных с каким-либо другим значением, всегда будет давать в результате фиктивное значение, если фиктивно значение сравниваемого поля. Это справедливо, даже если значения обоих сравниваемых элементов являются фиктивными. Например условное выражение Pre:Field1 = Pre:Field2, будет давать результат “истина” только, если оба поля содержат реальные, одинаковые значения. Если одно из полей содержит фиктивное значение, то результат выражения будет также фиктивным.

Known = Known ! оценено как истина или ложь

Known = Unknown ! оценено как неизвестное

Unknown = Unknown ! оценено как неизвестное

Unknown <> 10 ! оценено как неизвестное

1 + Unknown ! оценено как неизвестное

Четыре булевых выражения, использующие операции OR (ИЛИ) и AND (И), в которых только одна часть всего выражения представляет собой фиктивное значение, а вторая удовлетворяет приведенным ниже критериям, являются единственным исключением из вышеприведенных правил:

Unknown OR True ! оценено как истина

True OR Unknown ! оценено как истина

Unknown AND False ! оценено как ложь

False AND Unknown ! оценено как ложь

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

Смотри также: NULL, SETNULL, SETNONULL

 

Свойства структуры FILE

Ниже представлен краткий список свойств, которые распространяются исключительно на компоненты структуры FILE. Смотри также Динамические свойства FILE и VIEW для более подробного списка.

Многофункциональные свойства структуры FILE

PROP:BINARY PROP:Dim PROP:Label

PROP:NAME PROP:Over PROP:Places

PROP:Size PROP:Type

Свойства файла

PROP:BLOB PROP:Blobs PROP:CREATE

PROP:Driver PROP:DriverString PROP:ENCRYPT

PROP:Fields PROP:FileDriver PROP:KEY

PROP:Keys PROP:Memos PROP:OEM

PROP:OWNER PROP:RECLAIM PROP:PRE

PROP:THREAD

Свойства индексов

PROP:Ascending PROP:Components PROP:DUP

PROP:FIELD PROP:Fields PROP:NOCASE

PROP:OPT PROP:PRIMARY

Все эти свойства являются элементами структуры данных FILE. Они описывают атрибуты, поля, ключи, memo- и blob-поля, которые могут быть объявлены только в пределах структуры FILE. Все эти свойства структуры FILE предназначены только для чтения (READ ONLY), за исключением: PROP:NAME (который может быть использован для изменения имени поля в файле), PROP:OWNER и PROP:DriverString. Присвоенные значения этим свойствам перекрывают соответствующие объявленные атрибуты.

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

Каждое поле, содержащееся в структуре RECORD, имеет положительный номер. Нумерация полей внутри структуры RECORD начинается с 1 и для каждого последующего поля увеличивается с шагом 1 в том же самом порядке, в котором они расположены в структуре RECORD. Завершающие структуру GROUP операторы END нумерации не подлежат, поскольку они не являются объявлениями полей.

Поля MEMO и BLOB нумеруются отрицательными числами. Описания MEMO- и BLOB-полей начинаются с -1 и последовательно убывают на 1 для каждого следующего MEMO- или BLOB-поля в том же порядке, в котором они расположены в структуре FILE.

Многофункциональные свойства структуры FILE

PROP:Label

Возвращает метку объявляемого оператора.

Когда не задано никакого номера элемента массива, и в качестве цели выступает метка ключа KEY (или индекса (INDEX)), PROP:Label возвращает метку означенного ключа или индекса.

Когда задан положительный номер элемента массива, и в качестве цели выступает метка структуры FILE, PROP:Label возвращает метку соответствующего поля внутри структуры RECORD.

Когда задан отрицательный номер элемента массива, и в качестве цели выступает метка структуры FILE, PROP:Label возвращает метку соответствующего MEMO-поля внутри структуры FILE.

Когда задан положительный номер элемента массива, и в качестве цели выступает BLOB-поле, PROP:Label возвращает метку означенного BLOB-поля.

PROP:NAME

Атрибут NAME объявляемого оператора.

Когда не задано никакого номера элемента массива, и в качестве цели выступает структура FILE, свойство PROP:Name возвращает содержимое атрибута NAME оператора FILE.

Когда задан положительный номер элемента массива, и в качестве цели выступает структура FILE, PROP:Name возвращает атрибут NAME соответствующего поля внутри структуры RECORD.

Когда задан отрицательный номер элемента массива, и в качестве цели выступает структура FILE, PROP:Name возвращает атрибут NAME соответствующего MEMO- или BLOB-поля внутри структуры FILE.

Когда не задано никакого номера элемента массива, и в качестве цели выступает метка ключа KEY (или индекса (INDEX)), PROP:Name возвращает атрибут NAME означенного ключа KEY (или индекса (INDEX)).

PROP:Size

Множественное свойство, которое возвращает объявленный размер указанного MEMO, STRING, CSTRING, PSTRING, DECIMAL или PDECIMAL поля.

PROP:Type

Тип данных, используемый объявляемым оператором.

Когда не задано никакого номера элемента массива, и в качестве цели выступает метка ключа KEY (или индекса (INDEX)), PROP:Type возвращает атрибут NAME означенного ключа или индекса.

Когда задан положительный номер элемента массива, и в качестве цели выступает метка структуры FILE, PROP:Type возвращает строку с типом данных соответствующего поля внутри структуры RECORD. PROP:Type теперь возвращает тип MEMO или BLOB. Когда указан отрицательный номер элемента массива и в качестве цели выступает метка FILE, PROP:Type возвращает либо "MEMO" либо "BLOB".

Свойства оператора FILE

Все перечисленные ниже свойства используют в качестве цели метку оператора FILE.

PROP:DRIVER

Атрибут драйвера. Возвращает файловый драйвер, используемый оператором FILE.

PROP:DriverString

Свойство файла, которое возвращает второй параметр атрибута DRIVER() файла.

PROP:CREATE

Атрибут CREATE оператора FILE. Переключаемый атрибут. Присвоение пустой строки (‘’) выключает его, литеральная единица (‘1’) - включает.

PROP:RECLAIM

Атрибут RECLAIM оператора FILE. Переключаемый атрибут. Присвоение пустой строки (‘’) выключает его, литеральная единица (‘1’) - включает.

PROP:OWNER

Атрибут OWNER оператора FILE.

PROP:ENCRYPT

Атрибут ENCRYPT оператора FILE. Переключаемый атрибут. Присвоение пустой строки (‘’) выключает его, литеральная единица (‘1’) - включает.

PROP:FileDriver

Допустим вы имеете инсталлированный Dynamic File Driver. Вы теперь можете динамически изменять статически определенный драйвер файла используя:

filelabel{PROP:FileDriver} = ADDRESS(OtherFile).

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

PROP:THREAD

Атрибут THREAD оператора FILE. Переключаемый атрибут. Присвоение пустой строки (‘’) выключает его, литеральная единица (‘1’) - включает.

PROP:OEM

Атрибут OEM оператора FILE. Переключаемый атрибут. Присвоение пустой строки (‘’) выключает его, литеральная единица (‘1’) - включает.

Prop:PRE

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

PROP:Keys

Возвращает количество объявленных ключей (KEY) и индексов (INDEX) в структуре FILE.

PROP:Key

Массив, который возвращает ссылку на указанный ключ (KEY) или индекс (INDEX) в структуре FILE. Эта ссылка может использоваться в качестве исходной стороны оператора ссылочного присвоения.

Свойства Ключа (KEY)

Все перечисленные ниже свойства используют в качестве цели метку ключа (KEY) или индекса (INDEX).

PROP:PRIMARY

Атрибут PRIMARY оператора KEY. Переключаемый атрибут. Присвоение пустой строки (‘’) выключает его, литеральная единица (‘1’) - включает.

PROP:DUP

Атрибут DUP оператора KEY. Переключаемый атрибут. Присвоение пустой строки (‘’) выключает его, литеральная единица (‘1’) – включает.

PROP:NOCASE

Атрибут NOCASE оператора KEY или INDEX. Переключаемый атрибут. Присвоение пустой строки (‘’) выключает его, литеральная единица (‘1’) - включает.

PROP:OPT

Атрибут OPT оператора KEY или INDEX. Переключаемый атрибут. Присвоение пустой строки (‘’) выключает его, литеральная единица (‘1’) - включает.

PROP:Components

Возвращает количество полей, являющихся компонентами ключа (KEY) или индекса (INDEX).

PROP:Field

Массив, который возвращает номер поля (в пределах структуры RECORD) соответствующего заданному полю-компоненте ключа (KEY) или индекса (INDEX). Этот номер поля может быть использован в качестве номера элемента массива для таких свойств, как PROP:LABEL или PROP:NAME.

PROP:Ascending

Массив, который возвращает ‘1’, если указанная компонента ключа находится в возрастающем порядке, и пустую строку (‘’) - если в убывающем.

Свойства Поля (Field)

Все перечисленные ниже свойства используют в качестве цели метку оператора FILE.

PROP:BLOB

Используется всеми драйверами баз данных поддерживающих создание BLOB:

blobRef &= file{PROP:Blob, N}

где N указывает на номер расположения BLOB (где файл может иметь несколько полей BLOB).

Это свойство используется для получения ссылки на BLOB. N может быть как положительным, так и отрицательным значением. Это вернет указатель на ABS(N)-ый BLOB. Где N - n-ое MEMO- или BLOB-поле. Если N - MEMO, то будет возвращен NULL.

Пример:

AFile FILE,DRIVER('TOPSPEED'),PRE(EMP)

M1 MEMO

B1 BLOB

RECORD

..

ABlob &BLOB

CODE

ABlob &= AFile{PROP:Blob, 1} !Вернет NULL

ABlob &= AFile{PROP:Blob, -1}!Вернет NULL

ABlob &= AFile{PROP:Blob, 2} !ABlob является указателем на AFile.B1

ABlob &= AFile{PROP:Blob, -2}!ABlob является указателем на AFile.B1

Смотри также: PROP:Value

PROP:Memos

Возвращает количество полей MEMO в структуре FILE.

PROP:Blobs

Возвращает количество полей BLOB в структуре FILE.

PROP:BINARY

Атрибут BINARY на операторе MEMO или BLOB в структуре FILE. Переключаемый атрибут. Присвоение пустой строки (‘’) выключает его, литеральная единица (‘1’) - включает.

PROP:Fields

Имеется несколько форм свойства PROP:Fields:

метка ключа{PROP:Fields}

Возвращает число полей в определении ключа.

метка файла{PROP:Fields}

Возвращает число полей, объявленных в структуре RECORD.

метка файла{PROP:Fields, n}

Возвращает число полей в группе. Значение этого свойства определяется только если файл{PROP:Type, n} возвращает 'GROUP'.

метка виртуального файла{PROP:Fields}

Возвращает число полей, объявленных в структуре VIEW.

метка виртуального файла{PROP:Fields, n}

Возвращает число полей, входящих в состав файла для n. Если n равно 0, тогда возвратит общее число полей входящих в виртуальный файл.

Пример:

v VIEW(PFile),ORDER('PFile:String1'),FILTER('PFile:ID = 3')

PROJECT(PFile:ID, PFile:String1)

JOIN(Child1:Keyname, PFile:ID) !Файл Child1 имеет 4 поля

JOIN(Child2:Keyname, Child1:ID) !Файл Child2 имеет 4 поля

JOIN(Child3, 'Child3:LinkField = Child2:ID')

PROJECT(Child3:String2)

END

END

JOIN(Child2Child1:KeyName, Child1:ID) !Файл Child2Child1 имеет 4 поля

END

END

END

 

v{PROP:Fields, 0} вернет 15

v{PROP:Fields, 1} вернет 2

v{PROP:Fields, 2} вернет 4

v{PROP:Fields, 3} вернет 4

v{PROP:Fields, 4} вернет 1

v{PROP:Fields, 5} вернет 4

Смотри также : JOIN

PROP:Size

Массив, который возвращает объявленный размер заданных полей, таких как MEMO, STRING, CSTRING, PSTRING, DECIMAL или PDECIMAL.

PROP:Places

Массив, который возвращает количество десятичных позиций, объявленных для заданного поля DECIMAL или PDECIMAL.

PROP:Dim

Множественное свойство файла, которое возвращает произведение измерений массива, указанных в атрибуте DIM указанного поля. Например, для поля DIM(3,2) свойство PROP:Dim возвратит значение 6.

PROP:Over

Множественное свойство файла, которое возвращает номер поля, указанного в атрибуте OVER, стоящем на указанном поле.

Пример программы, использующий свойства структуры файла:

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

PROGRAM

MAP

PrintFile PROCEDURE(*FILE F)

DumpGroupDetails PROCEDURE(USHORT start, USHORT total)

DumpFieldDetails PROCEDURE(USHORT indent, USHORT FieldNo)

DumpToFile PROCEDURE

SetAttribute PROCEDURE(SIGNED Prop,STRING Value)

StartLine PROCEDURE(USHORT indent,STRING label, STRING type)

Concat PROCEDURE(STRING s)

END

LineSize EQUATE(255)

FileIndent EQUATE(20)

DestName STRING(FILE:MaxFilePath)

DestFile FILE,DRIVER('ASCII'),CREATE,NAME(DestName)

Record RECORD

Line STRING(LineSize)

END

END

Employee FILE,DRIVER('TOPSPEED'),NAME('Employee.tps'),PRE(EMP),BINDABLE,CREATE,THREAD

EmpID_Key KEY(EMP:EmpID),PRIMARY

EmpName_Key KEY(EMP:Lname,EMP:Fname,EMP:MInit),DUP

JobID_Key KEY(EMP:JobID),DUP

PubID_Key KEY(EMP:PubID),DUP

DateKey KEY(-EMP:Hire_date),DUP,NOCASE,OPT

Record RECORD,PRE()

EmpID CSTRING(10)

Fname CSTRING(21)

MInit CSTRING(2)

Lname CSTRING(31)

JobID SHORT

Job_lvl BYTE

PubID CSTRING(5)

Hire_date DATE

PictureFile STRING(65)

END

END

TheFile &FILE

AKey &KEY

Line STRING(LineSize)

Blobs LONG

CODE

PrintFile(Employee)

PrintFile PROCEDURE(*FILE F)

CODE

IF NOT FILEDIALOG('Choose Output File',DestName,'Text|*.TXT|Source|*.CLW',0100b)

RETURN

END

OPEN(DestFile)

IF ERRORCODE()

CREATE(DestFile)

OPEN(DestFile)

END

ASSERT(ERRORCODE()=0)

TheFile &= F

DO DumpFileDetails

DO DumpKeys

DO DumpMemos

DumpGroupDetails(0, F{PROP:Fields})

StartLine(FileIndent,'','END')

DumpToFile

DumpFileDetails ROUTINE

StartLine(FileIndent,TheFile{PROP:label},'FILE')

Concat(',DRIVER(''' & CLIP(TheFile{PROP:Driver}))

IF TheFile{PROP:DriverString}

Concat(',' & CLIP(TheFile{PROP:DriverString}))

END

Concat(''')')

SetAttribute(TheFile{PROP:Create},'CREATE')

SetAttribute(TheFile{PROP:Reclaim},'RECLAIM')

IF TheFile{PROP:Owner}

Concat(',OWNER(''' & CLIP(TheFile{PROP:Owner}) & ''')')

END

SetAttribute(TheFile{PROP:Encrypt},'ENCRYPT')

Concat(',NAME(''' & CLIP(TheFile{PROP:Name}) & ''')')

SetAttribute(TheFile{PROP:Thread},'THREAD')

SetAttribute(TheFile{PROP:OEM},'OEM')

DumpToFile

DumpMemos ROUTINE

LOOP X# = 1 TO TheFile{PROP:Memos}

StartLine(FileIndent+2,TheFile{PROP:label,-X#},'MEMO(')

Concat(CLIP(TheFile{PROP:Size,-X#})&')')

SetAttribute(TheFile{PROP:Binary,-X#},'BINARY')

IF TheFile{PROP:Name,-X#}

Concat(',NAME(' & CLIP(TheFile{PROP:Name,-X#}) & ')')

END

DumpToFile

END

DumpKeys ROUTINE

LOOP X# = 1 TO TheFile{PROP:Keys}

AKey &= TheFile{PROP:Key,X#}

StartLine(FileIndent+2,AKey{PROP:label},AKey{PROP:Type})

Concat('(')

LOOP Y# = 1 TO AKey{PROP:Components}

IF Y# > 1 THEN Concat(',').

IF AKey{PROP:Ascending,Y#}

Concat('+')

ELSE

Concat('-')

END

Concat(TheFile{PROP:Label,akey{PROP:Field,Y#}})

END

Concat(')')

SetAttribute(AKey{PROP:Dup},'DUP')

SetAttribute(AKey{PROP:NoCase},'NOCASE')

SetAttribute(AKey{PROP:Opt},'OPT')

SetAttribute(AKey{PROP:Primary},'PRIMARY')

IF AKey{PROP:Name}

Concat(',NAME(''' & CLIP(AKey{PROP:Name}) & ''')')

END

DumpToFile

END

DumpGroupDetails PROCEDURE(USHORT start, USHORT total)

fld USHORT

fieldsInGroup USHORT

GroupIndent USHORT,STATIC

CODE

IF start = 0 THEN

GroupIndent = FileIndent+2

StartLine(GroupIndent,'RECORD','RECORD')

DumpToFile

END

GroupIndent += 2

LOOP fld = start+1 TO start+total

DumpFieldDetails(GroupIndent,fld)

IF TheFile{PROP:Type,fld} = 'GROUP'

fieldsInGroup = TheFile{PROP:Fields,fld}

DumpGroupDetails (fld, fieldsInGroup)

fld += fieldsInGroup

END

END

GroupIndent -= 2

StartLine(GroupIndent,'','END')

DumpToFile

DumpFieldDetails PROCEDURE(USHORT indent, USHORT FieldNo)

FldType STRING(20)

CODE

FldType = TheFile{PROP:Type,FieldNo}

StartLine(indent,TheFile{PROP:Label,FieldNo},FldType)

IF INSTRING('STRING',FldType,1,1) OR INSTRING('DECIMAL',FldType,1,1)

Concat('(' & TheFile{PROP:Size,FieldNo})

IF FldType = 'DECIMAL' OR FldType = 'PDECIMAL'

Concat(',' & TheFile{PROP:Places,FieldNo})

END

Concat(')')

END

IF TheFile{PROP:Dim,FieldNo} <> 0

Concat(',DIM(' & CLIP(TheFile{PROP:Dim,FieldNo}) & ')')

END

IF TheFile{PROP:Over,FieldNo} <> 0

Concat(',OVER(' & CLIP(TheFile{PROP:Label,TheFile{PROP:Over,FieldNo}}) & ')')

END

IF TheFile{PROP:Name,FieldNo}

Concat(',NAME(''' & CLIP(TheFile{PROP:Name,FieldNo}) & ''')')

END

DumpToFile

SetAttribute PROCEDURE (Prop,Value)

CODE

IF Prop THEN Line = CLIP(Line) & ',' & CLIP(Value).

StartLine PROCEDURE (USHORT indent,STRING label, STRING type)

TypeStart USHORT

CODE

Line = label

IF LEN(CLIP(Line)) < Indent

TypeStart = Indent

ELSE

TypeStart = LEN(CLIP(Line)) + 4

END

Line[TypeStart : LineSize] = type

Concat PROCEDURE (STRING s)

CODE

Line = CLIP(Line) & s

DumpToFile PROCEDURE

CODE

DestFile.Line = Line; ADD(DestFile)

ASSERT(ERRORCODE()=0)

Смотри также: Динамические свойства VIEW и FILE

Файлы переменных среды

Файл, описывающий среду, содержит установки параметров, настраивающие приложение на специфику использования в конкретной стране. В начале выполнения программы, процедуры исполняющей системы пытаются обнаружить файл, описывающий среду для данной программы, который имеет такое же, как программа имя (appname.ENV) и расположен в том же каталоге. Если такого файла нет, то исполняющая система устанавливает по умолчанию стандартные установки на English/ASCII. Создав файл CLARION6.ENV можно также использовать установки, связанные с национальной спецификой (Database Manager использует эти установки, когда выводит содержимое файлов данных). Если переменная CLACHARSET установлена в OEM, то файл .ENV совместим с файлом .INI, используемым Clarion для DOS (и версии 3, и версии 3.1), потому что, вообще говоря, файл .INI подготавливается, используя набор символов OEM ASCII, а не ANSI.

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

В файле установок среды можно задать следующие переменные:

CLASYSTEMCHARSET=WINDOWS

CLASYSTEMCHARSET="charset"

Устанавливает системный набор символов. Если эта переменная не установлена или установлена Windows, то по умолчанию используется CHARSET:ANSI. Эти установки в файле .ENV эквивалентны настройкам свойства SYSTEM{PROP:CharSet}.

CLACHARSET=WINDOWS

CLACHARSET=OEM

Этот переменная определяет набор символов, используемый для элементов в файле .ENV. Если эта переменная опущена, то по умолчанию используется WINDOWS. Если для редактирования .ENV файла вы используете текстовый редактор в DOS или если этот файл должен быть совместим с Clarion для DOS, то указывайте OEM. В противном случае задавайте значение WINDOWS или опустите эту переменную. Эта переменная всегда должна быть первой переменной в файле установок среды.

CLACOLSEQ=WINDOWS

CLACOLSEQ="string"

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

Если используется значение WINDOWS, то последовательность сортировки, используемая по умолчанию, определяется установкой страны в Windows (в Панели управления). Если эта переменная в файле установок среды опущена, то по умолчанию используется последовательность сортировки в стандарте ANSI. Используя значение WINDOWS, можно при упорядочении чередовать прописные и строчные буквы (AaBbCc ...), так что программа такого типа:

CASE SomeString[1]

OF 'A' TO 'Z'

обработает также и буквы от ‘a’ до ‘y’ (буквы латинские - прим. перев). Если установлено значение WINDOWS (или другой отличный от умалчиваемого вида сортировки), то для такого типа проверок предпочтительнее использовать функции ISUPPER и ISLOWER.

Кроме значения WINDOWS можно указать строку символов (в двойных кавычках), чтобы прямо определить, какую последовательность сортировки следует использовать. В строку нужно включить только те символы, для которых надо указать новое положение при сортировке. Все остальные, не перечисленные символы остаются на своих прежних местах. Например, если задано CLACOLSEQ=’CA’. для стандартной последовательности английского алфавита (ABCD ...), то в результате последовательность станет ‘CBAD’. В этом состоит отличие этого значения от версии Clarion для DOS , в которой требуется указать точно 222 символа (но обратная совместимость обеспечивается).

ЗАМЕЧАНИЕ: Читать и писать файлы следует, всегда используя одну и ту же последовательность сортировки. Применение различных последовательностей может привести к тому, что ключи будут не отсортированы, а записи станут недоступны. Задание CLACOLSEQ = WINDOWS подразумевает, что последовательность сортировки может изменить пользователь, изменив страну в Управляющей панели Windows. Если меняется порядок сортировки – используйте BUILD для перестройки ключей в ваших файлах данных.

CLAAMPM=WINDOWS

CLAAMPM="AMstring","PMstring"

Эта переменная задает текст, используемый для обозначения времени суток (“до полудня” или “после полудня”) как части высвечиваемого времени. Значение WINDOWS указывает, что используется соответствующая установка, сделанная в Управляющей панели Windows. Значения AMстрока и PMстрока те же самые, что и в Clarion для DOS за исключением того, что учитывается значение переменной CLACHARSET.

CLAMONTH="Месяц1"," Месяц 2", ... ," Месяц 12"

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

CLAMON="СокрМесяц1"," СокрМесяц 2", ... ," СокрМесяц 12"

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

CLADIGRAPH=”ДиграфСимв1Симв2, ...

Позволяет правильно сортировать диграфы. Диграф - это логически единый символ, представляющий собой сочетание двух символов (Симв1 and Симв2). Диграфы сортируются как два символа, их составляющие. Чаще всего диграфы имеются в других языках, не в английском. Например, CLADIGRAPH="ЖAe,жae" задает, слово "Jжger" при сортировке стоит перед словом "Jager". (поскольку "Jae" идет перед "Jag"). Можно определить несколько сочетаний ДиграфСимв1Симв2, разделенных запятыми. При этом учитывается значение переменной CLACHARSET.

CLACASE=WINDOWS

CLACASE="UpperString","LowerString"

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

Значение WINDOWS подразумевает использование таких пар, определенных установкой конкретной страны в Windows (в Управляющей панели). Если эта переменная в файле .ENV опущена, то используется не принятые в Windows пары, а задаваемые стандартом ANSI.

Параметры СтрокаПрописных и СтрокаСтрочных задают набор прописных букв и соответствующие им строчные буквы. Длины этих параметров должны быть равны. При установке этой переменной следует учитывать значение переменной CLACHARSET. На ANSI символы с кодами меньше 127 эта переменная не влияет.

CLABUTTON="OK","&Yes","&No","&Abort","&Retry","&Ignore",Cancel","&Help"

Эта переменная определяет тексты, используемые кнопками, выполняющими функции сообщений. Тексты задаются в виде списка разделенных запятыми строк в следующем порядке: OK, YES, NO, ABORT, RETRY, IGNORE, CANCEL, HELP. По умолчанию используются тексты, приведенные выше.

CLAMSGerrornumber="ErrorMessage"

Эта переменная позволяет заместить во время выполнения приложения стандартные сообщения об ошибке заданными строками. Номер_ошибки представляет собой стандартный для Clarion код ошибки, присоединяемый к ключевому слову CLAMSG. “Сообщение об ошибке” - это строка, используемая для замены стандартного для ошибки с этим кодом сообщения. Например, CLAMSG2= “Файл не найден” приводит к тому, что в тех случаях, когда функция ERRORCODE() = 2, процедура ERROR() возвращает “Файл не найден”.

CLALFN=OFF

Дезактивирует все длинные имена файлов.

Пример:

CLACHARSET=WINDOWS

CLACOLSEQ="AДЕЖaабвдежBbCЗcзDdEЙeийклFfGgHhIiмнопJjKkLlMmNСnсOЦoтуфцPpQqRrSsЯTtUЬuщъыьVvWwXxYyZzя"

CLAAMPM="AM","PM"

CLAMONTH="January","February","March","April","May","June","July","August","Sep

,"October","November","December"

CLAMON="Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"

CLADIGRAPH="ЖAe,жae"

CLACASE="ДЕЖЗЙСЦЬ","дежзйсть"

CLABUTTON="OK","&Si","&No","&Abortar","&Volveratratar","&Ignora","Cancelar","&Ayuda"

CLAMSG2="No File Found"

Смотри также: LOCALE

 

Структуры для организации виртуального файла

VIEW (объявить “виртуальный” файл)

метка VIEW(первичный файл) [,FILTER( )] [,ORDER( )]

[PROJECT( )]

[JOIN( )

[PROJECT( )]

[JOIN( )

[PROJECT( )]

END]

END]

END

VIEW Объявляет “виртуальный” файл, как агрегат из связанных файлов.

метка Имя виртуального файла.

первичный файл Метка первичной структуры FILE для виртуального файла.

FILTER Объявляет выражение, используемое для отбора записей в виртуальный файл (PROP:FILTER).

ORDER Объявляет выражение или список выражений, используемых для того, чтобы определить порядок сортировки записей виртуального файла (PROP:ORDER или PROP:SQLOrder).

PROJECT Указывает поля из первичного файла или из связанного файла, указанного структурой JOIN, которые будут входить в состав виртуального файла. Если этот атрибут опущен, то доступны все поля.

JOIN Объявляет вторичный, связанный файл.

Структура VIEW объявляет виртуальный файл, как агрегат из связанных файлов. Так как структура VIEW представляет собой логическую конструкцию, элементы данных, объявленные в ней физически в этой структуре не существуют. VIEW представляет собой особый способ обращения к данным физически располагающимся в нескольких связанных структурах FILE. Во время выполнения программы структуре VIEW не выделяется память для буфера данных, так что поля, используемые в ней размещаются в буферах записей соответствующих структур FILE.

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

Для определения порядка обработки VIEW-структуры и начальной точки обработки должен присутствовать или оператор SET, поставленный на первичный файл VIEW-структуры до OPEN(view), или оператор SET(view), выполняющийся после срабатывания OPEN(view), а затем либо оператор NEXT(view), либо PREVIOUS(view), определяющие последовательный доступ ко VIEW-структуре.

Структура данных VIEW предназначена для реализации последовательного доступа, однако она допускает также и случайный доступ, реализуемый путем использования оператора REGET. Оператор REGET может использоваться для работы с VIEW-структурой, но только для определения тех записей в первичных и вторичных связанных файлах, которые должны в данный момент содержаться в соответствующих им буферах записи после того, как VIEW будет закрыт. Если непосредственно перед оператором CLOSE(view) не было выполнено никакого оператора REGET, буферы записи первичного и вторичных связанных файлов будут пусты.

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

Структура данных VIEW предназначена для того, чтобы облегчить доступ к базе данных в системах с архитектурой клиент-сервер. Она выполняет две реляционные операции одновременно: реляционные операции “соединение” и “проекция”. В клиент-серверных системах эти операции выполняются на файловом сервере, а клиенту пересылается только результат. Это может коренным образом улучшить производительность сетевой прикладной программы.

Реляционная операция “соединение” выбирает данные из нескольких файлов основываясь на определенных связях между файлами. Операцию “соединение” определяет структура JOIN в структуре VIEW. В структуре VIEW может быть несколько структур JOIN, и они могут быть вложенными одна в другую, выполняя многоуровневую операцию соединения. По умолчанию структура VIEW строится по принципу “левое внешнее присоединение”, когда получаются все записи первичного файла VIEW- структуры независимо от того, содержит или нет вторичный файл, определенный в структуре JOIN, какие-нибудь связанные записи. Для тех записей первичного файла, у которых нет связанных вторичных, значение записей вторичного файла неявно очищено (равно нулю или не заполнено). Левое внешнее присоединение можно переопределить путем задания у структуры JOIN атрибута INNER (создание “внутреннего присоединения”), так что отбираются только те записи первичного файла, у которых есть связанные записи из вторичного файла.

Реляционная операция “проекция” делает доступными только указанные элементы данных из соответствующих файлов, а не всю запись. Доступны только те поля, которые явно объявлены в операторах PROJECT. Таким образом структурой VIEW реляционная операция “проекция” реализуется автоматически. Содержимое полей, которые не описаны в PROJECT, не определено.

Атрибут FILTER ограничивает виртуальный файл подмножеством записей. Выражение в FILTER может включать любые поля, явно объявленные в структуре VIEW, и накладывает ограничения на виртуальный файл, основываясь на содержимом этих полей. Таким образом атрибут FILTER работает на всех уровнях операции “соединения”.

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

Связанные процедуры: BUFFER, CLOSE, FLUSH, OPEN, RECORDS, DELETE, HOLD, NEXT, POSITION, PREVIOUS, PUT, RELEASE, REGET, RESET, SET, SKIP, WATCH

Пример:

Customer FILE,DRIVER('Clarion'),PRE(Cus) ! Объявить структуру файла покупателей

AcctKey KEY(Cus:AcctNumber)

Record RECORD

AcctNumber LONG

OrderNumber LONG

Name STRING(20)

Addr STRING(20)

City STRING(20)

State STRING(20)

Zip STRING(20)

END

Header FILE,DRIVER('Clarion'),PRE(Hea) !Объявить структуру файла заголовков

AcctKey KEY(Hea:AcctNumber)

OrderKey KEY(Hea:OrderNumber)

Record RECORD

AcctNumber LONG

OrderNumber LONG

ShipToName STRING(20)

ShipToAddr STRING(20)

ShipToCity STRING(20)

ShipToState STRING(20)

ShipToZip STRING(20)

END

END

Detail FILE,DRIVER('Clarion'),PRE(Dtl) ! Объявить структуру файла накладных

OrderKey KEY(Dtl:OrderNumber)

Record RECORD

OrderNumber LONG

Item LONG

Quantity SHORT

END

END

Product FILE,DRIVER('Clarion'),PRE(Pro) ! Объявить структуру файла товаров

ItemKey KEY(Pro:Item)

Record RECORD

Item LONG

Description STRING(20)

Price DECIMAL(9,2)

END

END

ViewOrder VIEW(Customer) ! Объявить структуру VIEW

PROJECT(Cus:AcctNumber,Cus:Name)

JOIN(Hea:AcctKey,Cus:AcctNumber) ! Соединить с файлом заголовков

PROJECT(Hea:OrderNumber)

JOIN(Dtl:OrderKey,Hea:OrderNumber) ! Соединить с файлом накладных

PROJECT(Det:Item,Det:Quantity)

JOIN(Pro:ItemKey,Dtl:Item) ! Соединить с файлом товаров

PROJECT(Pro:Description,Pro:Price)

END

END

END

END

Смотри также: JOIN, PROJECT

 

PROJECT (задать поля виртуального файла)

PROJECT( поля )

PROJECT Объявляет поля, доступные в структуре VIEW.

поля Разделенный запятыми список полей (включая префиксы) из первичного файла или связанного файла, обозначенного в структуре JOIN, содержащей данный оператор PROJECT.

Оператор PROJECT объявляет в структуре VIEW поля выбираемые в реляционной операции “проекция”. Эта операция делает доступными только указанные поля файла, а не целую запись. Оператор PROJECT может указываться в структуре VIEW или внутри одного из ее компонентов - в структуре JOIN. Если в структуре VIEW и в ее структурах JOIN нет операторов PROJECT, то доступны все поля из файлов, составляющих виртуальный файл.

Если во VIEW-структуре или в структуре JOIN присутствует оператор PROJECT, то отобраны будут только те поля, которые явно объявлены в структуре PROJECT, содержание же всех остальных полей в соответствующем файле не определено. В зависимости от возможностей конкретного файлового драйвера, используемом вами, могут быть определены другие поля. Тем не менее, вам не следует полагаться на это как будущие изменения или изменения в драйвере баз данных могущие дать такую возможность.

Пример:

Detail FILE,DRIVER('Clarion'),PRE(Dtl) ! Объявить файл накладных

OrderKey KEY(Dtl:OrderNumber)

Record RECORD

OrderNumber LONG

Item LONG

Quantity SHORT

Description STRING(20) ! Строка описания элемента

END

END

Product FILE,DRIVER('Clarion'),PRE(Pro) ! Объявить файл товаров

ItemKey KEY(Pro:Item)

Record RECORD

Item LONG

Description STRING(20) ! Описание товара

Price DECIMAL(9,2)

END

END

ViewOrder VIEW(Detail)

PROJECT(Det:OrderNumber,Det:Item,Det:Description)

JOIN(Pro:ItemKey,Det:Item)

PROJECT(Pro:Description,Pro:Price)

END

END

 

JOIN (объявить операцию "соединение")

JOIN( | вторичный ключ ,связывающие поля | ) [, INNER ]

| вторичный файл ,выражение |

[PROJECT( )]

[JOIN( )

[PROJECT( )]

END]

END

JOIN Объявляет вторичный файл для реляционной операции “соединения”.

вторичный ключ Метка оператора KEY, которая определяет вторичный файл и ключ доступа к нему.

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

вторичный файл Метка вторичного файла.

выражение Строковая константа, содержащая единое логическое выражение для объединения файлов (PROP:JoinExpression или PROP:SQLJoinExpression). Это выражение может содержать любые логические и булевы операторы.

INNER Определяет “внутреннее присоединение” вместо используемого по умолчанию “левого внешнего присоединения”, то есть из первичного файла VIEW-структуры выбираются только те записи, у которых есть по крайней мере одна связанная запись во вторичном файле, определенном в JOIN.

PROJECT Задает поля из вторичного файла, указанного структурой JOIN, которые будут доступны в структуре VIEW. Если этот оператор опущен, то доступны все поля файла.

Структура JOIN объявляет вторичный файл для реляционной операции “соединение”. Реляционная операция “соединение”, основываясь на определенных между файлами связях, выбирает данные из нескольких файлов. В структуре VIEW может быть несколько структур JOIN, и они могут быть вложенными одна в другую, выполняя многоуровневую операцию соединения.

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

Если при выборке данных для записи первичного файла во вторичном, связанном файле, нет соответствующей записи, то полям, указанным в операторе PROJECT для этого файла, присваиваются нулевые (пробельные) значения. Этот тип реляционной операции “соединения” известен как “внешнее соединение”.

Параметр выражение позволяет соединить файлы, которые связаны полями, но не связаны между собой ключами. PROP:JoinExpression и PROP:SQLJoinExpression множественные свойства, чьи номера элементов указывают на позицию JOIN в VIEW. PROP:SQLJoinExpression это только SQL версия PROP:JoinExpression. Если первым символом выражения назначаемый PROP:JoinExpression или PROP:SQLJoinExpression является знак “плюс” (+) – новое выражение присоединяется к существующему выражению соединения.

Пример:

Customer FILE,DRIVER('Clarion'),PRE(Cus) ! Объявить структуру файла покупателей

AcctKey KEY(Cus:AcctNumber)

Record RECORD

AcctNumber LONG

OrderNumber LONG

Name STRING(20)

END

END

Header FILE,DRIVER('Clarion'),PRE(Hea) ! Объявить структуру файла заголовков

AcctKey KEY(Hea:AcctNumber)

OrderKey KEY(Hea:AcctNumber,Hea:OrderNumber)

Record RECORD

AcctNumber LONG

OrderNumber LONG

Total DECIMAL(11,2) ! Всего оплачено наличными

Discount DECIMAL(11,2) ! Величина данной скидки

OrderDate LONG

END

END

Detail FILE,DRIVER('Clarion'),PRE(Dtl) ! Объявить структуру файла накладных

OrderKey KEY(Dtl:AcctNumber,Dtl:OrderNumber)

Record RECORD

AcctNumber LONG

OrderNumber LONG

Item LONG

Quantity SHORT

END

END

Product FILE,DRIVER('Clarion'),PRE(Pro) ! Объявить структуру файла товаров

ItemKey KEY(Pro:Item)

Record RECORD

Item LONG

Description STRING(20)

Price DECIMAL(9,2)

END

END

ViewOrder1 VIEW(Header) ! Объявить структуру VIEW

PROJECT(Hea:AcctNumber,Hea:OrderNumber)

JOIN(Dtl:OrderKey,Hea:AcctNumber,Hea:OrderNumber) ! Присоединить файл Detail

PROJECT(Dtl:ItemDtl:Quantity)

JOIN(Pro:ItemKey,Dtl:Item) ! Присоединить файл Product

PROJECT(Pro:Description,Pro:Price)

END

END

ViewOrder2 VIEW(Customer) ! Объявить структуру VIEW

JOIN(Header,'Cus:AcctNumber = Hea:AcctNumber AND ' & |

' (Hea:Discount + Hea:Total) * .1 > Hea:Discount')

PROJECT(Hea:AcctNumber,Hea:OrderNumber)

JOIN(Dtl:OrderKey,Hea:AcctNumber,Hea:OrderNumber) ! Присоединить файл Detail

PROJECT(Dtl:ItemDtl:Quantity)

END

END

Смотри также: INNER

Структуры Queue

QUEUE (объявить структуру QUEUE)

метка QUEUE( [ группа ] ) [,PRE] [,STATIC] [,THREAD] [,TYPE] [,BINDABLE] [,EXTERNAL] [,DLL]

меткаполя переменная [,NAME( )]

END

QUEUE Объявляет структуру очереди в памяти.

метка Имя структуры QUEUE.

группа Метка ранее объявленной структуры GROUP или QUEUE от которой наследуется структура данных. В этом качестве могут выступать структуры GROUP и QUEUE с атрибутом TYPE.

PRE Объявляет префикс для полей в данной структуре.

STATIC Объявляет локальную по отношению к процедуре очередь, буфер которой выделяется в статической памяти.

THREAD Указывает, что память для очереди выделяется один раз для каждого исполняемого процесса. Должен использоваться с атрибутом STATIC для локальных данных процедуры.

TYPE Указывает, что данное объявление является объявлением типа для очереди, передаваемой в качестве параметра.

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

EXTERNAL Указывает, что структура QUEUE описывается во внешней библиотеке (там же выделяется память для нее).

DLL Объявляет структуру QUEUE, определенную внешне, в библиотеке DLL. Дополнительно к этому атрибуту требуется атрибут EXTERNAL.

меткаполя Имя переменной в очереди.

переменная Объявление данных. Общая длина объявляемых переменных может быть до 4 Мб.

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

Начало структуры QUEUE, объявленной с параметром группа совпадает со структурой, указываемой названной группой; данная очередь наследует поля группы, указываемой параметром группа. В структуре QUEUE могут содержаться дополнительные, собственные поля, которые следуют за наследуемыми полями. Если очередь не включает в себя любые другие поля, имя группы, которую наследует очередь, может быть использована как тип данных без ключевых слов QUEUE и END.

Очередь может рассматриваться как файл в памяти, реализованный как динамический массив из элементов очереди. При объявлении структуры QUEUE ей выделяется буфер (совсем как для файла). Каждый элемент очереди во время операций ADD или PUT сжат таким образом, чтобы занимать как можно меньше памяти, и разжимается во время операции GET. На каждый элемент очереди приходится 8 байт непроизводительных издержек для очередей с несжатыми записями и 12 байт для очередей со сжатыми записями.

Буфер данных для локальной по отношению к процедуре (объявленной в разделе данных процедуры) очереди выделяется в стеке (если не указан атрибут STATIC и элемент очереди не слишком велик). Память, выделенная для элементов локальной по отношению к процедуре очереди без атрибута STATIC, распределяется для нее только до тех пор, пока не будет выполнен оператор FREE или не завершится выполнение процедуры - в этом случае память, занимаемая очередью, освобождается автоматически.

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

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

Как только элемент добавляется в очередь, для него динамически выделяется память и данные копируются из буфера в элемент очереди и сжимаются. При удалении элемента из очереди занимаемая им память освобождается. Максимальное количество элементов в очереди теоретически составляет 2^26 (67 108 864), но в действительности зависит от доступной виртуальной памяти. Объем памяти, занимаемой каждым элементом, зависит от коэффициента сжатия данных библиотечной функцией времени исполнения.

Структура QUEUE с атрибутом BINDABLE предполагает, что все переменные из этой структуры доступны для использования в динамических выражениях, без обязательного выполнения оператора BIND для каждого поля (позволяя выполнить один оператор BIND(очередь), чтобы сделать доступными все поля из нее). Содержимое параметра NAME для каждой переменной является логическим именем, используемым в динамическом выражении. Если атрибут NAME не указан, то используется имя переменной (включая префикс). Для имен всех переменных структуры в EXE-модуле резервируется память. Это увеличивает размер программы и затраты оперативной памяти. Поэтому атрибут BINDABLE следует применять только когда большую часть составляющих структуру полей планируется использовать в динамических выражениях.

Для структуры QUEUE с атрибутом TYPE память не выделяется. Это только определение типа для очередей, передаваемых в качестве параметров в процедуры. Определение типа позволяет процедуре непосредственно адресоваться к отдельным полям переданной очереди. Объявление параметра в операторе PROCEDURE устанавливает локальный префикс для передаваемой очереди. Например, PROCEDURE(LOC:PassedGroup) объявляет, что процедура использует для непосредственного обращения к полям-компонентам передаваемой в качестве параметра структуры QUEUE префикс LOC: (вместе с именами отдельных полей, использованными в объявлении типа).

Процедуры WHAT и WHERE обеспечивают доступ к полям по их относительной позиции в структуре QUEUE.

Связанные процедуры: ADD, CHANGES, DELETE, FREE, GET, POINTER, POSITION, PUT, RECORDS, SORT

Смотри также: PRE, STATIC, NAME, FREE, THREAD, WHAT, WHERE

Пример:

NameQue QUEUE,PRE(Nam) ! Объявить очередь

Name STRING(20)

Zip DECIMAL(5,0),NAME('SortField')

END ! Конец структуры queue

NameQue2 QUEUE(NameQue),PRE(Nam2) ! Очередь, наследующая поля Name и Zip

Phone STRING(10) ! и имеющая дополнительно поле Phone

END

NameQue3 NameQue2 ! Объявить вторую точно такую же очередь

! с такой же структурой как NameQue2

 

Дополнительные сведения об очередях

Эта тема стремится развить понимание важных вопросов о поддерживаемых операторах и дополнительных параметрах, которые влияют на очередь.

ADD, GET, PUT в QUEUE по ключу

Существует 3 формы параметра ключа очереди: последовательность, строка и функция.

Каждый из них описывается следующим образом:

последовательность [±]ключ1[,[±]ключ2...]

В списке может быть до 16 меток полей очереди, разделенных запятыми и с необязательными знаками + (плюс) и – (минус) добавленные в начале меток полей. Если компонент ключа имеет знак – (минус), то это значит, что он используется в убывающем порядке. Ссылочные типы полей (включая ANY) и массивы запрещены.

имя

Строковая константа, переменная или выражение. Оно может включать в себя список до 16 атрибутов NAME полей очереди, разделенных запятыми и необязательного знака + или - , прибавленных спереди имени. Если компонент ключа имеет знак – (минус), то это значит что он используется в убывающем порядке. Ссылочные типы полей (включая ANY) и массивы запрещены.

При сравнении двух ключей, использованных в одной из форм, рассмотренных выше, ключи считаются равными, если все их компоненты равны.

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

И, наконец, ключ считается меньше другого ключа, если его n-компонент больше второго ключа и высший компонент стоит в убывающем порядке (при равенстве остальных компонентов ключа).

Есть также третья форма типов ключей для очередей:

функция

Имя функции, содержащей два параметра *GROUP или поименованная GROUP, передаваемая по адресу, и имеющая возвращаемое значение со знаком. Оба параметра должны использовать одинаковые типы параметров и не должны быть опущенными. Атрибуты RAW, C и PASCAL запрещены в объявлении прототипа.

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

Используя операторы ADD, PUT или GET функции вы можете получить позицию, номер которой возвратит функция для чтения или записи.

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

Если функция возвращает отрицательное значение, ADD или PUT записи, переданной как первый параметр, трактуется как имеющий меньшее значение чем запись, переданная как второй параметр, и записывается соответственно.

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

Использование множественных порядков сортировки

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

До Clarion 5, возможно было использовать форму GET(очередь, ключ), чтобы указать на первую или последнюю запись в диапазоне.

Например:

Q QUEUE

A LONG

B STRING(20)

END

CODE

...

SORT(Q, Q.A, Q.B) !сортировать очередь в порядке a,b

Q.A = 1 !установить первое поле

CLEAR (Q.B) !для уверенности очистить второе поле

GET (Q, Q.A) !получить первую запись

first# = POINTER(Q) !получим ошибку, но если запись будет существовать то !получим POINTER

Q.A = 5 !получить последнюю запись или за ней

CLEAR (Q.B) !снова, очищение второго поля сортировки

GET (Q, Q.A) !GET даст ошибку

last# = POINTER(Q)-1 !и вернет где будет новая запись

После выполнения этого кода, first# будет содержать указатель на первую запись поля Q.A в диапазоне (в этом примере диапазон от 1 до 4), а last# - указатель на последнюю запись со значением Q.A в этом диапазоне.

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

Следовательно, если программа использует частичное значение ключа в операторе GET(Queue,Key), логика очереди должна построить порядок сортировки основанный на указанном ключе, если он существует, и выполнить операцию GET используя этот порядок сортировки. Другими словами, GET никогда не даст ошибку.

Порядки сортировки основанные на “полном” и “частичном” ключах могут различаться, так как правила очередей гласят: ADD добавляет запись после всех других записей с таким же ключом, а PUT модифицирует существующую запись после всех других записей с таким же ключом. Новая функция POSITION(Queue) осуществляет поведение, ранее использующиеся GET на частичном ключе.

В Clarion 6, каждая активная очередь может иметь вплоть до 16 порядков сортировки, которые могут находится в памяти одновременно.

В соответствии с темой раздела, порядки сортировки не определеные как текущая активная сортировка, но находящееся в памяти предыдущее действие очереди (описанное позже), называется memory-ключ.

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

В любой момент времени существования очереди, один из memory-ключей, является “ключом по умолчанию”. Это один из ключей сортировки выполненной самой последней. Если сортировка не было сделана, “ключ по умолчанию” либо не сортирован, либо сортирован методами ADD(ключ) или PUT(ключ) (“сортировка как вам нужно”).

Несортированные ключи часто используются для операций, для которых не нужен ключ (т.е. POINTER()).

FREE() удаляет все memory-ключи.

Memory-ключ, основанный на последнем используемом ключе операторов ADD, GET, PUT или SORT, называется активным ключом. Он считается активным пока выполняется этот конкретный оператор. Если активный ключ не существует перед оператором, использующим ключ, он создается беря начальную последовательность записей отсортированных по умолчанию, и пересортировывает используя новый memory-ключ.

SORT делает активный ключ, ключом по умолчанию. Например, если активный ключ существовал перед сортировкой, пересортировка не осуществиться, так как в этом нет нужды.

GET(Queue,Key) получает первую запись используя активный ключ порядка сортировки, который совпадает с текущим содержимым буфера очереди. Если записи не найдены, буфер не изменяется и значение следующего вызова POINTER() не определено.

GET(Queue,Pointer) извлекает запись с относительной позицией равной позиции указателя в memory-ключе по умолчанию.

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

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

PUT(Queue):

Пишет запись в ту же относительную позицию в том же первичном порядке сортировки как GET или ADD работали с ней. Если первичный порядок сортировки был модифицирован со времени работы операторов GET или ADD, он отмечается как несортированный.

PUT(Queue,Pointer):

Если передаваемый указатель равен относительной позиции первичного порядка сортировки записи, получаемый в результате работы GET или ADD, то это выражение эквивалентно PUT(Queue). В противном случае, запись удаляется из старой позиции первичного порядка сортировки и помещается в позицию указанную новым значением. Если при этом нарушается первичный порядок сортировки, он помечается как несортированный.

PUT(Queue,Key)

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

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

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

ADD(Queue)

Эквивалентна ADD(Queue,RECORDS(Queue)+1)

ADD(Queue,Pointer)

Запись в буфере очереди добавляется в относительную позицию в первичном порядке сортировки. Если после этого оригинальный порядок сортировки нарушается, он помечается как несортированный.

ADD(Queue,Key)

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

Пример 1:

Q QUEUE

A LONG

B LONG

END

CODE

FREE(Q)

Q.A = 1

Q.B = 5

ADD(Q, Q.A)

Тут только один порядок сортировки, основанный на ключе (Q.A); является активным memory-ключем

SORT (Q, Q.A, Q.B)

Теперь, существует два порядка сортировки, основанные на ключах (Q.A) и (Q.A,Q.B). Последний ключ теперь является активным memory-ключом.

Порядок записей теперь:

(Q.A): (1, 5)

(Q.A,Q.B) (1, 5)

Если мы сейчас выполним:

Q.A = 1

Q.B = 1

ADD (Q, Q.A, Q.B)

Порядок станет следующим:

(Q.A): (1, 5) (1, 1)

(Q.A,Q.B): (1, 1) (1, 5)

Выполним оператор:

GET(Q, Q.A)

Получим запись (1, 5), потому что это первая запись совпадающая со значением ключа в текущем буфере очереди основанном на (Q.A)

Пример 2:

Q QUEUE

A LONG

B LONG

END

CODE

FREE(Q)

Q.A = 1

Q.B = 5

ADD (Q)

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

SORT (Q, Q.A, Q.B)

Теперь здесь один порядок сортировки основанный на ключе (Q.A,Q.B). Это теперь новый активный ключ.

Текущий порядок записей:

(Q.A,Q.B) (1, 5)

После выполнения следующего кода:

Q.A = 1

Q.B = 1

ADD (Q, Q.A, Q.B)

Новый порядок записей становится:

(Q.A,Q.B) (1, 1) (1, 5)

Выполним:

GET (Q, Q.A)

Порядок сортировки, основанный на (Q.A) не существует. Следовательно он создает новую последовательность записей в порядке по умолчанию пересортированном по ключу (Q.A).

Memory ключи после этого GET:

(Q.A) (1, 1) (1, 5)

(Q.A,Q.B) (1, 1) (1, 5)

GET получает запись (1, 1), потому что это первая запись со значением ключа, которое совпадает с текущим буфером очереди основанном на (Q.A).

к оглавлению

Знаете ли Вы, что спецификация - это документ, описывающий соглашение между разработчиками и пользователями. Разработчик берется написать модуль, а пользователь соглашается не полагаться на знания о том, как именно этот модуль реализован, т.е. не предполагать ничего такого, что не было бы указано в спецификации. Такое соглашение позволяет разделить анализ реализации от собственно использования программы. Спецификации дают возможность создавать логические основы, позволяющие успешно "разделять и властвовать".

НОВОСТИ ФОРУМА

Форум Рыцари теории эфира


Рыцари теории эфира
 10.11.2021 - 12:37: ПЕРСОНАЛИИ - Personalias -> WHO IS WHO - КТО ЕСТЬ КТО - Карим_Хайдаров.
10.11.2021 - 12:36: СОВЕСТЬ - Conscience -> РАСЧЕЛОВЕЧИВАНИЕ ЧЕЛОВЕКА. КОМУ ЭТО НАДО? - Карим_Хайдаров.
10.11.2021 - 12:36: ВОСПИТАНИЕ, ПРОСВЕЩЕНИЕ, ОБРАЗОВАНИЕ - Upbringing, Inlightening, Education -> Просвещение от д.м.н. Александра Алексеевича Редько - Карим_Хайдаров.
10.11.2021 - 12:35: ЭКОЛОГИЯ - Ecology -> Биологическая безопасность населения - Карим_Хайдаров.
10.11.2021 - 12:34: ВОЙНА, ПОЛИТИКА И НАУКА - War, Politics and Science -> Проблема государственного терроризма - Карим_Хайдаров.
10.11.2021 - 12:34: ВОЙНА, ПОЛИТИКА И НАУКА - War, Politics and Science -> ПРАВОСУДИЯ.НЕТ - Карим_Хайдаров.
10.11.2021 - 12:34: ВОСПИТАНИЕ, ПРОСВЕЩЕНИЕ, ОБРАЗОВАНИЕ - Upbringing, Inlightening, Education -> Просвещение от Вадима Глогера, США - Карим_Хайдаров.
10.11.2021 - 09:18: НОВЫЕ ТЕХНОЛОГИИ - New Technologies -> Волновая генетика Петра Гаряева, 5G-контроль и управление - Карим_Хайдаров.
10.11.2021 - 09:18: ЭКОЛОГИЯ - Ecology -> ЭКОЛОГИЯ ДЛЯ ВСЕХ - Карим_Хайдаров.
10.11.2021 - 09:16: ЭКОЛОГИЯ - Ecology -> ПРОБЛЕМЫ МЕДИЦИНЫ - Карим_Хайдаров.
10.11.2021 - 09:15: ВОСПИТАНИЕ, ПРОСВЕЩЕНИЕ, ОБРАЗОВАНИЕ - Upbringing, Inlightening, Education -> Просвещение от Екатерины Коваленко - Карим_Хайдаров.
10.11.2021 - 09:13: ВОСПИТАНИЕ, ПРОСВЕЩЕНИЕ, ОБРАЗОВАНИЕ - Upbringing, Inlightening, Education -> Просвещение от Вильгельма Варкентина - Карим_Хайдаров.
Bourabai Research - Технологии XXI века Bourabai Research Institution