Ассоциация ЭБНИТ    ИРБИС-корпорация    Вики-Ирбис    Online/CHM справка Ирбис   
Опыт и разработки пользователей ИРБИС :  ИРБИС Irbis
 
Статистика на большой базе. Замена стат. формы табличной формой
Пользователь: Gena (IP-адрес скрыт)
Дата: 09, November, 2019 20:46

Работа библиотеки тесно связана с ведением статистики. Количество выданных книг, посещений, регистраций/перерегистраций, что и кому выдавалось, где и когда, и много других вопросов статистического характера регулярно задают инженерам. С большинством вопросов статистики можно справиться с помощью механизма стат. форм. Однако, когда база читателей переваливает где-то за 60-80 тысяч читателей, статистика начинает формироваться слишком долго. Иной раз отчеты так и не формируются, потому как АРМы отключаются по таймауту. Проблема в том, что модуль формирование стат. отчетов для анализа каждой записи выполняет несколько запросов:
1. чтение всей записи целиком
2. расформатирование прочитанной записи
3. обработка полученных результатов

И все эти действия выполняются в режиме общения АРМа с TCP/IP сервером Ирбиса. В итоге, получается достаточно длительная работа. Оптимизировать работу модуля стат. отчетов не представляется возможным. Однако! Появилась идея решить задачу получения статистических отчетов другим способом – с помощью режима печати табличных форм.

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

Справочник вертикали:
1
Значение 1
2
Значение 2
3
Значение 3
*****

Справочник горизонтали:
А
Значение 1
Б
Значение 2
В
Значение 3
Г
Значение 4
*****

Тогда матрица будет следующей: 3х4

1:А 1:Б 1:В 1:Г
2:А 2:Б 2:В 2:Г
3:А 3:Б 3:В 3:Г

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

Справочник вертикали:
чз
Читальный зал
аб.1
Абонемент 1
аб.2
Абонемент 2
аб.ин.
Абонемент иностр.
аб.муз.
Абонемент музык.
*****
Значения формата вертикали:
чз
чз
аб.1
аб.2
аб.2
аб.1
аб.муз.

Справочник горизонтали:
01
январь
02
февраль
03
март



10
октябрь
11
ноябрь
12
Декабрь
*****
Значения формата горизонтали:
04
06
08
09
09
09
09

То есть, имеет следующие пары координат:
(чз:04)(чз:06) (аб.1:08)(аб.2:09)(аб.2:09)(аб.1:09)(аб.муз:09)
При таких справочниках и сформированных форматами данных матрица будет заполнена следующим образом:
<code>
01 02 03 04 05 06 07 08 09 10 11 12
чз 1 1
аб.1 1 1
аб.2 2
аб.ин.
аб.муз 1
</code>
Отрабатывая на каждой следующей записи, значения в матрице все время пополняются: каждый раз, когда координаты указывают на какую-то ячейку в матрице, ее значение увеличивается на единицу.

Отдельно стоит обратить внимание на ситуацию, когда количество значений по вертикали и горизонтали не совпадает. Это типичная ситуация для стат.форм, в которых анализ выполняется по полям с разным количеством повторений. Например, распределение количества зарегистрированных читателей по кафедрам выдачи и категориям. В записи может быть сколько угодно повторений поля 51 с данными о дате и месте регистрации (абонементах), но может быть одна категория. В тех случая, когда количество терминов для вертикали и горизонтали не совпадают, выполняется следующее правило: сделать пары координат для всех терминов, для которых есть значения вертикали и горизонтали, а когда останутся термины только для одной размерности, добавлять им в пару ПОСЛЕДНИЙ существующий термин из первой размерности. Например:

Значения вертикали:
Аб1
Аб2
Чз
Аб1
Значения горизонтали:
школьник
Сформированные пары координат:
(Аб1:школьник)
(Аб2:школьник)
(Чз:школьник)
(Аб1:школьник)

Как уже говорилось в начале, стат. формы на очень больших базах (60-80 тысяч записей и более) начинают работать чудовищно медленно, что и вызвало необходимость искать альтернативный способ получения статистических данных.

