КЛАССИФИКАТОРЫ И УНИВЕРСАЛЬНЫЕ СПРАВОЧНИКИ
В АБС Бисквит существует два вида справочников: Классификаторы и Универсальные справочники.
Классификатор позволяет определить набор значений соответствующий одному уникальному критерию. В качестве критерия выступает поле code.code.
Универсальный справочник (indicate), в свою очередь, позволяет определить одно единственное значение, соответствующее уникальному набору (множеству) критериев.
КЛАССИФИКАТОРЫ
Все классификаторы хранятся в таблице code, на которой в свою очередь построен одноименный класс метасхемы code.
Для начала посмотрим как же организовано ведение классификаторов в таблице code. Для примера, создадим и рассмотрим тестовый классификатор ТестКлассф следующего вида:
КОД ПАРАМЕТРА НАИМЕНОВАНИЕ ПАРАМЕТРА ЗНАЧЕНИЕ
_____________ ______________________ ____________________
1 Радел 1 1
2 Радел 2 2 >
> 2.1 Подраздел 2.1 3
> 2.2 Подраздел 2.2 4 >
>2.2.1 Подраздел 2.2.1 5
Данный классификатор в таблице code будет представлен следующим образом:
code name val class parent
___________ ______________________ _____ __________ _________
ТестКлассф Тестовый классификатор
1 Радел 1 1 ТестКлассф ТестКлассф
2 Радел 2 2 ТестКлассф ТестКлассф
2.1 Подраздел 2.1. 3 ТестКлассф 2
2.2 Подраздел 2.2. 4 ТестКлассф 2
2.2.1 Подраздел 2.2.1 5 ТестКлассф 2.2
Таким образом, по нашему примеру, можно сказать, что в базе данных хранится объявление самого классификатора (первая запись с пустым значение в поле class) и 5 объектов подкласса ТестКлассф (записи классификатора). При этом такого класса в метасхеме мы не найдем. Другими словами, наш классификатор представляет собой набор записей в таблице code объединенных по полю code.class.
При этом мы все же можем объявить в метасхеме АБС Бисквит одноименный с кодом классификатора класс, но это совсем необязательно делать, а чаще всего совсем и не нужно, ведь классификатор и так выполняет свою функцию. Что нам даст заведение класса в метасхеме и зачем это нужно?
Заведя классификатор как класс метасхемы мы во-первых получим возможность расширить его с помощью дополнительных реквизитов, а во-вторых сможем объявить ряд процедур по работе с ним в виде методов класса. Каждая запись классификатора при этом будет представлять собой отдельный объект данного класса.
На созданном классификаторе можно указать ряд процедур по работе с ним:
На основе дополнительного реквизита ГрупТабл классификаторы могут быть объединены в группы. Одной из целей данного объединения является разделение классификаторов по принадлежности к модулям АБС Бисквит.
Процедура class.p является браузером классификаторов входящих в заданную группу:
class.p (iTitle, iCodeValue, iLevel)
- iTitle - заголовок браузера классификаторов, тип CHAR;
- iCodeValue - код группы классификаторов, тип CHAR;
- iLevel - строка с которой начинается вывод браузера, тип INT64.
ПРОЦЕДУРА ПРОСМОТРА КЛАССИФИКАТОРА
Процедурой просмотра классификатора используемой по умолчанию является процедура codvlbrw.p. Данная процедура выводит значения Кода параметра (code), его Наименования (name) и Значения (val). Кроме этих полей в классификатора существуют текстовое поле-массив misc таблицы code, размер которого равен 8-ми, а так же текстовое поле-массив description, с размером равным 3-м. Таким образом, в классификаторе, помимо поля val возможно заполнение и хранение еще 11-ти основных значений. Процедура просмотра по умолчанию не выводит данные поля, для этого требуется разработка собственной экранной формы классификатора, в которой будет осуществлен их вывод, а так же формы записей классификатора.
Схема выбора процедуры просмотра:
Существует два способа организации процедуры просмотра записей в справочнике:
1-й способ - процедура просмотра.
Собственная процедура просмотра классификатора строится на основе вызова процедуры pclass.p, которая в свою очередь реализует браузер на основе navigate.cqr.
При вызове процедуры pclass.p можно передать 3-и аргумента:
- значение аргумента &ef в navigate.cqr (значение по умолчанию pclass2.uf);
- значение аргумента &look в navigate.cqr (значение по умолчанию pclass2.nav);
- произвольный аргумент и его значение передаваемое в navigate.cqr.
Так же перед вызовом процедуры pclass.p необходимо (возможно) определить ряд глобальных переменных и их значения для последующей передачи их в качестве аргументов в navigate.cqr.
Глобальная переменная | Аргумент navigate.cqr | Значение по умолчанию |
bf11 | &bf1 | "code.code code.name code.val " |
bf21 | &bf2 | "code.code code.name code.val " |
bf31 | &bf3 | "code.code code.name code.parent " |
form-brw1 | форма просмотра классификатора browse1 | |
form-brw2 | форма просмотра классификатора browse2 | |
form-brw3 | форма просмотра классификатора browse3 | |
edit1 | &edit | edit-ef.cqr |
create1 | &create | link2 &lfld = class &lfld2 = PARENT |
update1 | &update | pclass.upd |
lookup1 | &lookup | pclass.nau |
befupd1 | &befupd | pclass2.bup |
find21 | findsp.cqr &find2 |
"searchsp.cqr &file-name = CODE &sfld = NAME &metod = MATCHES &metmatch = YES" |
find31 | findsp.cqr &find3 |
"searchsp.cqr &file-name=CODE &sfld=val &metod=MATCHES &metmatch =YES" |
postfind1 | &postfind | pclass2.fnd |
join1 | &join | blank |
befjoin1 | &befjoin | pclass.bfj |
return1 | &return | return.cqr |
mydelete | &delete | pclass.del |
myprt | pclass.prt | |
eh | - | pclass.eh~032 |
fieldcode | - | code.code |
Пример собственной процедуры просмотра классификатора:
test-code.p
&GLOBAL-DEFINE bf11 "code.code code.misc[1] code.misc[2] code.misc[3] code.misc[4] "
&GLOBAL-DEFINE form-brw1 test-code.frm /* Form для navigate.cqr */
&GLOBAL-DEFINE form-edit test-code.edf
{pclass.p
"test-code.uf"
"test-code.nav"
}
test-code.frm
FORM
code.code
COLUMN-LABEL "П/Н"
HELP "Порядковый номер"
FORMAT "x(3)"
code.misc[1]
COLUMN-LABEL "ПРОДУКТ"
HELP "Тип продукта"
FORMAT "x(30)"
code.misc[2]
COLUMN-LABEL "КЛАССЫ МЕТАСХЕМЫ"
HELP "Список классов метасхемы в формате CAN-DO"
FORMAT "x(30)"
code.misc[3]
COLUMN-LABEL "ТИП КРЕДИТА"
HELP "Тип кредита в формате CAN-DO"
FORMAT "x(10)"
code.misc[4]
COLUMN-LABEL "ТИП КЛИЕНТА"
HELP "Тип клиента Ч/Ю"
FORMAT "x(10)"
WITH FRAME browse1 WIDTH 131 TITLE "".
test-code.uf
code.code
LABEL "П/Н"
HELP "Порядковый номер"
FORMAT "x(3)"
VIEW-AS FILL-IN SIZE 40 BY 1
code.misc[1]
LABEL "ПРОДУКТ"
HELP "Тип продукта"
FORMAT "x(100)"
VIEW-AS FILL-IN SIZE 40 BY 1
code.misc[2]
LABEL "КЛАССЫ МЕТАСХЕМЫ"
HELP "Список классов метасхемы в формате CAN-DO"
FORMAT "x(100)"
VIEW-AS FILL-IN SIZE 40 BY 1
code.misc[3]
LABEL "ТИП КРЕДИТА"
HELP "Тип кредита в формате CAN-DO"
FORMAT "x(100)"
VIEW-AS FILL-IN SIZE 40 BY 1
code.misc[4]
LABEL "ТИП КЛИЕНТА"
HELP "Тип клиента Ч/Ю"
FORMAT "x(1)"
VIEW-AS FILL-IN SIZE 40 BY 1
test-code.edf
FORM
{test-code.uf}
WITH FRAME edit.
test-code.nav
DISPLAY
{test-code.uf}
WITH FRAME edit.
IF LASTKEY EQ KEYCODE("F1") THEN
PAUSE.
ELSE
WAIT-FOR GO OF FRAME edit.
HIDE FRAME edit.
2-й способ - класс метасхемы.
Данный метод работы с классификатором основывается на том, что он будет заведен как отдельный класс метасхемы (подкласс класса Сode). Таким образом, дальнейшая работа с классификатором строится на его методах, в частности на методах browse (браузер классификатора) и form (форма редактирования записей классификатора). При этом на самом классификаторе, в качестве процедуры просмотра необходимо указать: __MTX (предполагаю, что данный признак выбран исходя из сокращения МеTасXема).
Код класса классификатора должен быть аналогичен коду классификатора, для нашего примера нам необходимо создать класс с кодом ТестКлассф.
метод browse:
{globals.i}
{flt-file.i}
FORM
code.code
COLUMN-LABEL "П/Н"
HELP "Порядковый номер"
FORMAT "x(3)"
code.misc[1]
COLUMN-LABEL "ПРОДУКТ"
HELP "Тип продукта"
FORMAT "x(30)"
code.misc[2]
COLUMN-LABEL "КЛАССЫ МЕТАСХЕМЫ"
HELP "Список классов метасхемы в формате CAN-DO"
FORMAT "x(30)"
code.misc[3]
COLUMN-LABEL "ТИП КРЕДИТА"
HELP "Тип кредита в формате CAN-DO"
FORMAT "x(10)"
code.misc[4]
COLUMN-LABEL "ТИП КЛИЕНТА"
HELP "Тип клиента Ч/Ю"
FORMAT "x(10)"
WITH FRAME browse1 WIDTH 131
TITLE COLOR BRIGHT-WHITE
"[ " + CAPS(GetFltVal ("title")) + " ]".
{qrdef.i
&buff-list = "code"
&Fields-Mandatory = "class,parent"
}
{navigate.cqr
&file = code
&files = "code"
&filt = yes
&bf1 = "code.code code.misc[1] code.misc[2] code.misc[3] code.misc[4] "
&cf1 = "code.code code.misc[1] code.misc[2] code.misc[3] code.misc[4] "
&edit = "bis-tty.ef "
&before-run-method = "brwresln.bfe "
&look = "bis-tty.nav "
&class_avail = "'ТестКлассф'"
&SpecClass = "'ТестКлассф'"
}
метод form:
{globals.i} /* Глобальные переменные сессии. */
{formpar.i}
{intrface.get tmess} /* Инструменты обработки сообщений. */
{intrface.get xclass} /* Библиотека инструментов метасхемы. */
DEF VAR in-class AS CHAR NO-UNDO.
DEF VAR in-parent AS CHAR NO-UNDO.
DEF VAR mScreenValue AS CHAR NO-UNDO.
FORM
code.code
LABEL "П/Н"
HELP "Порядковый номер"
FORMAT "x(3)"
VIEW-AS FILL-IN SIZE 40 BY 1
code.misc[1]
LABEL "ПРОДУКТ"
HELP "Тип продукта"
FORMAT "x(100)"
VIEW-AS FILL-IN SIZE 40 BY 1
code.misc[2]
LABEL "КЛАССЫ МЕТАСХЕМЫ"
HELP "Список классов метасхемы в формате CAN-DO"
FORMAT "x(100)"
VIEW-AS FILL-IN SIZE 40 BY 1
code.misc[3]
LABEL "ТИП КРЕДИТА"
HELP "Тип кредита в формате CAN-DO"
FORMAT "x(100)"
VIEW-AS FILL-IN SIZE 40 BY 1
code.misc[4]
LABEL "ТИП КЛИЕНТА"
HELP "Тип клиента Ч/Ю"
FORMAT "x(1)"
VIEW-AS FILL-IN SIZE 40 BY 1
WITH FRAME edit TITLE COLOR bright-white "".
MAIN:
DO:
IF iSurrogate GT "" THEN DO:
FIND FIRST code WHERE
code.class EQ ENTRY(1,iSurrogate)
AND code.code EQ ENTRY(2,iSurrogate)
NO-LOCK NO-ERROR.
IF NOT AVAIL code THEN
LEAVE MAIN.
ASSIGN
in-rec-id = RECID(code)
in-class = code.class
in-parent = code.parent
.
RELEASE CODE.
END.
ELSE
ASSIGN
in-class = ENTRY(2,iInstanceList,CHR(3))
WHEN NUM-ENTRIES(iInstanceList,CHR(3)) GT 1
in-parent = ENTRY(3,iInstanceList,CHR(3))
WHEN NUM-ENTRIES(iInstanceList,CHR(3)) GT 2
.
FRAME edit:TITLE = "[ " + (IF iMode = 'F1'
THEN 'ПРОСМОТР'
ELSE IF iMode = 'F9'
AND in-rec-id NE 0
THEN 'РЕДАКТИРОВАНИЕ'
ELSE 'СОЗДАНИЕ') + ' КОДА КЛАССИФИКАТОРА ]'.
{rec-ed.i
&file = code
&ModView = YES
&ef = "brwcode.ef "
&create = "link2 &lfld=class &lfld2=parent "
}
END.
{intrface.del} /* Выгрузка инструментария. */
brwcode.ef
code.code
code.misc[1]
code.misc[2]
code.misc[3]
code.misc[4]
После написания процедур методов Browse и Form необходимо переопределить их на классе классификатора в метасхеме. Остальные методы класса классификатора должны быть унаследованы от класса Code.
Для вызова процедуры просмотра (браузера) заданного классификатора, независимо от способа ее реализации, удобно воспользоваться процедурой codvalgt.p, которая в свою очередь является прослойкой для вызова процедуры codelay.p.
codvalgt.p (iClass, iLevel)
- iClass - код классификатора, тип CHAR;
- iLevel - строка с которой начинается вывод браузера, тип INT64.
ПРОЦЕДУРА УДАЛЕНИЯ
Процедура удаления осуществляет контроль при удалении записи классификатора. Удаляемая запись классификатора может иметь связь с другими объектами и ее удаление может оказаться критическим.
Процедура удаления должна обладать следующими входными параметрами:
DEF INPUT PARAM iClass AS CHAR NO-UNDO.
DEF INPUT PARAM iCode AS CHAR NO-UNDO.
DEF INPUT PARAM iLevel AS CHAR NO-UNDO.
ПРОЦЕДУРА СОЕДИНЕНИЯ
Процедурой соединения является процедура вызываемая из пункта меню "Связи" на записях классификатора. Данная процедура должна обладать следующими входными параметрами.
DEF INPUT PARAM iProc AS CHAR NO-UNDO.
DEF INPUT PARAM iCode AS CHAR NO-UNDO.
DEF INPUT PARAM iLevel AS CHAR NO-UNDO.
ТЕМПОРИРОВАННЫЕ КЛАССИФИКАТОРЫ
Классификатор в АБС Бисквит может быть темпорированным, т.е. записи которого определяются на указываемый период времени.
Данные классификаторы являются поклассами класса tmp-code построенного на одноименной таблице и являющегося в свою очередь подклассом класса code. В отличие от класса code на классе tmp-code введены еще два основных реквизита beg-date и end-date, определяющие период действия записи классификатора.
При заведении темпорированного классификатора в браузере классификаторов вызываемого из меню "Классификаторы" раздела "Справочники" запись о нем формируется в таблице code с указанием кода создаваемого классификатора (поле class будет пустым), аналогично обычному классификатору, а записи его значений будут формироваться в таблице tmp-code.
На темпорированном классификаторе заполняется доп. реквизит class-code с указанием класса к которому он относится и указывается универсальная процедура просмотра - tmpcode. Данная процедура по значению доп. реквизита class-code определяет класс классификатора и далее осуществляет вызова соответствующего этому классу метода browse, который в свою очередь выводит записи значений данного классификатора из таблицы tmp-code.
Для работы с темпорированными классификаторами применяется библиотека интерфейсов pp-tmcod, которая на текущий момент содержит одну единственную функцию:
getTCodeFld (iField, iClass, iCode, iSince) - возвращает значение указанного поля классификатора заданного кода параметра из таблицы tmp-code .
- iField - код поля таблицы tmp-code, тип CHAR;
- iClass - код классификатора, тип CHAR;
- iCode - код параметра классификатора, тип CHAR;
- iSince - дата на которую определяется код параметра, тип DATE.
УНИВЕРСАЛЬНЫЕ СПРАВОЧНИКИ
Запись раздела indicate (универсальные справочники) хранится в таблице code и видна в браузере классификаторов вызываемого из меню "Классификаторы" раздела "Справочники". При этом, сами универсальные справочники являются классами данных финансовой отчетности и анализа.
Код универсального справочника является кодом класса данных (DataClass). Описание правила справочника, представляет собой набор атрибутов класса данных (DataAttr). Разделы с датами на которые определены наборы значений справочника - блоки данных (DataBlock), а значения правила справочника записываются в таблицу DataLine.
В метасхеме АБС Бисквит универсальные справочники представлены следующими классами:
- Indication - Справочники;
- IndicationAttr - Описание правила;
- IndicationBlock - Правила справочника;
- IndicationLine - Значение справочника.
Работа с универсальными справочниками осуществляется с помощью следующих инструментов:
- библиотека процедур и функций для работы с универсальными справочниками;
- indicatetable.cls - класс ООП;
- indicate.fun - набор функций по работе с универсальными справочниками.
ИМПОРТ ЗНАЧЕНИЙ УНИВЕРСАЛЬНОГО СПРАВОЧНИКА
В АБС Бисквит существует процедура txt2refer.p импорта значений классификатора из *.csv файла с разделителем ";".
Структура импортируемого файла должна соответствовать описанию справочника, т.е. последовательность полей в файле должна быть такой как в описании правила. Последним полем в файле может быть указанно поле "Комментарий". Кодировка файла должна быть windows 1251.
При импорте файла необходимо указать существующую дату значений справочника. Если в файле указанно поле комментарий, то в меню процедуры необходимо становить соответствующий флажок.
Для импорта значений в справочник Касса с описанием:
√ КОД НАЗВАНИЕ
─ ────────── ────────────────────────
Отделение Отделение
currency Код валюты
Дневная Дневная
acct Номер лицевого счета
необходимо создать например следующий файл:
9999;810;Нет;20202810000000000001;Коментарий 1
9999;810;Да ;20202810000000000002;Коментарий 2
9999;840;Да ;20202840000000000001;Коментарий 3
9999;978;Да ;20202978000000000001;Коментарий 4