МЕТОД BROWSE КЛАССОВ МЕТАСХЕМЫ (NAVIGATE.CQR)

Одним из основных визуальных инструментов по работе с данными в АБС Бисквит являются браузеры. Источниками данных, выводимых в браузере, могут выступать как данные из таблиц базы данных, временных  таблиц, так и различные расчетные значения.

Navigate.cqr является универсальным инклюд-файлом на основе которого в АБС Бисквит построено большинство браузеров объектов классов метасхемы - методов browse классов метасхемы.

В navigate.cqr объявлен входной параметр level типа INT64, предназначенный для указания уровня (строки) вывода браузера, который автоматически становится входным параметром процедуры, в которой подключен navigate.cqr.


БРАУЗЕР ВРЕМЕННОЙ ТАБЛИЦЫ


Для начала определим временную таблицу и заполним ее. Для примера, создадим таблицу, tt-acct, содержащую следующие поля: ID клиента, наименование  клиента, счет, валюту счета, и отделение, к которому относится данный счет. Заполним нашу таблицу информацией по счетам юридических лиц открытых "сегодня".

{globals.i}
{navigate.def}
{sh-defs.i}  /* Для остатка по счету */

DEF VAR mAcctPos AS DEC  FORMAT "->,>>>,>>9.99"
                         LABEL "ОСТАТОК"
                         NO-UNDO.

DEF TEMP-TABLE tt-acct NO-UNDO
   FIELD cust-name AS   CHAR
   FIELD acct      LIKE acct.acct
   FIELD currency  LIKE acct.currency
   FIELD cust-id   LIKE acct.cust-id
   FIELD branch-id LIKE acct.branch-id
.

FOR EACH acct WHERE acct.cust-cat = "Ю" AND open-date = TODAY:
   FIND cust-corp OF acct.
     CREATE tt-acct.
ASSIGN
        tt-acct.cust-name = cust-corp.cust-stat + " " + cust-corp.name-corp
        tt-acct.acct      = acct.acct
        tt-acct.currency  = acct.currency
        tt-acct.cust-id   = acct.cust-id
        tt-acct.branch-id = acct.branch-id
     .
END. 

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

FORM
   tt-acct.cust-name                   /* Наименование клиента */
      COLUMN-LABEL "Клиент"  
      HELP "Наименование клиента"
      FORMAT "x(30)"
   tt-acct.acct                        /* Счет                 */
      COLUMN-LABEL "Счет"
      HELP "Счет"
      FORMAT "x(20)"
   tt-acct.currency                    /* Валюта счета         */
      COLUMN-LABEL "Валюта"
      HELP "Код валюты счета"
   mAcctPos                            /* Доступный остаток    */      
     COLUMN-LABEL "Остаток"
     HELP "Доступный остаток"
WITH FRAME browse1 OVERLAY
                   WIDTH 80
                   TITLE COLOR bright-white "[ Мой браузер ]"
                   15 DOWN.

Таким образом, наш браузер будет выводиться в FRAME browse1. Форм браузера может быть определено несколько и они могут сменяться в процессе отображения браузера по нажатию F3. Каждая последующая форма должна выводиться в соответствующем ее номеру FRAME: browse1, browse2 и т.д. Определить с какой формой будет запускаться браузер, можно указав ее порядковый номер в аргументе &first-frm.

Для примера, определим еще одну форму браузера, в которой последним выводимым полем будет не "Остаток", а "Подразделение" счета.

FORM
   tt-acct.cust-name                   /* Наименование клиента */
      COLUMN-LABEL "Клиент"  
      HELP "Наименование клиента"
      FORMAT "x(30)"
   tt-acct.acct                        /* Счет                 */
      COLUMN-LABEL "Счет"
      HELP "Счет"
      FORMAT "x(20)"
   tt-acct.currency                    /* Валюта счета         */
      COLUMN-LABEL "Валюта"
      HELP "Код валюты счета"
   tt-acct.branch-id                   /* Подразделение        */      
     COLUMN-LABEL "Подразделение"
     HELP "Подразделение"