Ключевой момент ускорения формирования стат. форм – это передача выполнения всех операция на сервер. Так как вклиниться в работу сервера нет возможности, то нужно использовать штатные методы для обхода записей и расформатирования их. В связи с этим было принято решения получать стат. отчеты в режиме печати выходных табличных форм. В принципе, если задаться такой целью, то реализовать статистическую форму можно вообще полностью штатным функционалом печатной формы. Для этого существует механизм суммирования данных – секция SUM в файле TBU, в которой можно ввести форматы для подсчета данных, а в конце работы формы вывести все данные. В том случае, если у вас формируется небольшое количество данные, то есть размерность вертикали и горизонтали не большая, допустим по 4-5 значений, то настроить это еще реально: нужно написать 16-25 форматов, а потом в области итогов описать таблицу, где в каждую ячейку будут выводиться эти данные. Но для больших стат. отчетов, а так же для таких, которые периодически приходится редактировать. это уже становится крайне утомительной задачей.

Что нужно, что бы в режиме печатной табличной форме получить статистику? Не так уж и много:
• форматы для вертикали и горизонтали
• буфер, в которой после статистической обработки каждой записи будут записываться итоги
• механизм для чтения/записи в буфер данных
• механизм формирования итоговой таблицы с данными

Форматы для вертикали и горизонтали уже есть – они у нас в стат. формах были созданы и там использовались, принципиально что-то в них переделывать смысла и надобности нет. Единственное что пришлось изменить – метку модельного поля, так как в стат. формах она могла быть любой, и там часто использовались метки 999, 1000, 1001 и любые другие, а в режиме печати табличных форм модельное поле, которое формируется на основе данных из опросного листа и передается в запись для запуска механизм фильтрации данных, может быть только с меткой 991. Форматы вертикали и горизонтали должны выполняться на самой записи, по этому их целесообразно поместить в файл [TABNAME].PFT. Там же поместим механизм, который обработанные данные текущей записи будет складывать в буфер и передавать из записи в запись.

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

В принципе, если очень задаться целью и не бояться большого количества вложенных циклов, которые в языке манипулирования данными реализуются с помощью вложенных форматов, то можно обойтись вообще одними только штатными средствами – файлами таблицы и форматами. Я решил несколько упростить код за счет того, что вынес функции работы с буферов во внешнюю библиотеку (array_dll.dll). В этой библиотеке реализовано несколько функций:
GetCall – получение данных из ячейки с заданными координатами;
AddArrayValue – установка значений ячеек (передается три массива: массив индексов вертикали, массив индексов горизонтали, массив значений);
FindIndex – определение индекса (номера) для вертикали или горизонтали по значению, которое было сформировано форматами вертикали и горизонтали (выполняется по справочнику)

Для наглядности я дальше буду оперировать названием файлов для печатной формы exp_stat. Среди них:
exp_stat.hdr – определяет наличие опросного листа и заголовка над таблицей
exp_stat.pft – формат, который выполняется на каждой записи
exp_stat.tbu – описание самой RTF-страницы и шаблона таблицы, так же именно в этом файле происходит суммирование данных и вывод итоговой сумму, а в нашем случае – самой таблицы
exp_stat.wss – файл опросного листа подполей, который используется для передачи параметров в стат. форму; этот файл описан в файле exp_stat.hdr
exp_stat_h.pft – файл заголовка таблицы; этот файл описан в файле exp_stat.hdr
exp_stat_row.pft – формат, используемый стат. формой для заполнения данных строки в таблице
exp_stat_summ_col.pft – формат, используемый стат. формой для подсчета итогов в столбце

И так, создаем печатную форму для получения статистики по регистрации/перерегистрации читателей.

