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:Passed
Group) объявляется, что для непосредственного обращения к полям - компонентам переданной в качестве параметра группы, в данной процедуре используется префикс 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( [ родительский класс ] ) [,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’) !Производный от
OneClassFunc 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.FuncMESSAGE(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 и FuncClassFour.BaseProc(9) !BaseProc также обращается к ClassThree.Proc и Func
Proc(ClassFour,’Fourth Class’,10) !обращение к TwoClass.Proc (перегруженной)
OneClass.BaseProc PROCEDURE(REAL Parm) !определение OneCla
ss.BaseProcCODE
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.Nam
eGroup & 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,LO
NG Parm) ! Определение TwoClass.ProcCODE
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. Этот атрибут дополнительно требует атрибута EXTERNALOEM
Указывает, что строковые данные при чтении с диска преобразуются из 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 ! Объявить индекс по полю NameNbrNdx 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
RECORDName 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.Re
c !присвоить данные rec ArchiveArcNames.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 и 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 поля.
Тип данных, используемый объявляемым оператором.
Когда не задано никакого номера элемента массива, и в качестве цели выступает метка ключа 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} !
Вернет NULLABlob &= AFile{PROP:Blob, -1}!
Вернет NULLABlob &= AFile{PROP:Blob, 2} !ABlob
является указателем на AFile.B1ABlob &= AFile{PROP:Blob, -2}!ABlob
является указателем на AFile.B1Смотри также
: PROP:ValuePROP: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}
вернет 15v{PROP:Fields, 1}
вернет 2v{PROP:Fields, 2}
вернет 4v{PROP:Fields, 3}
вернет 4v{PROP:Fields, 4}
вернет 1v{PROP:Fields, 5}
вернет 4Смотри также
: JOINPROP: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
Produc
t 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
Смотри также:
INNERQUEUE (объявить структуру 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
...
SO
RT(Q, Q.A, Q.B) !сортировать очередь в порядке a,bQ.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, называется активным ключом. Он считается активным пока выполняется этот конкретный оператор. Если активный ключ не существует перед оператором, использующим ключ, он создается беря начальную последовательность записей отсортированных по умолчанию, и пересортировывает используя новый memo
ry-ключ.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).