WITH FRAME browse2 OVERLAY
                   WIDTH 80
                   TITLE COLOR bright-white "[ Мой браузер ]"
                   15 DOWN.

Далее нам необходимо создать запрос (QUERY) для браузера. Для этого будем использовать инклюд-файл qrdef.i. Подробное описание данного инклюд-файла дано в статье МЕТОД BRWQUERY.

В браузере мы будем выводить все записи временной таблицы tt-acct.

{qrdef.i
&buff-list = "tt-acct"
&join-list = "each"
}

Таким образом, мы получим следующий запрос:

FOR EACH tt-acct WHERE NO-LOCK INDEXED-REPOSITION

============ INDEX INFORMATION ==================

TABLE-NAME   INDEX-NAME           FIELD-NAME
------------ -------------------- ---------------
tt-acct      WHOLE-INDEX,default

Теперь наступает момент вызова самого браузера.

{navigate.cqr
   &WORKFILE  = "/*"
   &file      = tt-acct
   &first-frm = 1
   &maxfrm    = 2
   &oth3      = "frames.cqr "
   &oh3       = "│F3 форма"
   &bf1       = "tt-acct.cust-name tt-acct.acct tt-acct.currency mAcctPos"
   &cf1       = "tt-acct.cust-name tt-acct.acct "
   &bff2      = "gt_nav.lf2 "
   &postfind  = "mypostfind.cqr "
}

Определение остатка по счету опишем в отдельном файле mypostfind.cqr:

FIND FIRST acct WHERE acct.acct      EQ tt-acct.acct
                  AND acct.currency  EQ tt-acct.currency
                NO-LOCK NO-ERROR.

IF AVAIL acct THEN
DO:
   RUN acct-pos-exc-cr IN h_base (acct.acct,
                                  acct.currency,
                                  TODAY,
                                  "П").
                
   mAcctPos =       IF acct.currency   EQ ''
              THEN  (IF acct.side EQ 'А'
                    THEN sh-bal
                    ELSE sh-bal * (-1))
              ELSE  (IF acct.side EQ 'А'
                    THEN sh-val
                    ELSE sh-val * (-1)).

END.
ELSE
   mAcctPos = 0.

Так как у нас определено две формы, то &maxfrm = 2. Смена форм по нажатию F3 осуществляется штатным БИСовским механизмом frames.cqr. 

В &bf1, &bf2, и т.д. указываются списки полей соответствующих номеру форм, именно в той последовательности, в какой они объявлены в формах. Для удобства можно использовать отдельный файл в котором перечисляются поля (в столбец) соответствующей формы. В таком случае ссылку на файл с полями для соответствующей формы необходимо указать в &bff1, &bff2, и т.д.

В нашем примере, поля первой формы мы указали в &bf1, а второй формы в файле mynav.lf2 (&bff2 = "mynav.lf2 ").

файл mynav.lf2:

tt-acct.cust-name 
tt-acct.acct
tt-acct.currency

&cf1, &cf2 и т.д. указываются списки полей соответствующей по номеру формы, поля которых доступны для перехода на них курсора. Если данный список не указан для формы, то по умолчанию все поля формы будут доступны для перевода на них курсора. Для удобства так же как и списки полей форм, данные поля могут быть указанны в отдельном файле. В таком случае ссылку на файл с полями для соответствующей формы необходимо указать в &сff1, &сff2, и т.д.

В нашем примере, для первой формы только поля "Клиент" и "Счет" доступны для перевода на них курсора, так как только эти поля указаны в списке &cf1. На другие поля курсор переведен быть не может. Поля второй формы доступны полностью, так как мы не определяли для нее соответствующий список &cf2 (&cff2). 


&look - инклюд-файл, триггер обрабатывающий нажатия F1


В значение аргумента &look указывается инклюд-файл, в котором описывается  триггер события нажатия клавиши F1 в браузере.

