PREVIEW - ПОСТРОЕНИЕ ОТЧЕТОВ

В АБС БИСквит большинство отчетов формируются в PREVIEW, откуда они могут быть распечатаны по нажатию F5, или выгружены в файл по SHIFT+F5. Вот о работе с PREVIEW мы и поговорим в данной статье.


PREVIEW.I и SETDEST.I


Для ввода/вывода информации в PREVIEW используются 2-а инклюд-файла setdest.i и preview.i, между которыми заключается вывод информации например с помощью операторов DISPLAY или PUT.

{setdest.i}
PUT UNFORMATTED "[ДОГОВОРА ОТКРЫТЫЕ СЕГОДНЯ]" SKIP.
FOR EACH loan WHERE loan.open-date EQ TODAY:
   DISPLAY loan.cust-id loan.cust-corp loan.cust-cat.
END.
{preview.i}

Содержимое отчета предварительно формируется в файл, а после содержимое данного файла выводится на экран. По умолчанию это файл _spool.tmp. Данный файл можно изменить, для этого необходимо в setdest.i передать аргумент &filename со значением имени файла в который необходимо производить вывод и так же указать этот аргумент для preview.i для последующего отображения содержимого сформированного файла на экране.

{setdest.i &filename=""otchet.txt""}
PUT UNFORMATTED "[ДОГОВОРА ОТКРЫТЫЕ СЕГОДНЯ]" SKIP.
FOR EACH loan WHERE loan.open-date EQ TODAY:
   DISPLAY loan.cust-id loan.cust-corp loan.cust-cat.
END.
{preview.i &filename=""otchet.txt""}

Если аргумент &filename передать только в setdest.i, то отчет будет сформирован в файл указанный в данном аргументе, а preview.i выведет на экран содержимое файла _spool.tmp находящегося в рабочем каталоге пользователя, а отсутствие такового вызовет ошибку.

Если необходимо чтобы вывод осуществлялся в конец уже существующего файла, то необходимо указать аргумент &append   = "append"

Информация в PREVIEW может быть выведена из отдельно сформированного файла. Для этого имя файла необходимо передать аргументом &filename инклюд-файлу preview.i.

{setdest.i}
{preview.i &filename=""otchet1.txt""}

Для определения имени потока вывода данных в PREVIEW, необходимо указать его посредством аргумента &stream в setdest.i. Если имя потока неуказанно, то по умолчанию будет использоваться default поток.


ФОРМИРОВАНИЕ ОТЧЕТА


Отчет как правило представляет из себя некую таблицу, которая формируется непосредственно в теле процедуры отчета. Нарисовать границы таблицы в процедуре можно с помощью программы FAR, воспользовавшись ее инструментов DRAW.

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

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

{globals.i}
DEF VAR chAcctPos AS CHAR NO-UNDO.
{setdest.i}
FOR EACH acct WHERE acct.bal-acct EQ 40817 NO-LOCK:
RUN acct-pos in h_base(acct.acct,acct.currency,TODAY,TODAY,"П").
chAcctPos = STRING(sh-bal).
PUT UNFORMATTED  "|" + DelFilFromAcct(acct.acct) + "|"
                      + chAcctPos                 + "|"
  SKIP.
END.
{preview.i}

результат:

|40817810000000000001|1005.01|
|40817810000000000002|15.85|
|40817810000000000003|352.10|

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

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

chAcctPos = STRING(sh-bal, "->>>,>>9.99").

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

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

Решение данной проблемы лежит в разбиении длинного значения на несколько строк фиксированной ширины. Для реализации такого разбиения в БИСквите применяется  инструмент wordwrap.i.


wordwrap - разбивка строк


wordwrap.i - разбивает длинную строку {&s}[1] на {&n} строк {&s}[i] длиной не более {&l} по границам слов. Если установлен параметр {&centered}, то центрирует полученные строки. Специальный символ &d (по умолчанию "|") в строке {&s}[1] вызывает безусловный перевод строки.

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

  • Дата документа
  • Номер документа
  • Счет по дебету
  • Счет по кредиту
  • Сумма
  • Назначение платежа

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

{globals.i}
{wordwrap.def} /* требуется для wordwrap.i */
{tmprecid.def}
{getdates.i}   /* запрос периода выписки   */
DEF VAR vExtDetails  AS  CHAR   NO-UNDO   EXTENT 10. /* для разбивки */
DEF VAR i            AS  INT    NO-UNDO.
DEF TEMP-TABLE tt-string NO-UNDO /* Таблица строк выписки */
   FIELD str AS CHAR
