Форма вывода текущей статистики2
Пользователь:
Соколинский К.Е. (СЗТУ) (IP-адрес скрыт)
Дата: 24, October, 2005 18:31
ОПИСАНИЕ АЛГОРИТМА
Ниже приведён файл STAT.SRW, в котором определены условия первичного отбора информации для вычислений.
[HeaderNumber]
1
[HeaderFormat]
&uf('6!!!display')
*****
[KeyOptions]
1000
1
if 'SPEC PAZK ZK':v920 then,&uf('+1W502#'),(if p(v907) then ,&uf('+1W503#',&uf('+1R503'),'*'v907^b), if (val(v907^a)>=val(&uf('av991^a#1')) and val(v907^a)<=val(&uf('av991^b#1'))) or v907^a=&uf('av991^a#1') then , if &uf('Av991^c#1'):v907^b then ,if &uf('+1R502'):s('*'v907^b) then else '^A'v907^b,'^B'v907^a,'^D',f(mfn,0,0), / ,&uf('+1W502#*'v907^b,&uf('+1R502')),&uf('+1W468#',&uf('Kposled.mnu|',v907^b)),,if &uf('+1R503'):&uf('+1R468') and &uf('+1R468')<>'' then &uf('+1W464#',v907^a),&uf('+1W463#') ,ref(mfn,( if p(v907) then if v907^b=&uf('+1R468') and val(&uf('+1R464'))>=val(v907^a) then if &uf('+1R464'):s(v907^a.4,if val(f(val(v907^a*4.2)+1,1,0))<10 then '0' fi, f(val(v907^a*4.2)+1,0,0)) or &uf('+1R464'):v907^a.6 then, &uf('+1W463#'v907^a),&uf('+1W468#') fi ,fi, fi)),if &uf('+1R463')<>'' then '^A'v907^b,'^C',&uf('+1R463')'^D',f(mfn,0,0) fi / ,fi, fi, fi, fi, fi/), fi,
*****
Результатом работы формата отбора и сортировки являются строки типа:
^AЗЕА^C20050927^D15555
^AЗЕА^C20050923^D15535
^AЗЕА^B20051006^D15539
^AЗЕА^B20051006^D15633
^AЗЕА^B20051006^D15636
^AЗЕА^B20051006^D15640
^AЧНН^C20050920^D15360
^AЧНН^C20050920^D15385
^AЧНН^B20050921^D15360
Где подполе ^A - инициалы сотрудника, ^B - дата корректировки или создания документа, ^D - инвентарный номер, ^C - дата передачи документа предшественником(тем, кто должен обрабатывать данные до обозначенного в поле ^A сотрудника).
В приведённом примере первые два первых повторения будут записаны в "Очередь"(на обработку), а остальные, после дополнительного анализа, будут отражены в графах "Новые поступления", "Докомплектование", "Ретро".
Конструкция ref(mfn, ....) используется здесь для создания вложенных циклов(или вложенных групп, если использовать терминологию разработчиков).
ref(mfn,( if p(v907) then if v907^b=&uf('+1R468') and val(&uf('+1R464'))>=val(v907^a) then if &uf('+1R464'):s(v907^a.4,if val(f(val(v907^a*4.2)+1,1,0))<10 then '0' fi, f(val(v907^a*4.2)+1,0,0)) or &uf('+1R464'):v907^a.6 then, &uf('+1W463#'v907^a),&uf('+1W468#') fi ,fi, fi))
После того, как найдено повторение с данными нужного сотрудника(чьи инициалы указаны в 991^c), при помощи posled.mnu определяется его предшественник, и вновь происходит сканирование повторений с целью поиска наименьшей допустимой даты регистрации предшественника. Эти операции требуются для вычисления «Очереди».
Строки обрабатываются форматом !!!display.pft, который осуществляет подсчёты и обеспечивает вывод.
"Назначение глобальных переменных:",
"469 - инициалы (v1^a)",
"501 - дата (v1^b)",
"504 - количество описаний на вновь поступившие книги",
"499 - количество ретро",
"498 - количество докомплектованных",
"470 - продолжительность задержки(очередь)",
"462 - количество вновь созданных записей",
"497 - номера КСУ новых экземпляров",
"464 - текущие инициалы(для отбора)",
"451 - характер работы(докомплектование, новая литература, ретро)"
(if p(v1) then
,"Вывод табличных строк",
if s(&uf('+1R504'),&uf('+1R499'),&uf('+1R498'),&uf('+1R497'),&uf('+1R462'))<>'' and ((v1^b<>&uf('+1R501') and p(v1^b) and &uf('+1R501')<>'' ) or (v1^a<>&uf('+1R464') and p(v1^c))) then
' \trowd\trqc\trgaph108\trleft-263\trhdr\trkeep
\clbrdrt\brdrs\brdrw15\clbrdrl\brdrs\brdrw15\clbrdrb\brdrs\brdrw15\clbrdrr\brdrs\brdrw15\cellx1500
\clbrdrt\brdrs\brdrw15\clbrdrl\brdrs\brdrw15\clbrdrb\brdrs\brdrw15\clbrdrr\brdrs\brdrw15\cellx2500
\clbrdrt\brdrs\brdrw15\clbrdrl\brdrs\brdrw15\clbrdrb\brdrs\brdrw1\clbrdrr\brdrs\brdrw15\cellx3500
\clbrdrt\brdrs\brdrw15\clbrdrl\brdrs\brdrw15\clbrdrb\brdrs\brdrw15\clbrdrr\brdrs\brdrw15\cellx4500
\clbrdrt\brdrs\brdrw15\clbrdrl\brdrs\brdrw15\clbrdrb\brdrs\brdrw15\clbrdrr\brdrs\brdrw15\cellx5500
\clbrdrt\brdrs\brdrw15\clbrdrl\brdrs\brdrw15\clbrdrb\brdrs\brdrw15\clbrdrr\brdrs\brdrw15\cellx6500
\clbrdrt\brdrs\brdrw15\clbrdrl\brdrs\brdrw15\clbrdrb\brdrs\brdrw15\clbrdrr\brdrs\brdrw15\cellx9069
\pard \qc\widctlpar\intbl { ',&uf('+1R461'),
'\cell }\pard \qc\widctlpar\intbl {', &uf('+1R504')#,&uf('+1W504#'),' \cell }
\pard \qc\widctlpar\intbl { ',&uf('+1R498')#,&uf('+1W498#'),' \cell }
\pard \qc\widctlpar\intbl { ',&uf('+1R499')#,&uf('+1W499#'),' \cell }
\pard \qc\widctlpar\intbl { ',&uf('+1R462')#,&uf('+1W462#'),' \cell }
\pard \qc\widctlpar\intbl { ',&uf('+1R470')#, ' \cell }
\pard \qc\widctlpar\intbl { ',&uf('+1R497')#,&uf('+1W497#'),' \cell }
\pard \widctlpar\intbl { \row }\pard \qc\widctlpar ',
if v1^a<>&uf('+1R464') then &uf('+1W465#') fi,
&uf('+1W464#',v1^a),
fi,
,"/3",
,"Зачисление документа в очередь на обработку",
if p(v1^c) then,
&uf('+1W470#',f(val(&uf('+1R470'))+1,0,0)),&uf('+1W465#',&uf('+1R465'),'*'v1^d'*'),
fi,
,"/2",
if a(v1^c) then,
&uf('+1W451#'),
,"================= Вложенный формат, осуществляющий вычисления=========================",
, ref(val(v1^d),
(if p(v910^c)then
if &uf('+1R501'):s(v910^c.4,if val(f(val(v910^c*4.2)+1,1,0))<10 then '0' fi, f(val(v910^c*4.2)+1,0,0)) or &uf('+1R501'):v910^c.6 then,
if &uf('+1R501'):v910^u.4 and p(v910^u) then
if &uf('+1R451')='' then &uf('+1W451#1') fi,
if &uf('+1R497'):v910^u then else,
&uf('+1W497#',&uf('+1R497'),v910^u|, |),
fi,
fi,
else,
if &uf('+1R451')='1' then &uf('+1W451#2') fi,
fi,
fi/)
,
,
if &uf('Av907^b#1')=&uf('+1R469') and &uf('Av907^a#1')=&uf('+1R501') then,
, &uf('+1W462#',f(val(&uf('+1R462'))+1,0,0)),
else,
if &uf('+1R451')='1' then ,
&uf('+1W504#',f(val(&uf('+1R504'))+1,0,0)),
else,
if &uf('+1R451')='2' then
&uf('+1W498#',f(val(&uf('+1R498'))+1,0,0)),
else,
&uf('+1W499#',f(val(&uf('+1R499'))+1,0,0)),
fi,
fi,
fi,),
,"================= /Вложенный формат, осуществляющий вычисления=========================",
,"Запись форматированной даты для вывода и даты для сверки",
&uf('+1W461#',v1^b.4'.',v1^b*4.2,'.'v1^b*6.2),
&uf('+1W501#',v1^b),
,"Исключение редактированного документа из очереди",
if &uf('+1R465'):s('*'v1^d'*') then &uf('+1W470#',f(val(&uf('+1R470'))-1,0,0)),fi,
##
,"Вывод ФИО сотрудника и шапки таблицы",
if v1^a<>&uf('+1R469') then,' \ql\pard\tab\par\s1\b\i\fs32{ ',&uf('Kfio.mnu|',v1^a),' }\par\b0\i0\fs20\par ','\trowd\trqc\trgaph108\trleft-263\trhdr\trkeep\clbrdrt\brdrs\brdrw15\clbrdrl\brdrs\brdrw15\clbrdrb\brdrs\brdrw15\clbrdrr\brdrs\brdrw15\cellx1500
\clbrdrt\brdrs\brdrw15\clbrdrl\brdrs\brdrw15\clbrdrb\brdrs\brdrw15\clbrdrr\brdrs\brdrw15\cellx2500
\clbrdrt\brdrs\brdrw15\clbrdrl\brdrs\brdrw15\clbrdrb\brdrs\brdrw15\clbrdrr\brdrs\brdrw15\cellx3500
\clbrdrt\brdrs\brdrw15\clbrdrl\brdrs\brdrw15\clbrdrb\brdrs\brdrw15\clbrdrr\brdrs\brdrw15\cellx4500
\clbrdrt\brdrs\brdrw15\clbrdrl\brdrs\brdrw15\clbrdrb\brdrs\brdrw15\clbrdrr\brdrs\brdrw15\cellx5500
\clbrdrt\brdrs\brdrw15\clbrdrl\brdrs\brdrw15\clbrdrb\brdrs\brdrw15\clbrdrr\brdrs\brdrw15\cellx6500
\clbrdrt\brdrs\brdrw15\clbrdrl\brdrs\brdrw15\clbrdrb\brdrs\brdrw15\clbrdrr\brdrs\brdrw15\cellx9069
\pard \qc\widctlpar\intbl {\b Дата \cell }
\pard \qc\widctlpar\intbl {\b ',if &uf('Kheadn.mnu|','1-',v1^a)<>'' then &uf('Kheadn.mnu|','1-',v1^a) else, 'Новые пост.',fi,' \cell }
\pard \qc\widctlpar\intbl {\b ',if &uf('Kheadn.mnu|','2-',v1^a)<>'' then &uf('Kheadn.mnu|','2-',v1^a) else, 'Докомпл.',fi,' \cell }
\pard \qc\widctlpar\intbl {\b ',if &uf('Kheadn.mnu|','3-',v1^a)<>'' then &uf('Kheadn.mnu|','3-',v1^a) else, 'Ретро',fi,' \cell }
\pard \qc\widctlpar\intbl {\b ',if &uf('Kheadn.mnu|','4-',v1^a)<>'' then &uf('Kheadn.mnu|','4-',v1^a) else, 'Вновь созд.',fi,' \cell }
\pard \qc\widctlpar\intbl {\b ',if &uf('Kheadn.mnu|','5-',v1^a)<>'' then &uf('Kheadn.mnu|','5-',v1^a) else, 'Очередь',fi,' \cell }
\pard \qc\widctlpar\intbl {\b КСУ \cell }
\pard \widctlpar\intbl {\b \row }\pard \qc\widctlpar ',
&uf('+1W469#',v1^a),,
fi, "5",
fi,
"/1",
,fi),
ПРОБЛЕМЫ ИСПОЛЬЗОВАНИЯ
Как видно из приведённых фрагментов, алгоритм отбора достаточно сложен. Это не может не сказываться на скорости. Если самый простой способ отбора(if v907:v991. . . . . . ) работает несколько минут, то при двойном сканировании каждого повторения ситуация заметно ухудшается. В локальном режиме, на базе 16 тыс. и компьютере Sempron 754 c реальной частотой 1.86 отбор осуществляется 4 минуты. Пока я не вижу способа исправить это положение, если разработчики не внедрят возможность отбора по словарю с использованием поисковых выражений.
Что касается формата !!!display.pft, то на том же компьютере он выполняется всего 3 секунды. В 10 раз хуже дело обстояло при работе на Сeleron 1800. Видимо, сказывается маленький и «глупый» кэш.
Предвижу упрёки в использовании вложенного формата. Должен сказать, что они неправомерны. Мне вообще не удалось зафиксировать различия в скорости работы формата в шапке и формата в файле. Однако очевидно, что второй способ запуска позволяет сэкономить нервы.
Естественный вопрос, который возникает при первом взгляде на форму: "А нельзя это было сделать попроще?". Я не нашел способа хоть сколько-нибудь существенно упростить формат без ущерба для качества расчетов. Тем не менее, я буду признателен за любые предложения по оптимизации.
Если кто-то создаёт свои формы статистики и эта тема его заинтересовала, я дам более подробные комментарии к формату. При возникновении сложностей с его использованием, могу выслать все файлы формы.