Как принято в АБС Бисквит, по нажатию F1 в браузере вызывается форма просмотра объекта, на котором находится курсор.

Допустим, что мы хотим, чтоб при нажатии F1 на наименовании клиента в нашем браузере открывалась карточка клиента, а при F1 на счете - карточка счета.

Создадим следующий инклюд-файл с именем mylook.cqr:

IF KEYLABEL(LASTKEY) EQ "F1" THEN 
DO:
   IF FRAME-FIELD EQ 'cust-name' THEN
   DO:
      RUN formld.p ("cust-corp",
                    STRING(tt-acct.cust-id),
                    "",
                    {&MOD_VIEW},
                    4).
   END.

   IF FRAME-FIELD EQ 'acct' THEN
   DO:
      RUN formld.p ("acct",
                    tt-acct.acct + "," + tt-acct.currency,
                    "",
                    {&MOD_VIEW},
                    4).
   END.
END.

В зависимости от того, на каком поле (на наименовании клиента, или счете) производится нажатие F1, вызывается соответствующий метод FORM соответствующего класса (cust-corp или acct).

Укажем данный инклюд-файл в качестве значения аргумента &look.

&look = "mylook.cqr "       

Обращаю внимание на наличие пробела перед закрывающей " - он обязателен.


&edit - инклюд-файл, триггер обрабатывающий нажатия F9 и INS


В данном инклюд-файле обрабатывается редактирование (нажатие F9) и добавление новой записи (INS).

Создадим следующий инклюд-файл с именем myedit.cqr:

IF KEYLABEL(LASTKEY) EQ "F9" THEN 
DO:
   RUN formld.p ("acctb",
                 tt-acct.acct + "," + tt-acct.currency,
                 "",
                 {&MOD_EDIT},
                 4).

END.

IF KEYLABEL(LASTKEY) EQ "INS" THEN
DO:
   RUN formld.p ("acctb",
                 "",
                 "",
                 {&MOD_ADD},
                 4).
END.

Укажем данный инклюд-файл в качестве значения ключа &edit .

&edit = "myedit.cqr " 

Одним из универсальных инклюд-файлов редактирования и добавления записей в АБС Бисквит является edit-ef.cqr. Данный инклюд-файл принимает следующие аргументы:

  • &create - инклюд-файл с кодом отвечающим за создание записи;
  • &update - инклюд-файл с кодом отвечающим за редактирование записи.


&nodel - удаление записей


Значением аргумента &nodel может быть только YES. Определение данного аргумента отключает реакцию браузера на событие нажатия клавиши DEL, если конечно триггер этого события не был определен в одном из аргументов &othN.

Если аргумент &nodel не определен, то автоматически триггером события DEL является инклюд-файл delete.cqr.


&print - инклюд-файл, триггер обрабатывающий нажатия CTRL+G


Если данный аргумент не задан, то по умолчанию, в качестве триггера события нажатия CTRL+G в браузере будет применен инклюд-файл print.cqr. Данный инклюд-файл формирует печатную форму содержимого браузера в PREVIEW.


&join - инклюд-файл, связанное меню


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

Основным таким файлом является join.cqr

Аргументы join.cqr:

  • &title - заголовок меню;
  • &numch - кол-во пунктов меню;
  • &choices - список наименований пунктов меню (разделитель запятая);
  • &progs - список вызываемых процедур без расширения .p (разделитель запятая);
  • &parms - параметры процедур;
  • &jwidth - ширина меню в символах (по умолчанию - 40);
  • &userfun - пользовательский код выполняемый перед вызовом процедур пунктов меню.

В &progs указывается список процедур соответствующих пунктам меню, при этом все процедуры должны обладать единым набором параметров указываемых в &parms.

При выборе пользователем какого-либо из пунктов меню будет осуществлен вызов соответствующей этому пункту процедуры из списка &progs с передачей ей всех параметров указанных в &parms.

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