В файле exp_stat.pft помещается почти без изменений формат вертикали и горизонтали из старой стат. формы. Единственное изменение – это замена номеров меток модельного поля на 991. В глобальных переменных G100 и G200 находятся загруженные справочники вертикали и горизонтали. Они нам нужны для определения координат. Значения терминов вертикали записываются в глобальную переменную G101, значения терминов горизонтали – в глобальную переменную G201. На этом моменте у нас есть сформированные термины и нам нужно их преобразовать в координаты и занести в массив, который передается из записи в запись в глобальной переменной с меткой G1. После того, как мы загрузили в глобальные переменные G100/G200 справочники вретикали и горизонтали, а в глобальные переменные G101/G201 значения, которые сформировали форматы вертикали и горизонтали, мы можем определить координаты терминов. Для этого служит функция FindIndex из библиотеки array_dll. В результате у нас в глобальных переменных G102/G202 записываются уже числовые координаты ячеек, значения которых нужно увеличить. Изменение данных в массиве буфера выполняется с помощью функции AddArrayValue из библиотеки array_dll. В эту функцию передается два массива координат и текущее значение массива буфера (G1). Функция возвращает многострочный текст, который является измененным массивом буфера с данными из всех предыдущих и текущей записей.

/*список значений вертикали
&uf('+7W100#'(&unifor('+5Tkv_STF.mnu')/)),

&uf('+7W200#'(&unifor('+5Tvozrast_STF.mnu')/)),
/*список значений горизонтали

/*Получаем значения распределений по вертикали
&uf('+7w101#'
   (if p(v51) then 
      if (v51^*>=&uf('Av991^a#1')) and (v51^*<=&uf('Av991^b#1')) then 
         if (&uf('kkv_STF.mnu!'v51^c)<>'') then v51^c else '*' fi/ 
      fi 
   fi),
   (if p(v52) then 
      if (v52^*>=&uf('Av991^a#1')) and (v52^*<=&uf('Av991^b#1')) then 
         if (&uf('kkv_STF.mnu!'v52^c)<>'') then v52^c else '*' fi/ 
      fi 
   fi)
),

/*Получаем значения распределений по горизонтали
&uf('+7w201#'
   if p(v21) then 
      &uf('+7W300#',&uf('3')), 
      if (val(&uf('+95',v21))=4) or (val(&uf('+95',v21))=8) then 
         &uf('+7W301#',F(val(g300.4)-val(v21.4),0,0)), 
         if (v21*4<>'') then 
            if val(g300*4)<val(v21*4) then 
               &uf('+7W301#',F(val(g301)-1,0,0)) 
            fi 
         fi, 
         if (val(g301)<=6) then '1' fi, 
         if (val(g301)>=7) and (val(g301)<=14) then '2' fi, 
         if (val(g301)>=15) and (val(g301)<=30) then '3' fi, 
         if (val(g301)>=31) and (val(g301)<=60) then '4' fi, 
         if (val(g301)>=61) then '5' fi, 
      else 
         '*' 
      fi,
   else 
      '*' 
   fi
),

/*Внесение данных в массив происходит только тогда, когда есть и значения вертикали, и значения горизонтали
if s(g101)<>'' and s(g201)<>'' then 
   /*Список индексов вертикали
   &uf('+7w102#'&uf('+8array_dll,FindIndex,'(|$|g101|$!|),/,(|$|g100|$!|))),

   /*Список индексов горизонтали
   &uf('+7w202#'&uf('+8array_dll,FindIndex,'(|$|g201|$!|),/,(|$|g200|$!|))),

   if s(g102)<>'' and s(g202)<>'' then 
      /*Формирование массива со статистическими данными
      &uf('+7w1#'&uf('+8array_dll,AddArrayValue,'(|$|g102|$!|)/(|$|g202|$!|)/(g1/))),
   fi, 
fi,


На самом деле, для получения статистики уже вот этого хватит. Можно остановится на том, что в exp_stat.tbu в секции [Sum] вывести на печать полученный массив. Но это будет малоинформативно. По этому, как раз в этом файле и в этой секции начинается самая интересная часть – нам нужно нарисовать таблицы, заполнить данные шапки вертикали и горизонтали, внести данные из массива буфера и заполнить итоги. Так как там уже будут предполагаться вложенные циклы, то для решения этих задач используются вложенные форматы (exp_stat_row, exp_stat_summ_col.pft)

Еще один момент, который пришлось ввести в файл exp_stat.tbu. Дело в том, что в секции [Sum] не работают обычные для языка форматирования комментирования - /*. При их использовании форматы перестают работать. В качестве комментариев используется глобальная переменная 123. Так что если вы видите что-то вот такое «&uf('+7w123#________», то это не полезный функционал, а пояснение того, что будет далее.

Что происходит в этом файле:

1. Формируется и записывается в глобальную переменную G501 шапка для строки таблицы. При желании в этой части можно менять размер первой левой ячейки, в которой выводится расшифровка значений горизонтали, а так же жирность и видимость линий. Ширина всех ячеек в переменной части рассчитывается автоматически: из размера таблицы на всю страницу вычитается размер первой ячейки и делится на количество значений по горизонтали + 1 ячейку (для итогов).

2. Выводится шапка таблицы: в начале описание ее тегов из переменной G501, а потом данные из справочника горизонтали

3. Цикл по значениям переменной G100 выводит строки таблицы. Каждая итерация цикла – это одна строка. В этой части выводятся описания строки таблицы, а значения выводятся с помощью вложенного формата exp_stat_row, в котором происходит перебор значений и разделение их тегами. В конце строки выводятся суммарные данные для текущей строки

4. После вывода всех данных по массиву буфера, формируется еще одна строка, в которую выводятся итоговые данные для всех столбцов. Для этого используется вложенный формат exp_stat_summ_col


[FormatCode]
WIN
*****
[Sum]
'1'
#

&uf('+7W100#'(&unifor('+5Tkv_STF.mnu')/)),
&uf('+7W200#'(&unifor('+5Tvozrast_STF.mnu')/)),

&uf('+7w123#________Подсчитываем кол-во значений по горизонтали________'),

&uf('+7w502#'f(rsum((if g200<>'' then '1;'fi)),0,0)),

&uf('+7w123#________Формируем описание строки таблицы________'),
&uf('+7w501#'
   &uf('+7w123#________Общая часть и первая колонка________'),
   '\trowd\trgaph108\trleft-108'
   '\trbrdrl\brdrs\brdrw10' 
   '\trbrdrt\brdrs\brdrw10' 
   '\trbrdrr\brdrs\brdrw10' 
   '\trbrdrb\brdrs\brdrw10' 
   '\trpaddl108\trpaddr108\trpaddfl3\trpaddfr3'
   '\clbrdrl\brdrw10\brdrs'
   '\clbrdrt\brdrw10\brdrs'
   '\clbrdrr\brdrw10\brdrs'
   '\clbrdrb\brdrw10\brdrs \cellx2127'
      
   &uf('+7w123#________значение отступа границы текущей ячейки от левого края________'),
   &uf('+7w123#________2127 - ширина первой колонки с данными вертикали, приблизительно 4см ________'),
   &uf('+7w503#2127'),
   &uf('+7w123#________ширина ячейки________')   ,
   &uf('+7w504#'f((13608 - 2127)/ (val(&uf('ag502#1')) + 1)  ,0,0)),
       
   (if g200<>'' then 
      &uf('+7w503#'f(rsum(&uf('ag503#1')';'&uf('ag504#1')),0,0))
      '\clbrdrl\brdrw10\brdrs'
      '\clbrdrt\brdrw10\brdrs'
      '\clbrdrr\brdrw10\brdrs'
      '\clbrdrb\brdrw10\brdrs \cellx'&uf('ag503#1')
   fi)  
      
   &uf('+7w123#________Ячейка под итоги в строке________'),
   &uf('+7w503#'f(rsum(&uf('ag503#1')';'&uf('ag504#1')),0,0))
   '\clbrdrl\brdrw10\brdrs'
   '\clbrdrt\brdrw10\brdrs'
   '\clbrdrr\brdrw10\brdrs'
   '\clbrdrb\brdrw10\brdrs \cellx'&uf('ag503#1')
   '\pard\intbl\nowidctlpar '
),

&uf('+7w123#________Выводим шапку таблицы________'),
&uf('ag501#1')
'\cell '
(if g200<>'' then 
   &uf('kvozrast_STF.mnu!'g200),
   '\cell '
fi),
'\bВСЕГО\b0\cell\row'
'\pard\nowidctlpar'

&uf('+7w105#0'),
(if g100<>'' then 
   &uf('+7w105#'f(rsum(&uf('ag105#1'),';1;'),0,0)),
   
&uf('+7w123#________Выводим описание строки таблицы________'),
   &uf('ag501#1')
&uf('+7w123#________Выводим данные строки________'),
   &uf('kkv_STF.mnu!'g100),
   '\cell '
   &uf('+7w500#'g1),
   &uf('6exp_stat_row'),
&uf('+7w123#________Выводим итоги строки________'),
   if rsum(&uf('ag500#1'))>0 then f(rsum(&uf('ag500#1')),0,0) else '0' fi, 
   '\cell\row'
fi/),

&uf('+7w123#________Выводим Итоги по столбцам________'),
&uf('+7w105#0'),
&uf('+7w506#0'),
&uf('+7w123#________Выводим описание строки таблицы________'),
&uf('+7w123#________Выводим данные строки________'),
'\bВСЕГО:\b0',
'\cell '
   
(if g200<>'' then 
   &uf('6exp_stat_summ_col'),
   '\cell '
   &uf('+7w105#'f(rsum(&uf('ag105#1'),';1;'),0,0)),
fi/),
&uf('ag507#1')'\cell\row'

'\pard\nowidctlpar\par'
*****
[Tab]
\paperw16839\paperh11907\margl1701\margr850\margt1134\margb1134 
{\b\fs\fs24\qc 
[Header]
\b0 }
}


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

На что хотелось бы обратить внимание – получившееся решение на самом деле достаточно универсально. В этой таблице есть только три файла, которые нужно модифицировать для получения новых стат. отчетов: в шапке exp_stat_h.pft внести заголовки и название таблицы, в файле теле exp_stat.pft внести (скопировать!) форматы горизонтали и вертикали из старых стат. форм, в файле exp_stat.tbu заменить названия справочников вертикали и горизонтали.

По поводу скорости работы хочу привести пример. Обычная стат. форма на базе читателей в 110 000 человек не справляется с выдачей результатов за 2 часа. В режиме печати табличной формы нужные результаты выдаются где-то за 20 минут на все той же базе в 110 000 читателей.



Редактировано 2 раз. Последний раз 10.11.2019 14:19 пользователем Gena.

Вложения: array_dll.dll (356.5KB)   Файлы табличной статистической формы.rar (3.1KB)  
Re: Статистика на большой базе. Замена стат. формы табличной формой
Пользователь: Игорь (IP-адрес скрыт)
Дата: 11, November, 2019 11:55

Я пришел к реализации "чтение MST файла с отбором записей по установленным признакам" -> ротация данных в программе -> выходная форма в документ MS Word.
На ~100 тыс. записях - 1-2 минуты работы на вполне себе офисном ПК.

Re: Статистика на большой базе. Замена стат. формы табличной формой
Пользователь: Gena (IP-адрес скрыт)
Дата: 11, November, 2019 12:17

Игорь написал(а):
-------------------------------------------------------
> Я пришел к реализации "чтение MST файла с отбором
> записей по установленным признакам" -> ротация
> данных в программе -> выходная форма в документ MS
> Word.
> На ~100 тыс. записях - 1-2 минуты работы на вполне
> себе офисном ПК.

То есть, это ваше приложение? Работает без форматера?

Re: Статистика на большой базе. Замена стат. формы табличной формой
Пользователь: woodyfon (IP-адрес скрыт)
Дата: 11, November, 2019 15:33

А если каждый элемент матрицы держать в инверсном файле и потом статистику делать форматом? Така получится?

Re: Статистика на большой базе. Замена стат. формы табличной формой
Пользователь: Gena (IP-адрес скрыт)
Дата: 11, November, 2019 16:19

woodyfon написал(а):
-------------------------------------------------------
> А если каждый элемент матрицы держать в инверсном
> файле и потом статистику делать форматом? Така
> получится?

Не могу представить такую технологию.

Re: Статистика на большой базе. Замена стат. формы табличной формой
Пользователь: Игорь (IP-адрес скрыт)
Дата: 13, November, 2019 11:48

Всё на ЯП штатными инструментами работы с массивами/строками. Без форматера (если имеется в виду форматер ИРБИСа). Медленный он. На базах ИБИС размером в 32К записей это ещё было не сильно критично, но теперь, когда библиографические базы легко превышают 600К записей, базы читателей под 100К и выше, и база читательского архива - в разы и десятки раз больше читательской, создание тривиального отчета превращается... превращается... в тренажер терпеливости. Извините, кажется, что-то в развитии системы пошло не так.

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

В основном же делаю отбор записей по словарю, загружаю записи и сразу преобразую их к JSON, отбрасывая ненужные поля и подгружая данные из связанных записей через отбор по словарю. Далее - штатными инструментами ЯП.

Пока пользовались Web-ИРБИСОМ, я базу LOGDB регулярно реплицировал в базу SQLite в формате JSON, и статистику делал уже по этой базе.

В принципе, базу RDR_ARCH можно также регулярно реплицировать в локальную SQL|NoSQL базу (она же не меняется со временем), сэкономив таким образом время на обращения к архивным записям при формировании статистики типа книговыдачи/спрашиваемости.

На вопрос "зачем так, надо же пользоваться средствами, предоставляемыми ИРБИСом" отвечу: средства ИРБИСа до сих пор сырые, да и мне так привычнее.

Re: Статистика на большой базе. Замена стат. формы табличной формой
Пользователь: Игорь (IP-адрес скрыт)
Дата: 13, November, 2019 12:00

woodyfon написал(а):
-------------------------------------------------------
> А если каждый элемент матрицы держать в инверсном
> файле и потом статистику делать форматом? Така
> получится?

убийца... :)
Сколько для начала такой инверсный файл будет перестраиваться на базе 100+К записей? )) И после каждый раз, когда запись будет меняться... и помножить на массовую книговыдачу/возврат, например... И хотя идея не новая, но это решение не для вселенной ИРБИСа.
Можно ещё сесть, немного подумать и просто добавить несколько важных для ускорения процесса создания отчетов ключей, не сильно напрягающих систему в процессе их создания/обновления.
А потом с каждым обновлением старательно переносить своё решение в новые форматы.
А там в обновлении (внезапно) поменяется логика работы какого-нибудь юнифора. И пляши с бубном, ога.

Re: Статистика на большой базе. Замена стат. формы табличной формой
Пользователь: woodyfon (IP-адрес скрыт)
Дата: 13, November, 2019 12:50

Цитата:
Пока пользовались Web-ИРБИСОМ, я базу LOGDB регулярно реплицировал в базу SQLite в формате JSON
В режиме реального времени?

Re: Статистика на большой базе. Замена стат. формы табличной формой
Пользователь: Gena (IP-адрес скрыт)
Дата: 13, November, 2019 14:39

woodyfon написал(а):
-------------------------------------------------------
> Пока пользовались Web-ИРБИСОМ, я базу LOGDB
> регулярно реплицировал в базу SQLite в формате
> JSON
> В режиме реального времени?


В режиме реального времени не получится - в базе триггеров нет. Можно сторонней прикладухой. которая каждые 5-10 минут опрашивает базу на наличие новых записей и переносит только их, а после переноса сразу же отмечает, что они отработаны. Это как раз просто

Re: Статистика на большой базе. Замена стат. формы табличной формой
Пользователь: Игорь (IP-адрес скрыт)
Дата: 13, November, 2019 14:45

woodyfon написал(а):
-------------------------------------------------------
> Пока пользовались Web-ИРБИСОМ, я базу LOGDB
> регулярно реплицировал в базу SQLite в формате
> JSON
> В режиме реального времени?

Да, конечно.
Файл "Сервер 64.doc" стандартной поставки, раздел 7 документа (он по оглавлению имеет номер 8, там сбита нумерация, и это до сих пор не исправили).



Извините, только зарегистрированные пользователи могут писать в этом форуме.
This forum powered by Phorum.