.
FOR FIRST tmprecid,
   FIRST acct WHERE RECID(acct) EQ tmprecid.id NO-LOCK:
   FOR EACH op-entry WHERE (op-entry.acct-db EQ acct.acct
                        OR op-entry.acct-cr EQ acct.acct)
                       AND op-entry.op-date >= beg-date
                       AND op-entry.op-date <= end-date
                     NO-LOCK:
      FIND FIRST op OF op-entry NO-LOCK NO-ERROR.
      vExtDetails[1] = op.details.
      {wordwrap.i
          &s=vExtDetails
          &l=30
          &n=EXTENT(vExtDetails)
      }
      CREATE tt-string.
         tt-string.str = STRING(op.op-date, "99.99.9999")            + " " +     
                         STRING(op.doc-num, "x(8)")                  + " " +                       
                         DelFilFromAcct(op-entry.acct-db)            + " " +     
                         DelFilFromAcct(op-entry.acct-db)            + " " +     
                         STRING(op-entry.amt-rub, "->>>,>>>,>>9.99") + " " +     
                         vExtDetails[1]                                          
         .
      DO i = 2 TO EXTENT(vExtDetails):
         IF vExtDetails[i] NE "" THEN
         DO:
            CREATE tt-string.
               tt-string.str = FILL(" ",78) + vExtDetails[i].
        END.        
      END.
   END.
END.
{setdest.i}

/* Шапка выписки */
PUT UNFORMATTED STRING("ДАТА",      "x(10)") + " " +
                       "НОМ.ДОК."            + " " +
                STRING("ДБ",        "x(20)") + " " +
                STRING("КР",        "x(20)") + " " +
                STRING("СУММА",     "x(15)") + " " +
                       "СОДЕРЖАНИЕ"
SKIP.
PUT UNFORMATTED FILL("-",10) + " " +
                FILL("-",8)  + " " +
                FILL("-",20) + " " +
                FILL("-",20) + " " +
                FILL("-",15) + " " +
                FILL("-",30)
SKIP.

/* Тело выписки */
FOR EACH tt-string NO-LOCK:
  PUT UNFORMATTED tt-string.str SKIP.
END.
{preview.i}

При формировании строк отчета необходимо обратить внимание на тот факт, что если хотя бы одно из выводимых значений элементов строки будет иметь неизвестное значение (?), то вся строка будет выведена как неизвестное значение. Такое часто происходит, когда одним из выводимых элементов строки является дата. Таким образом при выводе элементов строки отчета необходимо проверять их значения и заменять неизвестные значения на "пусто".

{globals.i}
DEF VAR vCloseDate AS CHAR NO-UNDO.
{setdest.i}
FOR EACH loan NO-LOCK:
vCloseDate = IF loan.close-date EQ ?
THEN ""

ELSE STRING(loan.close-date).
PUT UNFORMATTED loan.cont-code + " " + vCloseDate SKIP.
END.
{preview.i}

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


signatur.i - подписи


Нередко в "подвале" отчета требуется выводить подписи. Конечно их можно сформировать как вывод и других строк отчета, а можно воспользоваться инклюд-файлом signatur.i

Для вывода подписей руководителей по законодательству, signatur.i используется без аргумента &user-only, но требует обязательного подключения globals.i

{globals.i}
{setdest.i}
PUT ....
{signatur.i}
{preview.i}

При этом настройки подписей берутся из доп. реквизита "Подписи" меню процедуры отчета. В данном доп. реквизите прописывается код параметра из одноименного темпорированного классификатора. Как настроить подписи в классификаторе, см. инструкцию БИСа.

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

  • eсли не определен аргумент &no-mp: Дир,ГлБух,МестоПечати,Исполн,Дата;
  • если &no-mp=YES: Дир,ГлБух,Исполн,Дата.

Если же достаточно только информации по исполнителю, которым является пользователь запустивший отчет, то необходимо передать аргумент &user-only=YES:

{globals.i}
{setdest.i}
PUT ....

{signatur.i
&user-only=YES}

{preview.i}

Если при формирование отчета вывод данных осуществляется посредством объявленного потока STREAM, то для вывода подписей в том же потоке его необходимо указать посредством аргумента &stream.


ПЕЧАТЬ ОТЧЕТА


В ИБС "Бисквит" для каждого принтера возможно указание строк инициализации и сброса для печати листов определенной ширины и длины. PREVIEW определяет по максимально длинной строке отчета подходящую настройку принтера, на который будет выводиться отчет, с шириной равной, либо большей длине этой строки. Далее используется строка этой настройки в которой определяется формат листа (альбомная или книжная) и прочие параметры. В случае если подходящий настройки принтера PREVIEW не находит, выводится соответствующее предупреждение пользователю с вопросом-предложением о разбивке отчета.

Повлиять на выбор настройки принтера можно с помощью явной передачи посредством аргумента &cols инклюд-файлу {preview.i} ширины относительно которой будет выбираться настройка принтера независимо от максимально длинной строки отчета.

Разбивка на страницы осуществляется автоматически, согласно определенной настройки принтера, посредством вставки ASCII кода 12.

Параметры печати, такие как, например, ориентация листа и т.д. определяются набором ESC-символов заданных в настройках принтера. Помимо этого имеется возможность вставки ESC-символов в текст отчета. На моей практике случались такие ситуации, когда один лист одного отчета должен был иметь портретную ориентация, а другой альбомную.

Вы здесь: Главная ИБС Бисквит БАЗОВЫЙ PREVIEW - ПОСТРОЕНИЕ ОТЧЕТОВ