Укажем данный инклюд-файл в качестве значения аргумента &join.

&join = "join.cqr "
   &title   = "[ "" + DelFilFromAcct(acct.acct) + "" ]"
   &numch   = 2
   &progs   = ","
   &parms   = " "
   &jwidth  = 24 
   &choices = "Доп. реквизиты счета,Доп. реквизиты клиента"
  &userfun = "
              IF menu_idx = 1 THEN
                  RUN xattr-ed.p ('acct',
                                  tt-acct.acct + ',' + tt-acct.currency,
                                  DelFilFromAcct(tt-acct.acct),
                                  'NO',
                                  3). ELSE ~
              IF menu_idx = 2 THEN
                  RUN xattr-ed.p ('cust-corp',
                                  STRING(tt-acct.cust-id),
                                  STRING(tt-acct.cust-id),
                                  'NO',
                                  3). ELSE ~
             " 


&return - инклюд-файл, для возвращаемого значения (pick-value)


Когда требуется чтоб по нажатию Ctrl+Enter на записи в браузере формировалось значение переменной pick-value соответствующее данной записи, необходимо создать инклюд-файл формирующий это значение.

Предположим, что значение pick-value необходимо формировать на основе "счет,код валюты".

Создадим следующий инклюд-файл с именем myreturn.cqr:

IF LASTKEY EQ 10 THEN
DO:   
   pick-value = tt-acct.acct + "," + tt-acct.currency.
   LEAVE REFRESH.
END.

Укажем данный инклюд файл в качестве значения ключа &return.

&return  = "myreturn.cqr " 

Обращаю внимание на наличие пробела перед закрывающей " - он обязателен


&tmprecid -  отбор записей


Для возможности помечать записи и переноса их в во временную таблицу tmprecid необходимо указать значение аргумента  &tmprecid = YES.

При этом в браузере будет сформирована еще одна колонка (последняя справа) с отметками "√".


&total - итоговые значения


Аргумент &total определяет инклюд-файл осуществляющий вывод итоговых значений браузера по нажатию "+". Стандартным инклюд-файлом в БИСквит является total.cqr.

&total = "total.cqr "
   &cfldx = "mAcctPos"
   &dfldx = "mAcctPos"
  • &cfldx - список полей для суммирования;
  • &dfldx - список полей для отображения;
  • &AdvCond - альтернативные условия вызова формы итоговых значений (например, нажатие иных клавиш, отличных от "+").

Таким образом, мы получили простой браузер по нашей временной таблице, в котором возможен поиск записи по F7, быстрый поиск, сортировка записей по SHIFT+F6.


БРАУЗЕР ОБЪЕКТОВ КЛАССА МЕТАСХЕМЫ (МЕТОД BROWSE)


До этого мы достаточно подробно рассмотрели построение браузера временной таблицы. В чем же отличие при построении браузера объектов класса метасхемы?

Отличие заключается в том, что для класса метасхемы определяются методы, которые выносят логику той или иной функции navigate.cqr в отдельные подключаемые процедуры.

Если при построении браузера временной таблицы для формирования запроса мы подключали qrdef.i, то при построение браузера объектов класса метасхемы логика построения запросов может быть вынесена в процедуру метода BrwQuery. При этом в navigate.cqr необходимо определить 2-а аргумента:

  • &query-proc = YES - признак того, что запрос формируется во внешней компоненте;
  • &nav-buf-list = "<список буферов, которые могут участвовать в запросе>".

Для браузера объектов классов метасхемы может быть определен фильтр, структура которого описывается в процедуре МЕТОДА FLTSTRUCT. При этом в начале процедуры браузера необходимо подключить инклюд-файл flt-file.i, а так же задать в navigate.cqr следующие аргументы:

  • &filt      = YES
  • &oh6    = "│F6 фильтр"
  • &oth6   = "flt-file.f6 "

Если в фильтре предполагается возможность задания доп. реквизитов, то для формирования выражения запроса по ним необходимо указать &AutoSigns = YES.

Еще одной превычной функцией в браузере является меню вызываемое по F2. Такое меню строится на основе процедуры messmenu.p и оформляется в виде инклюд-файла, указываемого в аргументе &oth2.

ELSE IF lastkey EQ KEYCODE("F2")
   AND favail()
THEN
DO:
   pick-value = "0".
   RUN messmenu.p (10,
                  "[ Операции с частными вкладами ]",
                  "",
                  "1. Дополнительные реквизиты," +
                  "2. Другое действие").
   IF KEYFUNCTION(LASTKEY) EQ "end-error"
   THEN NEXT ACTION.

   /* 1. Дополнительные реквизиты */
   ELSE IF pick-value EQ "1"
   THEN
   DO:
      RUN SignRatSelectAttr.
      IF return-value eq "yes"
      THEN NEXT REFRESH.
      ELSE NEXT ACTION.
   END.

   /* 2. Другое действие. */
   ELSE IF pick-value EQ "2"
   THEN
   DO:
  
   END.
END.

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

  • подключить xsignrat.def вначале процедуры метода browse;
  • указать xsigns.rat в одном из аргументов &othN;
  • указать аргумент &startup = "xsignrat.st ".

Подключаемому xsigns.rat необходимо указать следующие аргументы:

  • &rat_file - таблица объектов браузера;
  • &rat_class - класс объекта ("loan.class-code");
  • &rat_upclass - основной класс браузера ("mClass");
  • &rat_surr - суррогат объекта ("loan.contract + ',' + loan.cont-code ");
  • &rat_num - порядковый номер фрэйма browseN, который будет использоваться для выбора объектов, которым необходимо изменить доп. реквизит;
  • &rat_key - функциональная клавиша (F2).

Форма фрейма указанная в &rat_num обязательно должна содержать поле signs_value, в котором будут выводиться значения изменяемого доп. реквизита.

Как правило, в браузерах объектов класса метасхемы триггер печати (CTRL+G) осуществляет вызов меню раздела печати, содержащее различные процедуры обработки отобранных записей. Т.е. в аргументе &print указывается специальный инклюд-файл выводящий данное меню, а не print.cqr. 

Примеры таких файлов в АБС Бисквит имеют расширение *.prt. Для примера, приведем один из вариантов данного триггера:

ELSE IF LASTKEY = KEYCODE("CTRL-G") THEN
DO:

   IF NOT CAN-FIND(FIRST tmprecid) THEN RUN CreateTmpRecid.
   RUN nav-menu.p ("ПРОЦЕДУРЫ ПЕЧАТИ", work-parent, 7).
   RUN DeleteTmpRecid.
   NEXT REFRESH.
END.

В завершение хотелось бы рассказать об одной маленькой хитрости. В метасхеме АБС Бисквит возможно объявление абстрактных классов, которые не связаны с таблицей БД, но для которых возможно задать набор методов. Так вот, метод browse такого класса может быть браузером временной таблицы. При этом на классе так же можно задать метод fltstruct и как следствие получить возможность построения фильтра для браузера временной таблицы. В качестве примеров таких классов можно посмотреть подклассы класса autodoc (Автодокументирование).

Описание основных ключей navigate.cqr:

Аргумент Описание
&file основная таблица, по которой строится браузер
&files список таблиц или буферов, используемых в браузере, разделитель пробел, по умолчанию равен &file
&workfile указывается, если таблицей браузера является временная таблица (TEMP-TABLE), значение может быть только "/*"
&startup инклюд-файл, выполняемый перед отображением браузера
&refresh инклюд-файл, выполняемый перед обновлением браузера
&refrbrow инклюд-файл, выполняемый во время обновления браузера
&repaint инклюд-файл перерисовки полей в браузере, используется для расцветки и для отображения полей в специальном формате
&postfind инклюд-файл определения рассчитываемых полей, кроме полей, указанных в &CalcFld
&total инклюд-файл для отображения итогов по записям
&release инклюд-файл для отпуска записи
&ohN часть строки помощи в подстрочнике, описывающая клавишу и действие &othN
&othN инклюд-файл обрабатывающий нажатия специальных клавиш,
далее идут парами &oh1 и &oth1, ... ,&oh9 и &oth9.
Формы браузера
&first-frm номер формы, с которой запускается браузер, может быть переопреден полем FirstFrame фильтра
&exclfrm список исключаемых форм, разделитель запятая
&maxfrm максимальное количество форм (ключей &bfN)
&bfN список полей формы N, должен быть в таком же порядке как и в форме, разделитель пробел
&cfN список выбираемых полей формы N, указывается если курсор не должен перемещаться на некоторые поля
Триггеры (action.cqr)
&look инклюд-файл, обрабатывающий нажатия F1 (методы Look, Form)
&befupd инклюд-файл, выполняемый перед редактированием записи
&edit инклюд-файл, для редактирования и создания записей (методы Modify, Form)
&nodel отключает возможность удаление записей, может быть только YES
&befdel инклюд-файл, выполняемый перед удалением записи
&delete инклюд-файл, для удаления записи
&befjoin инклюд-файл, выполняемый перед связанным меню
&join инклюд-файл связанного меню (метод Join)
&query-proc
&nav-buf-list
&query-proc = YES признак того, что QUERY строиться в отдельной процедуре метода; &nav-buf-list - список буферов. (метод Brwquery)
&print инклюд-файл печати
Фильтр
&filt включение фильтра, может быть только YES
&AutoSigns формировать выражения запроса для фильтрации по доп. реквизитам, может быть только YES
&after-filter код, выполняемый после фильтрации
&CacFld список рассчитываемых полей используемых в фильтре через пробел
&CalcVar инклюд-файл определения рассчитываемых полей используемых в фильтре
&edtprefix префикс (если есть) буфера, по которому построен браузер, используется для сопоставления фильтра и браузера
Поиск (autofind.cqr)
&AutoFastOFF отключает быстрый поиск, может быть только YES
&autofind перечень полей для поиска, по умолчанию - все
&autofind-no-file список рассчитываемых полей для быстрого поиска, по умолчанию равен списку полей формы 1, разделитель пробел
&SrchFld список полей формы браузера, по которым изменяется поиск, разделитель "|"
&SrchFile
список таблиц, по которым реально будет производиться поиск, разделитель "|", позиция должна соответствовать позиции в &SrchFld
&SrchAltFld список полей, по которым реально будет производиться поиск, разделитель "|", позиция должна соответствовать позиции в &SrchFld, к полю через запятую можно указать поле/переменную по которой должен производиться "быстрый поиск"
&SearchUseSort список полей, поиск по которым производится запросом с сортировкой, разделитель запятая
&SrchFormat список форматов, по которым реально будет производиться поиск, разделитель "|", позиция должна соответствовать позиции в &SrchFld
Возвращаемые значения
&return инклюд-файл, для возвращаемого значения (pick-value)
&tmprecid ключ, подключающий отбор записей, может быть только YES
&local-recid таблица отметок tmprecid локальная (иначе глобальная), может быть только YES
&local-rest восстанавливает список отметок tmprecid из глобальных в локальные перед запуском браузера, работает только если включен ключ &local-recid (таблица отметок tmprecid локальная); если включен фильтр (ключ &filt) работает только если поле фильтра RidRest = Yes, может быть только YES
&local-keep
сохраняет список отметок tmprecid из локальных в глобальные, работает только если включен ключ &local-recid (таблица отметок tmprecid локальная), может быть только YES

 

Вы здесь: Главная ИБС Бисквит МЕТАСХЕМА АБС БИСКВИТ КЛАССЫ МЕТАСХЕМЫ МЕТОД BROWSE КЛАССОВ МЕТАСХЕМЫ (NAVIGATE.CQR)