forked from CITKParus/P8-Panels
		
	
		
			
				
	
	
		
			2144 lines
		
	
	
		
			122 KiB
		
	
	
	
		
			SQL
		
	
	
	
	
	
			
		
		
	
	
			2144 lines
		
	
	
		
			122 KiB
		
	
	
	
		
			SQL
		
	
	
	
	
	
| create or replace package PKG_P8PANELS_VISUAL as
 | ||
| 
 | ||
|   /* Константы - типы данных */
 | ||
|   SDATA_TYPE_STR            constant PKG_STD.TSTRING := 'STR';  -- Тип данных "строка"
 | ||
|   SDATA_TYPE_NUMB           constant PKG_STD.TSTRING := 'NUMB'; -- Тип данных "число"
 | ||
|   SDATA_TYPE_DATE           constant PKG_STD.TSTRING := 'DATE'; -- Тип данных "дата"
 | ||
|   
 | ||
|   /* Константы - направление сортировки */
 | ||
|   SORDER_DIRECTION_ASC      constant PKG_STD.TSTRING := 'ASC';  -- По возрастанию
 | ||
|   SORDER_DIRECTION_DESC     constant PKG_STD.TSTRING := 'DESC'; -- По убыванию
 | ||
|   
 | ||
|   /* Константы - масштаб диаграммы Ганта */
 | ||
|   NGANTT_ZOOM_QUARTER_DAY   constant PKG_STD.TNUMBER := 0; -- Четверть дня
 | ||
|   NGANTT_ZOOM_HALF_DAY      constant PKG_STD.TNUMBER := 1; -- Пол дня
 | ||
|   NGANTT_ZOOM_DAY           constant PKG_STD.TNUMBER := 2; -- День
 | ||
|   NGANTT_ZOOM_WEEK          constant PKG_STD.TNUMBER := 3; -- Неделя
 | ||
|   NGANTT_ZOOM_MONTH         constant PKG_STD.TNUMBER := 4; -- Месяц
 | ||
|   
 | ||
|   /* Константы - тип графика */
 | ||
|   SCHART_TYPE_BAR           constant PKG_STD.TSTRING := 'bar';
 | ||
|   SCHART_TYPE_LINE          constant PKG_STD.TSTRING := 'line';
 | ||
|   SCHART_TYPE_PIE           constant PKG_STD.TSTRING := 'pie';
 | ||
|   SCHART_TYPE_DOUGHNUT      constant PKG_STD.TSTRING := 'doughnut';
 | ||
| 
 | ||
|   /* Константы - расположение легенды графика */  
 | ||
|   SCHART_LGND_POS_LEFT      constant PKG_STD.TSTRING := 'left';
 | ||
|   SCHART_LGND_POS_RIGHT     constant PKG_STD.TSTRING := 'right';
 | ||
|   SCHART_LGND_POS_TOP       constant PKG_STD.TSTRING := 'top';
 | ||
|   SCHART_LGND_POS_BOTTOM    constant PKG_STD.TSTRING := 'bottom';
 | ||
| 
 | ||
|   /* Типы данных - значение колонки таблицы данных */
 | ||
|   type TCOL_VAL is record
 | ||
|   (
 | ||
|     SVALUE                  PKG_STD.TLSTRING, -- Значение (строка)
 | ||
|     NVALUE                  PKG_STD.TNUMBER,  -- Значение (число)
 | ||
|     DVALUE                  PKG_STD.TLDATE    -- Значение (дата)
 | ||
|   );
 | ||
|   
 | ||
|   /* Типы данных - коллекция значений колонки таблицы данных */
 | ||
|   type TCOL_VALS is table of TCOL_VAL;
 | ||
|  
 | ||
|   /* Типы данных - описатель колонки таблицы данных */
 | ||
|   type TCOL_DEF is record
 | ||
|   (
 | ||
|     SNAME                   PKG_STD.TSTRING, -- Наименование
 | ||
|     SCAPTION                PKG_STD.TSTRING, -- Заголовок
 | ||
|     SDATA_TYPE              PKG_STD.TSTRING, -- Тип данных (см. константы SDATA_TYPE_*)
 | ||
|     SCOND_FROM              PKG_STD.TSTRING, -- Наименование нижней границы условия отбора
 | ||
|     SCOND_TO                PKG_STD.TSTRING, -- Наименование верхней границы условия отбора
 | ||
|     BVISIBLE                boolean,         -- Разрешить отображение
 | ||
|     BORDER                  boolean,         -- Разрешить сортировку
 | ||
|     BFILTER                 boolean,         -- Разрешить отбор
 | ||
|     RCOL_VALS               TCOL_VALS,       -- Предопределённые значения
 | ||
|     SHINT                   PKG_STD.TSTRING  -- Текст всплывающей подсказки
 | ||
|   );
 | ||
|   
 | ||
|   /* Типы данных - коллекция описателей колонок таблицы данных */
 | ||
|   type TCOL_DEFS is table of TCOL_DEF;
 | ||
|   
 | ||
|   /* Типы данных - колонка */
 | ||
|   type TCOL is record
 | ||
|   (
 | ||
|     SNAME                   PKG_STD.TSTRING, -- Наименование
 | ||
|     RCOL_VAL                TCOL_VAL         -- Значение
 | ||
|   );
 | ||
| 
 | ||
|   /* Типы данных - коллекция колонок */
 | ||
|   type TCOLS is table of TCOL;
 | ||
|   
 | ||
|   /* Типы данных - строка */
 | ||
|   type TROW is record
 | ||
|   (
 | ||
|     RCOLS                   TCOLS       -- Колонки
 | ||
|   );
 | ||
|   
 | ||
|   /* Типы данных - коллекция строк */
 | ||
|   type TROWS is table of TROW;
 | ||
|   
 | ||
|   /* Типы данных - таблица данных */
 | ||
|   type TDATA_GRID is record
 | ||
|   (
 | ||
|     RCOL_DEFS               TCOL_DEFS,  -- Описание колонок
 | ||
|     RROWS                   TROWS       -- Данные строк
 | ||
|   );
 | ||
|   
 | ||
|   /* Типы данных - фильтр */
 | ||
|   type TFILTER is record
 | ||
|   (
 | ||
|     SNAME                   PKG_STD.TSTRING, -- Наименование
 | ||
|     SFROM                   PKG_STD.TSTRING, -- Значение "с"
 | ||
|     STO                     PKG_STD.TSTRING  -- Значение "по"
 | ||
|   );
 | ||
|   
 | ||
|   /* Типы данных - коллекция фильтров */
 | ||
|   type TFILTERS is table of TFILTER;
 | ||
|   
 | ||
|   /* Типы данных - сортировка */
 | ||
|   type TORDER is record
 | ||
|   (
 | ||
|     SNAME                   PKG_STD.TSTRING, -- Наименование
 | ||
|     SDIRECTION              PKG_STD.TSTRING  -- Направление (см. константы SORDER_DIRECTION_*)
 | ||
|   );
 | ||
|   
 | ||
|   /* Типы данных - коллекция сортировок */
 | ||
|   type TORDERS is table of TORDER;
 | ||
|   
 | ||
|   /* Типы данных - описание атрибута задачи для диаграммы Ганта */
 | ||
|   type TGANTT_TASK_ATTR is record
 | ||
|   (
 | ||
|     SNAME                   PKG_STD.TSTRING, -- Наименование
 | ||
|     SCAPTION                PKG_STD.TSTRING  -- Заголовок
 | ||
|   );
 | ||
|   
 | ||
|   /* Типы данных - коллекция описаний атрибутов задачи для диаграммы Ганта */
 | ||
|   type TGANTT_TASK_ATTRS is table of TGANTT_TASK_ATTR;
 | ||
| 
 | ||
|   /* Типы данных - значение атрибута задачи для диаграммы Ганта */
 | ||
|   type TGANTT_TASK_ATTR_VAL is record
 | ||
|   (
 | ||
|     SNAME                   PKG_STD.TSTRING, -- Наименование
 | ||
|     SVALUE                  PKG_STD.TSTRING  -- Значение
 | ||
|   );
 | ||
|   
 | ||
|   /* Типы данных - коллекция значений атрибутов задачи для диаграммы Ганта */
 | ||
|   type TGANTT_TASK_ATTR_VALS is table of TGANTT_TASK_ATTR_VAL;
 | ||
|   
 | ||
|   /* Типы данных - коллекция ссылок на предшествующие задачи для диаграммы Ганта */
 | ||
|   type TGANTT_TASK_DEPENDENCIES is table of PKG_STD.TREF;
 | ||
|   
 | ||
|   /* Тип данных - задача для диаграммы Ганта */
 | ||
|   type TGANTT_TASK is record
 | ||
|   (
 | ||
|     NRN                     PKG_STD.TREF,                    -- Рег. номер
 | ||
|     SNUMB                   PKG_STD.TSTRING,                 -- Номер
 | ||
|     SCAPTION                PKG_STD.TSTRING,                 -- Заголовок
 | ||
|     SNAME                   PKG_STD.TSTRING,                 -- Наименование
 | ||
|     DSTART                  PKG_STD.TLDATE,                  -- Дата начала
 | ||
|     DEND                    PKG_STD.TLDATE,                  -- Дата окончания
 | ||
|     NPROGRESS               PKG_STD.TNUMBER := null,         -- Прогресс (% готовности) задачи (null - не определен)
 | ||
|     SBG_COLOR               PKG_STD.TSTRING := null,         -- Цвет заливки задачи (null - использовать цвет по умолчанию из стилей, формат - HTML-цвет, #RRGGBBAA)
 | ||
|     STEXT_COLOR             PKG_STD.TSTRING := null,         -- Цвет текста заголовка задачи (null - использовать цвет по умолчанию из стилей, формат - HTML-цвет, #RRGGBBAA)
 | ||
|     BREAD_ONLY              boolean := null,                 -- Сроки и прогресс задачи только для чтения (null - как указано в описании диаграммы)
 | ||
|     BREAD_ONLY_DATES        boolean := null,                 -- Сроки задачи только для чтения (null - как указано в описании диаграммы)
 | ||
|     BREAD_ONLY_PROGRESS     boolean := null,                 -- Прогресс задачи только для чтения (null - как указано в описании диаграммы)
 | ||
|     RATTR_VALS              TGANTT_TASK_ATTR_VALS := null,   -- Значения дополнительных атрбутов (null - дополнительные атрибуты не определены)
 | ||
|     RDEPENDENCIES           TGANTT_TASK_DEPENDENCIES := null -- Список предшествующих задач
 | ||
|   );
 | ||
|   
 | ||
|   /* Тип данных - коллекция задач диаграммы Ганта */
 | ||
|   type TGANTT_TASKS is table of TGANTT_TASK;
 | ||
|   
 | ||
|   /* Тип данных - описание цвета задач диаграммы Ганта */
 | ||
|   type TGANTT_TASK_COLOR is record
 | ||
|   (
 | ||
|     SBG_COLOR               PKG_STD.TSTRING := null, -- Цвет заливки задачи (формат - HTML-цвет, #RRGGBBAA)
 | ||
|     STEXT_COLOR             PKG_STD.TSTRING := null, -- Цвет текста заголовка задачи (формат - HTML-цвет, #RRGGBBAA)
 | ||
|     SDESC                   PKG_STD.TSTRING          -- Описание
 | ||
|   );
 | ||
|   
 | ||
|   /* Тип данных - коллекция описаний цветов задач диаграммы Ганта */
 | ||
|   type TGANTT_TASK_COLORS is table of TGANTT_TASK_COLOR;
 | ||
|   
 | ||
|   /* Типы данных - диаграмма Ганта */
 | ||
|   type TGANTT is record
 | ||
|   (
 | ||
|     STITLE                  PKG_STD.TSTRING := null,             -- Заголовок (null - не отображать)
 | ||
|     NZOOM                   PKG_STD.TNUMBER := NGANTT_ZOOM_WEEK, -- Текущий масштаб (см. константы NGANTT_ZOOM_*)
 | ||
|     BZOOM_BAR               boolean := true,                     -- Обображать панель масштабирования
 | ||
|     BREAD_ONLY              boolean := false,                    -- Сроки и прогресс задач только для чтения
 | ||
|     BREAD_ONLY_DATES        boolean := false,                    -- Сроки задач только для чтения
 | ||
|     BREAD_ONLY_PROGRESS     boolean := false,                    -- Прогресс задач только для чтения
 | ||
|     RTASK_ATTRS             TGANTT_TASK_ATTRS,                   -- Описание атрибутов карточки задачи
 | ||
|     RTASK_COLORS            TGANTT_TASK_COLORS,                  -- Описание цветов задач
 | ||
|     RTASKS                  TGANTT_TASKS                         -- Список задач
 | ||
|   );
 | ||
|   
 | ||
|   /* Типы данных - значение атрибута элемента данных графика */
 | ||
|   type TCHART_DATASET_ITEM_ATTR_VAL is record
 | ||
|   (
 | ||
|     SNAME                   PKG_STD.TSTRING, -- Наименование
 | ||
|     SVALUE                  PKG_STD.TSTRING  -- Значение
 | ||
|   );
 | ||
|   
 | ||
|   /* Типы данных - коллекция значений атрибутов элемента данных графика */
 | ||
|   type TCHART_DATASET_ITEM_ATTR_VALS is table of TCHART_DATASET_ITEM_ATTR_VAL;  
 | ||
|   
 | ||
|   /* Тип данных - элемент данных графика */
 | ||
|   type TCHART_DATASET_ITEM is record
 | ||
|   (
 | ||
|     NVALUE                  PKG_STD.TNUMBER,                      -- Значение элемента данных, отображаемое на графике
 | ||
|     RATTR_VALS              TCHART_DATASET_ITEM_ATTR_VALS := null -- Значения дополнительных атрбутов (null - дополнительные атрибуты не определены)
 | ||
|   );
 | ||
|   
 | ||
|   /* Тип данных - коллекция элементов данных */
 | ||
|   type TCHART_DATASET_ITEMS is table of TCHART_DATASET_ITEM;
 | ||
|   
 | ||
|   /* Тип данных - набор данных графика */
 | ||
|   type TCHART_DATASET is record
 | ||
|   (
 | ||
|     SCAPTION                PKG_STD.TSTRING,         -- Заголовок
 | ||
|     SBORDER_COLOR           PKG_STD.TSTRING := null, -- Цвет границы элемента данных на графике (null - использовать цвет по умолчанию из стилей, формат - HTML-цвет, #RRGGBBAA)
 | ||
|     SBG_COLOR               PKG_STD.TSTRING := null, -- Цвет заливки элемента данных на графике (null - использовать цвет по умолчанию из стилей, формат - HTML-цвет, #RRGGBBAA)
 | ||
|     RITEMS                  TCHART_DATASET_ITEMS     -- Элементы данных
 | ||
|   );
 | ||
|   
 | ||
|   /* Тип данных - коллекция наборов данных графика */
 | ||
|   type TCHART_DATASETS is table of TCHART_DATASET;
 | ||
|   
 | ||
|   /* Тип данных - коллекция меток данных графика */
 | ||
|   type TCHART_LABELS is table of PKG_STD.TSTRING;
 | ||
|   
 | ||
|   /* Типы данных - график */
 | ||
|   type TCHART is record
 | ||
|   (
 | ||
|     STYPE                   PKG_STD.TSTRING,         -- Тип (см. константы SCHART_TYPE_*)
 | ||
|     STITLE                  PKG_STD.TSTRING := null, -- Заголовок (null - не отображать)
 | ||
|     SLGND_POS               PKG_STD.TSTRING := null, -- Расположение легенды (null - не отображать, см. константы SCHART_LGND_POS_*)
 | ||
|     RLABELS                 TCHART_LABELS,           -- Метки значений
 | ||
|     RDATASETS               TCHART_DATASETS          -- Наборы данных
 | ||
|   );
 | ||
|   
 | ||
|   /* Расчет диапаона выдаваемых записей */
 | ||
|   procedure UTL_ROWS_LIMITS_CALC
 | ||
|   (
 | ||
|     NPAGE_NUMBER            in number,  -- Номер страницы (игнорируется при NPAGE_SIZE=0)
 | ||
|     NPAGE_SIZE              in number,  -- Количество записей на странице (0 - все)
 | ||
|     NROW_FROM               out number, -- Нижняя граница диапазона
 | ||
|     NROW_TO                 out number  -- Верхняя граница диапазона
 | ||
|   );
 | ||
|   
 | ||
|   /* Формирование наименования условия отбора для нижней границы */
 | ||
|   function UTL_COND_NAME_MAKE_FROM
 | ||
|   (
 | ||
|     SNAME                   in varchar2 -- Наименование колонки
 | ||
|   ) return                  varchar2;   -- Результат
 | ||
|   
 | ||
|   /* Формирование наименования условия отбора для верхней границы */
 | ||
|   function UTL_COND_NAME_MAKE_TO
 | ||
|   (
 | ||
|     SNAME                   in varchar2 -- Наименование колонки
 | ||
|   ) return                  varchar2;   -- Результат
 | ||
|   
 | ||
|   /* Добавление значения в коллекцию */
 | ||
|   procedure TCOL_VALS_ADD
 | ||
|   (
 | ||
|     RCOL_VALS               in out nocopy TCOL_VALS, -- Коллекция значений
 | ||
|     SVALUE                  in varchar2 := null,     -- Значение (строка)
 | ||
|     NVALUE                  in number := null,       -- Значение (число)
 | ||
|     DVALUE                  in date := null,         -- Значение (дата)
 | ||
|     BCLEAR                  in boolean := false      -- Флаг очистки коллекции (false - не очищать, true - очистить коллекцию перед добавлением)
 | ||
|   );
 | ||
|   
 | ||
|   /* Формирование строки */
 | ||
|   function TROW_MAKE
 | ||
|   return                    TROW;       -- Результат работы
 | ||
|   
 | ||
|   /* Добавление колонки к строке */
 | ||
|   procedure TROW_ADD_COL
 | ||
|   (
 | ||
|     RROW                    in out nocopy TROW,  -- Строка
 | ||
|     SNAME                   in varchar2,         -- Наименование колонки
 | ||
|     SVALUE                  in varchar2 := null, -- Значение (строка)
 | ||
|     NVALUE                  in number := null,   -- Значение (число)
 | ||
|     DVALUE                  in date := null,     -- Значение (дата)
 | ||
|     BCLEAR                  in boolean := false  -- Флаг очистки коллекции (false - не очищать, true - очистить коллекцию перед добавлением)
 | ||
|   );
 | ||
|   
 | ||
|   /* Добавление строковой колонки к строке из курсора динамического запроса */
 | ||
|   procedure TROW_ADD_CUR_COLS
 | ||
|   (
 | ||
|     RROW                    in out nocopy TROW, -- Строка
 | ||
|     SNAME                   in varchar2,        -- Наименование колонки
 | ||
|     ICURSOR                 in integer,         -- Курсор
 | ||
|     NPOSITION               in number,          -- Номер колонки в курсоре
 | ||
|     BCLEAR                  in boolean := false -- Флаг очистки коллекции (false - не очищать, true - очистить коллекцию перед добавлением)
 | ||
|   );
 | ||
|   
 | ||
|   /* Добавление числовой колонки к строке из курсора динамического запроса */
 | ||
|   procedure TROW_ADD_CUR_COLN
 | ||
|   (
 | ||
|     RROW                    in out nocopy TROW, -- Строка
 | ||
|     SNAME                   in varchar2,        -- Наименование колонки
 | ||
|     ICURSOR                 in integer,         -- Курсор
 | ||
|     NPOSITION               in number,          -- Номер колонки в курсоре
 | ||
|     BCLEAR                  in boolean := false -- Флаг очистки коллекции (false - не очищать, true - очистить коллекцию перед добавлением)
 | ||
|   );
 | ||
| 
 | ||
|   /* Добавление колонки типа "дата" к строке из курсора динамического запроса */
 | ||
|   procedure TROW_ADD_CUR_COLD
 | ||
|   (
 | ||
|     RROW                    in out nocopy TROW, -- Строка
 | ||
|     SNAME                   in varchar2,        -- Наименование колонки
 | ||
|     ICURSOR                 in integer,         -- Курсор
 | ||
|     NPOSITION               in number,          -- Номер колонки в курсоре
 | ||
|     BCLEAR                  in boolean := false -- Флаг очистки коллекции (false - не очищать, true - очистить коллекцию перед добавлением)
 | ||
|   );
 | ||
|   
 | ||
|   /* Формирование таблицы данных */
 | ||
|   function TDATA_GRID_MAKE
 | ||
|   return                    TDATA_GRID; -- Результат работы
 | ||
|   
 | ||
|   /* Поиск описания колонки в таблице данных по наименованию */
 | ||
|   function TDATA_GRID_FIND_COL_DEF
 | ||
|   (
 | ||
|     RDATA_GRID              in TDATA_GRID, -- Описание таблицы данных
 | ||
|     SNAME                   in varchar2    -- Наименование колонки
 | ||
|   ) return                  TCOL_DEF;      -- Найденное описание (null - если не нашли)
 | ||
|   
 | ||
|   /* Добавление описания колонки к таблице данных */
 | ||
|   procedure TDATA_GRID_ADD_COL_DEF
 | ||
|   (
 | ||
|     RDATA_GRID              in out nocopy TDATA_GRID,      -- Описание таблицы данных
 | ||
|     SNAME                   in varchar2,                   -- Наименование колонки
 | ||
|     SCAPTION                in varchar2,                   -- Заголовок колонки
 | ||
|     SDATA_TYPE              in varchar2 := SDATA_TYPE_STR, -- Тип данных колонки (см. константы SDATA_TYPE_*)
 | ||
|     SCOND_FROM              in varchar2 := null,           -- Наименование нижней границы условия отбора (null - используется UTL_COND_NAME_MAKE_FROM)
 | ||
|     SCOND_TO                in varchar2 := null,           -- Наименование верхней границы условия отбора (null - используется UTL_COND_NAME_MAKE_TO)
 | ||
|     BVISIBLE                in boolean := true,            -- Разрешить отображение
 | ||
|     BORDER                  in boolean := false,           -- Разрешить сортировку по колонке
 | ||
|     BFILTER                 in boolean := false,           -- Разрешить отбор по колонке
 | ||
|     RCOL_VALS               in TCOL_VALS := null,          -- Предопределённые значения колонки
 | ||
|     SHINT                   in varchar2 := null,           -- Текст всплывающей подсказки    
 | ||
|     BCLEAR                  in boolean := false            -- Флаг очистки коллекции описаний колонок таблицы данных (false - не очищать, true - очистить коллекцию перед добавлением)
 | ||
|   );
 | ||
|   
 | ||
|   /* Добавление описания колонки к таблице данных */
 | ||
|   procedure TDATA_GRID_ADD_ROW
 | ||
|   (
 | ||
|     RDATA_GRID              in out nocopy TDATA_GRID, -- Описание таблицы данных
 | ||
|     RROW                    in TROW,                  -- Строка
 | ||
|     BCLEAR                  in boolean := false       -- Флаг очистки коллекции строк таблицы данных (false - не очищать, true - очистить коллекцию перед добавлением)
 | ||
|   );
 | ||
| 
 | ||
|   /* Сериализация таблицы данных */
 | ||
|   function TDATA_GRID_TO_XML
 | ||
|   (
 | ||
|     RDATA_GRID              in TDATA_GRID, -- Описание таблицы данных
 | ||
|     NINCLUDE_DEF            in number := 1 -- Включить описание колонок (0 - нет, 1 - да)
 | ||
|   ) return                  clob;          -- XML-описание
 | ||
| 
 | ||
|   
 | ||
|   /* Конвертация значений фильтра в число */
 | ||
|   procedure TFILTER_TO_NUMBER
 | ||
|   (
 | ||
|     RFILTER                 in TFILTER, -- Фильтр
 | ||
|     NFROM                   out number, -- Значение нижней границы диапазона
 | ||
|     NTO                     out number  -- Значение верхней границы диапазона
 | ||
|   );
 | ||
| 
 | ||
|   /* Конвертация значений фильтра в дату */
 | ||
|   procedure TFILTER_TO_DATE
 | ||
|   (
 | ||
|     RFILTER                 in TFILTER, -- Фильтр
 | ||
|     DFROM                   out date,   -- Значение нижней границы диапазона
 | ||
|     DTO                     out date    -- Значение верхней границы диапазона
 | ||
|   );
 | ||
|   
 | ||
|   /* Поиск фильтра в коллекции */
 | ||
|   function TFILTERS_FIND
 | ||
|   (
 | ||
|     RFILTERS                in TFILTERS, -- Коллекция фильтров
 | ||
|     SNAME                   in varchar2  -- Наименование
 | ||
|   ) return                  TFILTER;     -- Найденный фильтр (null - если не нашли)
 | ||
|   
 | ||
|   /* Десериализация фильтров */
 | ||
|   function TFILTERS_FROM_XML
 | ||
|   (
 | ||
|     CFILTERS                in clob     -- Сериализованное представление фильтров (BASE64(<filters><name>ИМЯ</name><from>ЗНАЧЕНИЕ</from><to>ЗНАЧЕНИЕ</to></filters>...))
 | ||
|   ) return                  TFILTERS;   -- Результат работы
 | ||
| 
 | ||
|   /* Применение параметров фильтрации в запросе */
 | ||
|   procedure TFILTERS_SET_QUERY
 | ||
|   (
 | ||
|     NIDENT                  in number,         -- Идентификатор отбора
 | ||
|     NCOMPANY                in number,         -- Рег. номер организации
 | ||
|     NPARENT                 in number := null, -- Рег. номер родителя
 | ||
|     SUNIT                   in varchar2,       -- Код раздела
 | ||
|     SPROCEDURE              in varchar2,       -- Наименование серверной процедуры отбора
 | ||
|     RDATA_GRID              in TDATA_GRID,     -- Описание таблицы данных
 | ||
|     RFILTERS                in TFILTERS        -- Коллекция фильтров
 | ||
|   );
 | ||
|   
 | ||
|   /* Десериализация сортировок */
 | ||
|   function TORDERS_FROM_XML
 | ||
|   (
 | ||
|     CORDERS                 in clob     -- Сериализованное представление сотрировок (BASE64(<orders><name>ИМЯ</name><direction>ASC/DESC</direction></orders>...))
 | ||
|   ) return                  TORDERS;    -- Результат работы
 | ||
| 
 | ||
|   /* Применение параметров сортировки в запросе */
 | ||
|   procedure TORDERS_SET_QUERY
 | ||
|   (
 | ||
|     RDATA_GRID              in TDATA_GRID,     -- Описание таблицы
 | ||
|     RORDERS                 in TORDERS,        -- Коллекция сортировок
 | ||
|     SPATTERN                in varchar2,       -- Шаблон для подстановки условий отбора в запрос
 | ||
|     CSQL                    in out nocopy clob -- Буфер запроса
 | ||
|   );
 | ||
|   
 | ||
|   /* Формирование задачи для диаграммы Ганта */
 | ||
|   function TGANTT_TASK_MAKE
 | ||
|   (
 | ||
|     NRN                     in number,           -- Рег. номер
 | ||
|     SNUMB                   in varchar2,         -- Номер
 | ||
|     SCAPTION                in varchar2,         -- Заголовок
 | ||
|     SNAME                   in varchar2,         -- Наименование    
 | ||
|     DSTART                  in date,             -- Дата начала
 | ||
|     DEND                    in date,             -- Дата окончания
 | ||
|     NPROGRESS               in number := null,   -- Прогресс (% готовности) задачи (null - не определен)
 | ||
|     SBG_COLOR               in varchar2 := null, -- Цвет заливки задачи (null - использовать цвет по умолчанию из стилей, формат - HTML-цвет, #RRGGBBAA)
 | ||
|     STEXT_COLOR             in varchar2 := null, -- Цвет текста заголовка задачи (null - использовать цвет по умолчанию из стилей, формат - HTML-цвет, #RRGGBBAA)
 | ||
|     BREAD_ONLY              in boolean := null,  -- Сроки и прогресс задачи только для чтения (null - как указано в описании диаграммы)
 | ||
|     BREAD_ONLY_DATES        in boolean := null,  -- Сроки задачи только для чтения (null - как указано в описании диаграммы)
 | ||
|     BREAD_ONLY_PROGRESS     in boolean := null   -- Прогресс задачи только для чтения (null - как указано в описании диаграммы)
 | ||
|   ) return                  TGANTT_TASK;         -- Результат работы
 | ||
|   
 | ||
|   /* Добавление значения атрибута к задаче диаграммы Ганта */
 | ||
|   procedure TGANTT_TASK_ADD_ATTR_VAL
 | ||
|   (
 | ||
|     RGANTT                  in TGANTT,                 -- Описание диаграммы
 | ||
|     RTASK                   in out nocopy TGANTT_TASK, -- Описание задачи
 | ||
|     SNAME                   in varchar2,               -- Наименование
 | ||
|     SVALUE                  in varchar2,               -- Значение
 | ||
|     BCLEAR                  in boolean := false        -- Флаг очистки коллекции значений атрибутов (false - не очищать, true - очистить коллекцию перед добавлением)
 | ||
|   );
 | ||
|   
 | ||
|   /* Добавление предшествующей задачи к задаче диаграммы Ганта */
 | ||
|   procedure TGANTT_TASK_ADD_DEPENDENCY
 | ||
|   (
 | ||
|     RTASK                   in out nocopy TGANTT_TASK, -- Описание задачи
 | ||
|     NDEPENDENCY             in number,                 -- Рег. номер предшествующей задачи
 | ||
|     BCLEAR                  in boolean := false        -- Флаг очистки коллекции предшествущих задач (false - не очищать, true - очистить коллекцию перед добавлением)
 | ||
|   );
 | ||
|   
 | ||
|   /* Формирование диаграммы Ганта */
 | ||
|   function TGANTT_MAKE
 | ||
|   (
 | ||
|     STITLE                  in varchar2 := null,           -- Заголовок (null - не отображать)
 | ||
|     NZOOM                   in number := NGANTT_ZOOM_WEEK, -- Текущий масштаб (см. константы NGANTT_ZOOM_*)
 | ||
|     BZOOM_BAR               in boolean := true,            -- Обображать панель масштабирования
 | ||
|     BREAD_ONLY              in boolean := false,           -- Сроки и прогресс задач только для чтения
 | ||
|     BREAD_ONLY_DATES        in boolean := false,           -- Сроки задач только для чтения
 | ||
|     BREAD_ONLY_PROGRESS     in boolean := false            -- Прогресс задач только для чтения
 | ||
|   ) return                  TGANTT;                        -- Результат работы
 | ||
|   
 | ||
|   /* Добавление описания атрибута карточки задачи диаграммы Ганта */
 | ||
|   procedure TGANTT_ADD_TASK_ATTR
 | ||
|   (
 | ||
|     RGANTT                  in out nocopy TGANTT, -- Описание диаграммы Ганта
 | ||
|     SNAME                   in varchar2,          -- Наименование
 | ||
|     SCAPTION                in varchar2,          -- Заголовок
 | ||
|     BCLEAR                  in boolean := false   -- Флаг очистки коллекции атрибутов (false - не очищать, true - очистить коллекцию перед добавлением)
 | ||
|   );
 | ||
| 
 | ||
|   /* Добавление описания цвета задачи диаграммы Ганта */
 | ||
|   procedure TGANTT_ADD_TASK_COLOR
 | ||
|   (
 | ||
|     RGANTT                  in out nocopy TGANTT, -- Описание диаграммы Ганта
 | ||
|     SBG_COLOR               in varchar2 := null,  -- Цвет заливки задачи (формат - HTML-цвет, #RRGGBBAA)
 | ||
|     STEXT_COLOR             in varchar2 := null,  -- Цвет текста заголовка задачи (формат - HTML-цвет, #RRGGBBAA)
 | ||
|     SDESC                   in varchar2,          -- Описание
 | ||
|     BCLEAR                  in boolean := false   -- Флаг очистки коллекции цветов (false - не очищать, true - очистить коллекцию перед добавлением)
 | ||
|   );
 | ||
| 
 | ||
|   /* Добавление задачи к диаграмме Ганта */
 | ||
|   procedure TGANTT_ADD_TASK
 | ||
|   (
 | ||
|     RGANTT                  in out nocopy TGANTT, -- Описание диаграммы Ганта
 | ||
|     RTASK                   in TGANTT_TASK,       -- Задача
 | ||
|     BCLEAR                  in boolean := false   -- Флаг очистки коллекции задач диаграммы (false - не очищать, true - очистить коллекцию перед добавлением)
 | ||
|   );
 | ||
|   
 | ||
|   /* Сериализация диаграммы Ганта */
 | ||
|   function TGANTT_TO_XML
 | ||
|   (
 | ||
|     RGANTT                  in TGANTT,     -- Описание диаграммы Ганта
 | ||
|     NINCLUDE_DEF            in number := 1 -- Включить описание заголовка (0 - нет, 1 - да)
 | ||
|   ) return                  clob;          -- XML-описание
 | ||
| 
 | ||
|   /* Добавление дополнительного атрибута элемента данных графика */
 | ||
|   procedure TCHART_DATASET_ITM_ATTR_VL_ADD
 | ||
|   (
 | ||
|     RATTR_VALS              in out nocopy TCHART_DATASET_ITEM_ATTR_VALS, -- Коллекция дополнительных атрибутов элемента данных графика
 | ||
|     SNAME                   PKG_STD.TSTRING,                             -- Наименование
 | ||
|     SVALUE                  PKG_STD.TSTRING,                             -- Значение
 | ||
|     BCLEAR                  in boolean := false                          -- Флаг очистки коллекции дополнительных атрибутов элемента данных (false - не очищать, true - очистить коллекцию перед добавлением)
 | ||
|   );
 | ||
| 
 | ||
|   /* Формирование набора данных графика */
 | ||
|   function TCHART_DATASET_MAKE
 | ||
|   (
 | ||
|     SCAPTION                in varchar2,         -- Заголовок
 | ||
|     SBORDER_COLOR           in varchar2 := null, -- Цвет границы элемента данных на графике (null - использовать цвет по умолчанию из стилей, формат - HTML-цвет, #RRGGBBAA)
 | ||
|     SBG_COLOR               in varchar2 := null  -- Цвет заливки элемента данных на графике (null - использовать цвет по умолчанию из стилей, формат - HTML-цвет, #RRGGBBAA)
 | ||
|   ) return                  TCHART_DATASET;      -- Результат работы
 | ||
| 
 | ||
|   /* Добавление элемента в набор данных графика */
 | ||
|   procedure TCHART_DATASET_ADD_ITEM
 | ||
|   (
 | ||
|     RDATASET                in out nocopy TCHART_DATASET,             -- Описание набора данных графика
 | ||
|     NVALUE                  in number,                                -- Значение элемента данных, отображаемое на графике
 | ||
|     RATTR_VALS              in TCHART_DATASET_ITEM_ATTR_VALS := null, -- Значения дополнительных атрбутов (null - дополнительные атрибуты не определены)
 | ||
|     BCLEAR                  in boolean := false                       -- Флаг очистки коллекции элементов набора данных (false - не очищать, true - очистить коллекцию перед добавлением)
 | ||
|   );
 | ||
| 
 | ||
|   /* Формирование графика */
 | ||
|   function TCHART_MAKE
 | ||
|   (
 | ||
|     STYPE                   in varchar2,         -- Тип (см. константы SCHART_TYPE_*)
 | ||
|     STITLE                  in varchar2 := null, -- Заголовок (null - не отображать)
 | ||
|     SLGND_POS               in varchar2 := null  -- Расположение легенды (null - не отображать, см. константы SCHART_LGND_POS_*)
 | ||
|   ) return                  TCHART;              -- Результат работы
 | ||
| 
 | ||
|   /* Добавление метки значения графика */
 | ||
|   procedure TCHART_ADD_LABEL
 | ||
|   (
 | ||
|     RCHART                  in out nocopy TCHART, -- Описание графика
 | ||
|     SLABEL                  in varchar2,          -- Метка значения
 | ||
|     BCLEAR                  in boolean := false   -- Флаг очистки коллекции меток (false - не очищать, true - очистить коллекцию перед добавлением)
 | ||
|   );
 | ||
| 
 | ||
|   /* Добавление набора данных графика */
 | ||
|   procedure TCHART_ADD_DATASET
 | ||
|   (
 | ||
|     RCHART                  in out nocopy TCHART, -- Описание графика
 | ||
|     RDATASET                in TCHART_DATASET,    -- Набор данных
 | ||
|     BCLEAR                  in boolean := false   -- Флаг очистки коллекции наборов данных (false - не очищать, true - очистить коллекцию перед добавлением)
 | ||
|   );
 | ||
| 
 | ||
|   /* Сериализация графика */
 | ||
|   function TCHART_TO_XML
 | ||
|   (
 | ||
|     RCHART                  in TCHART,     -- Описание графика
 | ||
|     NINCLUDE_DEF            in number := 1 -- Включить описание заголовка (0 - нет, 1 - да)
 | ||
|   ) return                  clob;          -- XML-описание
 | ||
| 
 | ||
| end PKG_P8PANELS_VISUAL;
 | ||
| /
 | ||
| create or replace package body PKG_P8PANELS_VISUAL as
 | ||
| /*
 | ||
| TODO: owner="root" created="18.10.2023"
 | ||
| text="Формат data_grid и gant как в chart"
 | ||
| */
 | ||
|   /* Константы - тэги запросов */
 | ||
|   SRQ_TAG_XROOT               constant PKG_STD.TSTRING := 'XROOT';     -- Тэг для корня данных запроса
 | ||
|   SRQ_TAG_XFILTERS            constant PKG_STD.TSTRING := 'filters';   -- Тэг для строк данных
 | ||
|   SRQ_TAG_XORDERS             constant PKG_STD.TSTRING := 'orders';    -- Тэг для описания колонок
 | ||
|   SRQ_TAG_SNAME               constant PKG_STD.TSTRING := 'name';      -- Тэг для наименования
 | ||
|   SRQ_TAG_SDIRECTION          constant PKG_STD.TSTRING := 'direction'; -- Тэг для направления
 | ||
|   SRQ_TAG_SFROM               constant PKG_STD.TSTRING := 'from';      -- Тэг для значения "с"
 | ||
|   SRQ_TAG_STO                 constant PKG_STD.TSTRING := 'to';        -- Тэг для значения "по"
 | ||
| 
 | ||
|   /* Константы - тэги ответов */
 | ||
|   SRESP_TAG_XDATA             constant PKG_STD.TSTRING := 'XDATA';           -- Тэг для корня описания данных
 | ||
|   SRESP_TAG_XROWS             constant PKG_STD.TSTRING := 'XROWS';           -- Тэг для строк данных
 | ||
|   SRESP_TAG_XCOLUMNS_DEF      constant PKG_STD.TSTRING := 'XCOLUMNS_DEF';    -- Тэг для описания колонок
 | ||
|   SRESP_TAG_XGANTT_DEF        constant PKG_STD.TSTRING := 'XGANTT_DEF';      -- Тэг для описания заголовка диаграммы Ганта
 | ||
|   SRESP_TAG_XGANTT_TASKS      constant PKG_STD.TSTRING := 'XGANTT_TASKS';    -- Тэг для описания коллекции задач диаграммы Ганта
 | ||
|   SRESP_TAG_XCHART            constant PKG_STD.TSTRING := 'XCHART';          -- Тэг для описания графика
 | ||
|   
 | ||
|   /* Константы - атрибуты ответов (универсальные) */
 | ||
|   SRESP_ATTR_NAME             constant PKG_STD.TSTRING := 'name';     -- Атрибут для наименования
 | ||
|   SRESP_ATTR_CAPTION          constant PKG_STD.TSTRING := 'caption';  -- Атрибут для подписи
 | ||
|   SRESP_ATTR_DATA_TYPE        constant PKG_STD.TSTRING := 'dataType'; -- Атрибут для типа данных
 | ||
|   SRESP_ATTR_VISIBLE          constant PKG_STD.TSTRING := 'visible';  -- Атрибут для флага видимости
 | ||
|   SRESP_ATTR_TITLE            constant PKG_STD.TSTRING := 'title';    -- Атрибут для заголовка
 | ||
|   SRESP_ATTR_ZOOM             constant PKG_STD.TSTRING := 'zoom';     -- Атрибут для масштаба
 | ||
|   SRESP_ATTR_ID               constant PKG_STD.TSTRING := 'id';       -- Атрибут для идентификатора
 | ||
|   SRESP_ATTR_START            constant PKG_STD.TSTRING := 'start';    -- Атрибут для даты начала
 | ||
|   SRESP_ATTR_END              constant PKG_STD.TSTRING := 'end';      -- Атрибут для даты окончания
 | ||
|   SRESP_ATTR_RN               constant PKG_STD.TSTRING := 'rn';       -- Атрибут для рег. номера
 | ||
|   SRESP_ATTR_NUMB             constant PKG_STD.TSTRING := 'numb';     -- Атрибут для номера
 | ||
|   SRESP_ATTR_FULL_NAME        constant PKG_STD.TSTRING := 'fullName'; -- Атрибут для полного наименования
 | ||
|   SRESP_ATTR_DESC             constant PKG_STD.TSTRING := 'desc';     -- Атрибут для описания
 | ||
|   SRESP_ATTR_TYPE             constant PKG_STD.TSTRING := 'type';     -- Атрибут для типа
 | ||
|   SRESP_ATTR_HINT             constant PKG_STD.TSTRING := 'hint';     -- Атрибут для подсказки
 | ||
| 
 | ||
|   /* Константы - атрибуты ответов (таблица данных) */
 | ||
|   SRESP_ATTR_DT_ORDER         constant PKG_STD.TSTRING := 'order';  -- Атрибут для флага сортировки
 | ||
|   SRESP_ATTR_DT_FILTER        constant PKG_STD.TSTRING := 'filter'; -- Атрибут для флага отбора
 | ||
|   SRESP_ATTR_DT_COLUMN_VALUES constant PKG_STD.TSTRING := 'values'; -- Атрибут для предопределённых значений
 | ||
| 
 | ||
|   /* Константы - атрибуты ответов (диаграмма Ганта) */  
 | ||
|   SRESP_ATTR_GANTT_ZOOM_BAR   constant PKG_STD.TSTRING := 'zoomBar';          -- Атрибут для флага отображения панели масштаба диаграммы Ганта
 | ||
|   SRESP_ATTR_TASK_PROGRESS    constant PKG_STD.TSTRING := 'progress';         -- Атрибут для прогресса задачи
 | ||
|   SRESP_ATTR_TASK_DEPS        constant PKG_STD.TSTRING := 'dependencies';     -- Атрибут для зависимостей задачи
 | ||
|   SRESP_ATTR_TASK_RO          constant PKG_STD.TSTRING := 'readOnly';         -- Атрибут для флага задачи "только для чтения"
 | ||
|   SRESP_ATTR_TASK_RO_PRGRS    constant PKG_STD.TSTRING := 'readOnlyProgress'; -- Атрибут для флага задачи "прогресс только для чтения"
 | ||
|   SRESP_ATTR_TASK_RO_DATES    constant PKG_STD.TSTRING := 'readOnlyDates';    -- Атрибут для флага задачи "даты только для чтения"
 | ||
|   SRESP_ATTR_TASK_BG_COLOR    constant PKG_STD.TSTRING := 'bgColor';          -- Атрибут для цвета заголовка задачи
 | ||
|   SRESP_ATTR_TASK_TEXT_COLOR  constant PKG_STD.TSTRING := 'textColor';        -- Атрибут для цвета текста задачи
 | ||
|   SRESP_ATTR_TASK_ATTRIBUTES  constant PKG_STD.TSTRING := 'taskAttributes';   -- Атрибут для коллекции атрибутов задачи
 | ||
|   SRESP_ATTR_TASK_COLORS      constant PKG_STD.TSTRING := 'taskColors';       -- Атрибут для коллекции цветов задачи
 | ||
| 
 | ||
|   /* Константы - атрибуты ответов (графики) */  
 | ||
|   SRESP_ATTR_CHART_LGND_POS   constant PKG_STD.TSTRING := 'legendPosition';  -- Атрибут для места размешения легенды графика
 | ||
|   SRESP_ATTR_CHART_LABELS     constant PKG_STD.TSTRING := 'labels';          -- Атрибут для меток графика
 | ||
|   SRESP_ATTR_CHART_DATASETS   constant PKG_STD.TSTRING := 'datasets';        -- Атрибут для наборов данных графика
 | ||
|   SRESP_ATTR_CHART_DS_LABEL   constant PKG_STD.TSTRING := 'label';           -- Атрибут для метки набора данных графика
 | ||
|   SRESP_ATTR_CHART_DS_BR_CLR  constant PKG_STD.TSTRING := 'borderColor';     -- Атрибут для цвета границы элемента набора данных графика
 | ||
|   SRESP_ATTR_CHART_DS_BG_CLR  constant PKG_STD.TSTRING := 'backgroundColor'; -- Атрибут для цвета заливки элемента набора данных графика
 | ||
|   SRESP_ATTR_CHART_DS_DATA    constant PKG_STD.TSTRING := 'data';            -- Атрибут для коллекции значений элементов набора данных
 | ||
|   SRESP_ATTR_CHART_DS_ITEMS   constant PKG_STD.TSTRING := 'items';           -- Атрибут для коллекции элементов набора данных
 | ||
|   SRESP_ATTR_CHART_DS_I_VAL   constant PKG_STD.TSTRING := 'value';           -- Атрибут для значения элемента набора данных
 | ||
|   
 | ||
|   /* Константы - параметры условий отбора */
 | ||
|   SCOND_FROM_POSTFIX          constant PKG_STD.TSTRING := 'From'; -- Постфикс наименования нижней границы условия отбора
 | ||
|   SCOND_TO_POSTFIX            constant PKG_STD.TSTRING := 'To';   -- Постфикс наименования верхней границы условия отбора
 | ||
| 
 | ||
|   /* Расчет диапаона выдаваемых записей */
 | ||
|   procedure UTL_ROWS_LIMITS_CALC
 | ||
|   (
 | ||
|     NPAGE_NUMBER            in number,  -- Номер страницы (игнорируется при NPAGE_SIZE=0)
 | ||
|     NPAGE_SIZE              in number,  -- Количество записей на странице (0 - все)
 | ||
|     NROW_FROM               out number, -- Нижняя граница диапазона
 | ||
|     NROW_TO                 out number  -- Верхняя граница диапазона
 | ||
|   )
 | ||
|   is
 | ||
|   begin
 | ||
|     if (COALESCE(NPAGE_SIZE, 0) <= 0)
 | ||
|     then
 | ||
|       NROW_FROM := 1;
 | ||
|       NROW_TO   := 1000000000;
 | ||
|     else
 | ||
|       NROW_FROM := COALESCE(NPAGE_NUMBER, 1) * NPAGE_SIZE - NPAGE_SIZE + 1;
 | ||
|       NROW_TO   := COALESCE(NPAGE_NUMBER, 1) * NPAGE_SIZE;
 | ||
|     end if;
 | ||
|   end UTL_ROWS_LIMITS_CALC;
 | ||
|   
 | ||
|   /* Формирование наименования условия отбора для нижней границы */
 | ||
|   function UTL_COND_NAME_MAKE_FROM
 | ||
|   (
 | ||
|     SNAME                   in varchar2 -- Наименование колонки
 | ||
|   ) return                  varchar2    -- Результат
 | ||
|   is
 | ||
|   begin
 | ||
|     return SNAME || SCOND_FROM_POSTFIX;
 | ||
|   end UTL_COND_NAME_MAKE_FROM;
 | ||
| 
 | ||
|   /* Формирование наименования условия отбора для верхней границы */
 | ||
|   function UTL_COND_NAME_MAKE_TO
 | ||
|   (
 | ||
|     SNAME                   in varchar2 -- Наименование колонки
 | ||
|   ) return                  varchar2    -- Результат
 | ||
|   is
 | ||
|   begin
 | ||
|     return SNAME || SCOND_TO_POSTFIX;
 | ||
|   end UTL_COND_NAME_MAKE_TO;
 | ||
|   
 | ||
|   /* Формирование значения */
 | ||
|   function TCOL_VAL_MAKE
 | ||
|   (
 | ||
|     SVALUE                  in varchar2, -- Значение (строка)
 | ||
|     NVALUE                  in number,   -- Значение (число)
 | ||
|     DVALUE                  in date      -- Значение (дата)
 | ||
|   ) return                  TCOL_VAL     -- Результат работы
 | ||
|   is
 | ||
|     RRES                    TCOL_VAL;    -- Буфер для результата
 | ||
|   begin
 | ||
|     /* Формируем объект */
 | ||
|     RRES.SVALUE := SVALUE;
 | ||
|     RRES.NVALUE := NVALUE;
 | ||
|     RRES.DVALUE := DVALUE;
 | ||
|     /* Возвращаем результат */
 | ||
|     return RRES;
 | ||
|   end TCOL_VAL_MAKE;
 | ||
| 
 | ||
|   /* Добавление значения в коллекцию */
 | ||
|   procedure TCOL_VALS_ADD
 | ||
|   (
 | ||
|     RCOL_VALS               in out nocopy TCOL_VALS, -- Коллекция значений
 | ||
|     SVALUE                  in varchar2 := null,     -- Значение (строка)
 | ||
|     NVALUE                  in number := null,       -- Значение (число)
 | ||
|     DVALUE                  in date := null,         -- Значение (дата)
 | ||
|     BCLEAR                  in boolean := false      -- Флаг очистки коллекции (false - не очищать, true - очистить коллекцию перед добавлением)
 | ||
|   )
 | ||
|   is
 | ||
|   begin
 | ||
|     /* Инициализируем коллекцию если необходимо */
 | ||
|     if ((RCOL_VALS is null) or (BCLEAR)) then
 | ||
|       RCOL_VALS := TCOL_VALS();
 | ||
|     end if;
 | ||
|     /* Добавляем элемент */
 | ||
|     RCOL_VALS.EXTEND();
 | ||
|     RCOL_VALS(RCOL_VALS.LAST) := TCOL_VAL_MAKE(SVALUE => SVALUE, NVALUE => NVALUE, DVALUE => DVALUE);
 | ||
|   end TCOL_VALS_ADD;
 | ||
|   
 | ||
|   /* Формирование описания колонки */
 | ||
|   function TCOL_DEF_MAKE
 | ||
|   (
 | ||
|     SNAME                   in varchar2,                   -- Наименование
 | ||
|     SCAPTION                in varchar2,                   -- Заголовок
 | ||
|     SDATA_TYPE              in varchar2 := SDATA_TYPE_STR, -- Тип данных (см. константы SDATA_TYPE_*)
 | ||
|     SCOND_FROM              in varchar2 := null,           -- Наименование нижней границы условия отбора (null - используется UTL_COND_NAME_MAKE_FROM)
 | ||
|     SCOND_TO                in varchar2 := null,           -- Наименование верхней границы условия отбора (null - используется UTL_COND_NAME_MAKE_TO)
 | ||
|     BVISIBLE                in boolean := true,            -- Разрешить отображение
 | ||
|     BORDER                  in boolean := false,           -- Разрешить сортировку
 | ||
|     BFILTER                 in boolean := false,           -- Разрешить отбор
 | ||
|     RCOL_VALS               in TCOL_VALS := null,          -- Предопределённые значения
 | ||
|     SHINT                   in varchar2 := null            -- Текст всплывающей подсказки
 | ||
|   ) return                  TCOL_DEF                       -- Результат работы
 | ||
|   is
 | ||
|     RRES                    TCOL_DEF;                      -- Буфер для результата
 | ||
|   begin
 | ||
|     /* Формируем объект */
 | ||
|     RRES.SNAME      := SNAME;
 | ||
|     RRES.SCAPTION   := SCAPTION;
 | ||
|     RRES.SDATA_TYPE := COALESCE(SDATA_TYPE, SDATA_TYPE_STR);
 | ||
|     RRES.SCOND_FROM := COALESCE(SCOND_FROM, UTL_COND_NAME_MAKE_FROM(SNAME => SNAME));
 | ||
|     RRES.SCOND_TO   := COALESCE(SCOND_TO, UTL_COND_NAME_MAKE_TO(SNAME => SNAME));
 | ||
|     RRES.BVISIBLE   := COALESCE(BVISIBLE, true);
 | ||
|     RRES.BORDER     := COALESCE(BORDER, false);
 | ||
|     RRES.BFILTER    := COALESCE(BFILTER, false);
 | ||
|     RRES.RCOL_VALS  := COALESCE(RCOL_VALS, TCOL_VALS());
 | ||
|     RRES.SHINT      := SHINT;
 | ||
|     /* Возвращаем результат */
 | ||
|     return RRES;
 | ||
|   end TCOL_DEF_MAKE;
 | ||
|   
 | ||
|   /* Добавление описания колонки в коллекцию */
 | ||
|   procedure TCOL_DEFS_ADD
 | ||
|   (
 | ||
|     RCOL_DEFS               in out nocopy TCOL_DEFS,       -- Коллекция описаний колонок
 | ||
|     SNAME                   in varchar2,                   -- Наименование
 | ||
|     SCAPTION                in varchar2,                   -- Заголовок
 | ||
|     SDATA_TYPE              in varchar2 := SDATA_TYPE_STR, -- Тип данных (см. константы SDATA_TYPE_*)
 | ||
|     SCOND_FROM              in varchar2 := null,           -- Наименование нижней границы условия отбора (null - используется UTL_COND_NAME_MAKE_FROM)
 | ||
|     SCOND_TO                in varchar2 := null,           -- Наименование верхней границы условия отбора (null - используется UTL_COND_NAME_MAKE_TO)
 | ||
|     BVISIBLE                in boolean := true,            -- Разрешить отображение
 | ||
|     BORDER                  in boolean := false,           -- Разрешить сортировку
 | ||
|     BFILTER                 in boolean := false,           -- Разрешить отбор
 | ||
|     RCOL_VALS               in TCOL_VALS := null,          -- Предопределённые значения
 | ||
|     SHINT                   in varchar2 := null,           -- Текст всплывающей подсказки
 | ||
|     BCLEAR                  in boolean := false            -- Флаг очистки коллекции (false - не очищать, true - очистить коллекцию перед добавлением)
 | ||
|   )
 | ||
|   is
 | ||
|   begin
 | ||
|     /* Инициализируем коллекцию если необходимо */
 | ||
|     if ((RCOL_DEFS is null) or (BCLEAR)) then
 | ||
|       RCOL_DEFS := TCOL_DEFS();
 | ||
|     end if;
 | ||
|     /* Добавляем элемент */
 | ||
|     RCOL_DEFS.EXTEND();
 | ||
|     RCOL_DEFS(RCOL_DEFS.LAST) := TCOL_DEF_MAKE(SNAME      => SNAME,
 | ||
|                                                SCAPTION   => SCAPTION,
 | ||
|                                                SDATA_TYPE => SDATA_TYPE,
 | ||
|                                                SCOND_FROM => SCOND_FROM,
 | ||
|                                                SCOND_TO   => SCOND_TO,
 | ||
|                                                BVISIBLE   => BVISIBLE,
 | ||
|                                                BORDER     => BORDER,
 | ||
|                                                BFILTER    => BFILTER,
 | ||
|                                                SHINT      => SHINT,
 | ||
|                                                RCOL_VALS  => RCOL_VALS);
 | ||
|   end TCOL_DEFS_ADD;
 | ||
|   
 | ||
|   /* Поиск описания колонки по наименованию */
 | ||
|   function TCOL_DEFS_FIND
 | ||
|   (
 | ||
|     RCOL_DEFS               in TCOL_DEFS, -- Описание колонок таблицы данных
 | ||
|     SNAME                   in varchar2   -- Наименование
 | ||
|   ) return                  TCOL_DEF      -- Найденное описание (null - если не нашли)
 | ||
|   is
 | ||
|   begin
 | ||
|     /* Обходим колонки из коллекции описаний */
 | ||
|     if ((RCOL_DEFS is not null) and (RCOL_DEFS.COUNT > 0)) then
 | ||
|       for I in RCOL_DEFS.FIRST .. RCOL_DEFS.LAST
 | ||
|       loop
 | ||
|         if (RCOL_DEFS(I).SNAME = SNAME) then
 | ||
|           return RCOL_DEFS(I);
 | ||
|         end if;
 | ||
|       end loop;
 | ||
|     end if;
 | ||
|     /* Ничего не нашли */
 | ||
|     return null;
 | ||
|   end TCOL_DEFS_FIND;
 | ||
|   
 | ||
|   /* Сериализация описания колонки таблицы данных */
 | ||
|   procedure TCOL_DEFS_TO_XML
 | ||
|   (
 | ||
|     RCOL_DEFS               in TCOL_DEFS -- Описание колонок таблицы данных
 | ||
|   )
 | ||
|   is    
 | ||
|   begin
 | ||
|     /* Обходим колонки из коллекции */
 | ||
|     if ((RCOL_DEFS is not null) and (RCOL_DEFS.COUNT > 0)) then
 | ||
|       for I in RCOL_DEFS.FIRST .. RCOL_DEFS.LAST
 | ||
|       loop
 | ||
|         /* Открываем описание колонки */
 | ||
|         PKG_XFAST.DOWN_NODE(SNAME => SRESP_TAG_XCOLUMNS_DEF);
 | ||
|         /* Атрибуты колонки */
 | ||
|         PKG_XFAST.ATTR(SNAME => SRESP_ATTR_NAME, SVALUE => RCOL_DEFS(I).SNAME);
 | ||
|         PKG_XFAST.ATTR(SNAME => SRESP_ATTR_CAPTION, SVALUE => RCOL_DEFS(I).SCAPTION);
 | ||
|         PKG_XFAST.ATTR(SNAME => SRESP_ATTR_DATA_TYPE, SVALUE => RCOL_DEFS(I).SDATA_TYPE);
 | ||
|         PKG_XFAST.ATTR(SNAME => SRESP_ATTR_VISIBLE, BVALUE => RCOL_DEFS(I).BVISIBLE);
 | ||
|         PKG_XFAST.ATTR(SNAME => SRESP_ATTR_DT_ORDER, BVALUE => RCOL_DEFS(I).BORDER);
 | ||
|         PKG_XFAST.ATTR(SNAME => SRESP_ATTR_DT_FILTER, BVALUE => RCOL_DEFS(I).BFILTER);
 | ||
|         PKG_XFAST.ATTR(SNAME => SRESP_ATTR_HINT, SVALUE => RCOL_DEFS(I).SHINT);
 | ||
|         /* Предопределённые значения */
 | ||
|         if (RCOL_DEFS(I).RCOL_VALS is not null) and (RCOL_DEFS(I).RCOL_VALS.COUNT > 0) then
 | ||
|           for V in RCOL_DEFS(I).RCOL_VALS.FIRST .. RCOL_DEFS(I).RCOL_VALS.LAST
 | ||
|           loop
 | ||
|             /* Открываем описание предопределённого значения */
 | ||
|             PKG_XFAST.DOWN_NODE(SNAME => SRESP_ATTR_DT_COLUMN_VALUES);
 | ||
|             /* Значение */
 | ||
|             case RCOL_DEFS(I).SDATA_TYPE
 | ||
|               when SDATA_TYPE_STR then
 | ||
|                 PKG_XFAST.VALUE(SVALUE => RCOL_DEFS(I).RCOL_VALS(V).SVALUE);
 | ||
|               when SDATA_TYPE_NUMB then
 | ||
|                 PKG_XFAST.VALUE(NVALUE => RCOL_DEFS(I).RCOL_VALS(V).NVALUE);
 | ||
|               when SDATA_TYPE_DATE then
 | ||
|                 PKG_XFAST.VALUE(DVALUE => RCOL_DEFS(I).RCOL_VALS(V).DVALUE);
 | ||
|               else
 | ||
|                 P_EXCEPTION(0,
 | ||
|                             'Описание колонки "%s" таблицы данных содержит неподдерживаемый тип данных ("%s").',
 | ||
|                             COALESCE(RCOL_DEFS(I).SNAME, '<НЕ ОПРЕДЕЛЕНА>'),
 | ||
|                             COALESCE(RCOL_DEFS(I).SDATA_TYPE, '<НЕ ОПРЕДЕЛЁН>'));
 | ||
|             end case;
 | ||
|             /* Закрываем описание предопределённого значения */
 | ||
|             PKG_XFAST.UP();          
 | ||
|           end loop;
 | ||
|         end if;
 | ||
|         /* Закрываем описание колонки */
 | ||
|         PKG_XFAST.UP();
 | ||
|       end loop;
 | ||
|     end if;
 | ||
|   end TCOL_DEFS_TO_XML;
 | ||
|   
 | ||
|   /* Формирование колонки */
 | ||
|   function TCOL_MAKE
 | ||
|   (
 | ||
|     SNAME                   in varchar2,         -- Наименование колонки
 | ||
|     SVALUE                  in varchar2 := null, -- Значение (строка)
 | ||
|     NVALUE                  in number := null,   -- Значение (число)
 | ||
|     DVALUE                  in date := null      -- Значение (дата)
 | ||
|   ) return                  TCOL                 -- Результат работы
 | ||
|   is
 | ||
|     RRES                    TCOL;                -- Буфер для результата
 | ||
|   begin
 | ||
|     /* Формируем объект */
 | ||
|     RRES.SNAME    := SNAME;
 | ||
|     RRES.RCOL_VAL := TCOL_VAL_MAKE(SVALUE => SVALUE, NVALUE => NVALUE, DVALUE => DVALUE);
 | ||
|     /* Возвращаем результат */
 | ||
|     return RRES;
 | ||
|   end TCOL_MAKE;
 | ||
|   
 | ||
|   /* Добавление колонки в коллекцию */
 | ||
|   procedure TCOLS_ADD
 | ||
|   (
 | ||
|     RCOLS                   in out nocopy TCOLS, -- Коллекция колонок
 | ||
|     SNAME                   in varchar2,         -- Наименование колонки
 | ||
|     SVALUE                  in varchar2 := null, -- Значение (строка)
 | ||
|     NVALUE                  in number := null,   -- Значение (число)
 | ||
|     DVALUE                  in date := null,     -- Значение (дата)
 | ||
|     BCLEAR                  in boolean := false  -- Флаг очистки коллекции (false - не очищать, true - очистить коллекцию перед добавлением)
 | ||
|   )
 | ||
|   is
 | ||
|   begin
 | ||
|     /* Инициализируем коллекцию если необходимо */
 | ||
|     if ((RCOLS is null) or (BCLEAR)) then
 | ||
|       RCOLS := TCOLS();
 | ||
|     end if;
 | ||
|     /* Добавляем элемент */
 | ||
|     RCOLS.EXTEND();
 | ||
|     RCOLS(RCOLS.LAST) := TCOL_MAKE(SNAME => SNAME, SVALUE => SVALUE, NVALUE => NVALUE, DVALUE => DVALUE);
 | ||
|   end TCOLS_ADD;
 | ||
|   
 | ||
|   /* Формирование строки */
 | ||
|   function TROW_MAKE
 | ||
|   return                    TROW        -- Результат работы
 | ||
|   is
 | ||
|     RRES                    TROW;       -- Буфер для результата
 | ||
|   begin
 | ||
|     /* Формируем объект */
 | ||
|     RRES.RCOLS := TCOLS();
 | ||
|     /* Возвращаем результат */
 | ||
|     return RRES;
 | ||
|   end TROW_MAKE;
 | ||
|   
 | ||
|   /* Добавление колонки к строке */
 | ||
|   procedure TROW_ADD_COL
 | ||
|   (
 | ||
|     RROW                    in out nocopy TROW,  -- Строка
 | ||
|     SNAME                   in varchar2,         -- Наименование колонки
 | ||
|     SVALUE                  in varchar2 := null, -- Значение (строка)
 | ||
|     NVALUE                  in number := null,   -- Значение (число)
 | ||
|     DVALUE                  in date := null,     -- Значение (дата)
 | ||
|     BCLEAR                  in boolean := false  -- Флаг очистки коллекции (false - не очищать, true - очистить коллекцию перед добавлением)
 | ||
|   )
 | ||
|   is
 | ||
|   begin
 | ||
|     /* Сформируем колонку и добавим её к коллекции колонок строки */
 | ||
|     TCOLS_ADD(RCOLS => RROW.RCOLS, SNAME => SNAME, SVALUE => SVALUE, NVALUE => NVALUE, DVALUE => DVALUE, BCLEAR => BCLEAR);
 | ||
|   end TROW_ADD_COL;
 | ||
|   
 | ||
|   /* Добавление строковой колонки к строке из курсора динамического запроса */
 | ||
|   procedure TROW_ADD_CUR_COLS
 | ||
|   (
 | ||
|     RROW                    in out nocopy TROW, -- Строка
 | ||
|     SNAME                   in varchar2,        -- Наименование колонки
 | ||
|     ICURSOR                 in integer,         -- Курсор
 | ||
|     NPOSITION               in number,          -- Номер колонки в курсоре
 | ||
|     BCLEAR                  in boolean := false -- Флаг очистки коллекции (false - не очищать, true - очистить коллекцию перед добавлением)
 | ||
|   )
 | ||
|   is
 | ||
|     SVALUE                  PKG_STD.TLSTRING;   -- Буфер для значения курсора
 | ||
|   begin
 | ||
|     /* Читаем данные из курсора */
 | ||
|     PKG_SQL_DML.COLUMN_VALUE_STR(ICURSOR => ICURSOR, IPOSITION => NPOSITION, SVALUE => SVALUE);
 | ||
|     /* Сформируем колонку и добавим её к коллекции колонок строки */
 | ||
|     TCOLS_ADD(RCOLS => RROW.RCOLS, SNAME => SNAME, SVALUE => SVALUE, NVALUE => null, DVALUE => null, BCLEAR => BCLEAR);
 | ||
|   end TROW_ADD_CUR_COLS;
 | ||
| 
 | ||
|   /* Добавление числовой колонки к строке из курсора динамического запроса */
 | ||
|   procedure TROW_ADD_CUR_COLN
 | ||
|   (
 | ||
|     RROW                    in out nocopy TROW, -- Строка
 | ||
|     SNAME                   in varchar2,        -- Наименование колонки
 | ||
|     ICURSOR                 in integer,         -- Курсор
 | ||
|     NPOSITION               in number,          -- Номер колонки в курсоре
 | ||
|     BCLEAR                  in boolean := false -- Флаг очистки коллекции (false - не очищать, true - очистить коллекцию перед добавлением)
 | ||
|   )
 | ||
|   is
 | ||
|     NVALUE                  PKG_STD.TNUMBER;    -- Буфер для значения курсора
 | ||
|   begin
 | ||
|     /* Читаем данные из курсора */
 | ||
|     PKG_SQL_DML.COLUMN_VALUE_NUM(ICURSOR => ICURSOR, IPOSITION => NPOSITION, NVALUE => NVALUE);
 | ||
|     /* Сформируем колонку и добавим её к коллекции колонок строки */
 | ||
|     TCOLS_ADD(RCOLS => RROW.RCOLS, SNAME => SNAME, SVALUE => null, NVALUE => NVALUE, DVALUE => null, BCLEAR => BCLEAR);
 | ||
|   end TROW_ADD_CUR_COLN;
 | ||
|   
 | ||
|   /* Добавление колонки типа "дата" к строке из курсора динамического запроса */
 | ||
|   procedure TROW_ADD_CUR_COLD
 | ||
|   (
 | ||
|     RROW                    in out nocopy TROW, -- Строка
 | ||
|     SNAME                   in varchar2,        -- Наименование колонки
 | ||
|     ICURSOR                 in integer,         -- Курсор
 | ||
|     NPOSITION               in number,          -- Номер колонки в курсоре
 | ||
|     BCLEAR                  in boolean := false -- Флаг очистки коллекции (false - не очищать, true - очистить коллекцию перед добавлением)
 | ||
|   )
 | ||
|   is
 | ||
|     DVALUE                  PKG_STD.TLDATE;     -- Буфер для значения курсора
 | ||
|   begin
 | ||
|     /* Читаем данные из курсора */
 | ||
|     PKG_SQL_DML.COLUMN_VALUE_DATE(ICURSOR => ICURSOR, IPOSITION => NPOSITION, DVALUE => DVALUE);
 | ||
|     /* Сформируем колонку и добавим её к коллекции колонок строки */
 | ||
|     TCOLS_ADD(RCOLS => RROW.RCOLS, SNAME => SNAME, SVALUE => null, NVALUE => null, DVALUE => DVALUE, BCLEAR => BCLEAR);
 | ||
|   end TROW_ADD_CUR_COLD;
 | ||
|   
 | ||
|   /* Сериализация строки данных таблицы данных */
 | ||
|   procedure TROWS_TO_XML
 | ||
|   (
 | ||
|     RCOL_DEFS               in TCOL_DEFS, -- Описание колонок таблицы данных
 | ||
|     RROWS                   in TROWS      -- Строки таблицы данных
 | ||
|   )
 | ||
|   is  
 | ||
|     RCOL_DEF                TCOL_DEF;     -- Описание текущей сериализуемой колонки
 | ||
|   begin
 | ||
|     /* Обходим строки из коллекции */
 | ||
|     if ((RROWS is not null) and (RROWS.COUNT > 0)) then
 | ||
|       for I in RROWS.FIRST .. RROWS.LAST
 | ||
|       loop
 | ||
|         /* Открываем строку */
 | ||
|         PKG_XFAST.DOWN_NODE(SNAME => SRESP_TAG_XROWS);
 | ||
|         /* Обходим колонки строки */
 | ||
|         if ((RROWS(I).RCOLS is not null) and (RROWS(I).RCOLS.COUNT > 0)) then
 | ||
|           for J in RROWS(I).RCOLS.FIRST .. RROWS(I).RCOLS.LAST
 | ||
|           loop
 | ||
|             /* Найдём описание колонки */
 | ||
|             RCOL_DEF := TCOL_DEFS_FIND(RCOL_DEFS => RCOL_DEFS, SNAME => RROWS(I).RCOLS(J).SNAME);
 | ||
|             if (RCOL_DEF.SNAME is null) then
 | ||
|               P_EXCEPTION(0,
 | ||
|                           'Описание колонки "%s" таблицы данных не определено.',
 | ||
|                           RROWS(I).RCOLS(J).SNAME);
 | ||
|             end if;
 | ||
|             /* Добавлением значение колонки как атрибут строки */
 | ||
|             case RCOL_DEF.SDATA_TYPE
 | ||
|               when SDATA_TYPE_STR then
 | ||
|                 PKG_XFAST.ATTR(SNAME => RROWS(I).RCOLS(J).SNAME, SVALUE => RROWS(I).RCOLS(J).RCOL_VAL.SVALUE);
 | ||
|               when SDATA_TYPE_NUMB then
 | ||
|                 PKG_XFAST.ATTR(SNAME => RROWS(I).RCOLS(J).SNAME, NVALUE => RROWS(I).RCOLS(J).RCOL_VAL.NVALUE);
 | ||
|               when SDATA_TYPE_DATE then
 | ||
|                 PKG_XFAST.ATTR(SNAME => RROWS(I).RCOLS(J).SNAME, DVALUE => RROWS(I).RCOLS(J).RCOL_VAL.DVALUE);
 | ||
|               else
 | ||
|                 P_EXCEPTION(0,
 | ||
|                             'Описание колонки "%s" таблицы данных содержит неподдерживаемый тип данных ("%s").',
 | ||
|                             RCOL_DEFS(I).SNAME,
 | ||
|                             COALESCE(RCOL_DEFS(I).SDATA_TYPE, '<НЕ ОПРЕДЕЛЁН>'));
 | ||
|             end case;
 | ||
|           end loop;
 | ||
|         end if;
 | ||
|         /* Закрываем строку */
 | ||
|         PKG_XFAST.UP();
 | ||
|       end loop;
 | ||
|     end if;
 | ||
|   end TROWS_TO_XML;
 | ||
|   
 | ||
|   /* Формирование таблицы данных */
 | ||
|   function TDATA_GRID_MAKE
 | ||
|   return                    TDATA_GRID  -- Результат работы
 | ||
|   is
 | ||
|     RRES                    TDATA_GRID; -- Буфер для результата
 | ||
|   begin
 | ||
|     /* Формируем объект */
 | ||
|     RRES.RCOL_DEFS := TCOL_DEFS();
 | ||
|     RRES.RROWS     := TROWS();
 | ||
|     /* Возвращаем результат */
 | ||
|     return RRES;
 | ||
|   end TDATA_GRID_MAKE;
 | ||
|   
 | ||
|   /* Поиск описания колонки в таблице данных по наименованию */
 | ||
|   function TDATA_GRID_FIND_COL_DEF
 | ||
|   (
 | ||
|     RDATA_GRID              in TDATA_GRID, -- Описание таблицы данных
 | ||
|     SNAME                   in varchar2    -- Наименование колонки
 | ||
|   ) return                  TCOL_DEF       -- Найденное описание (null - если не нашли)
 | ||
|   is
 | ||
|   begin
 | ||
|     return TCOL_DEFS_FIND(RCOL_DEFS => RDATA_GRID.RCOL_DEFS, SNAME => SNAME);
 | ||
|   end TDATA_GRID_FIND_COL_DEF;
 | ||
|   
 | ||
|   /* Добавление описания колонки к таблице данных */
 | ||
|   procedure TDATA_GRID_ADD_COL_DEF
 | ||
|   (
 | ||
|     RDATA_GRID              in out nocopy TDATA_GRID,      -- Описание таблицы данных
 | ||
|     SNAME                   in varchar2,                   -- Наименование колонки
 | ||
|     SCAPTION                in varchar2,                   -- Заголовок колонки
 | ||
|     SDATA_TYPE              in varchar2 := SDATA_TYPE_STR, -- Тип данных колонки (см. константы SDATA_TYPE_*)
 | ||
|     SCOND_FROM              in varchar2 := null,           -- Наименование нижней границы условия отбора (null - используется UTL_COND_NAME_MAKE_FROM)
 | ||
|     SCOND_TO                in varchar2 := null,           -- Наименование верхней границы условия отбора (null - используется UTL_COND_NAME_MAKE_TO)
 | ||
|     BVISIBLE                in boolean := true,            -- Разрешить отображение
 | ||
|     BORDER                  in boolean := false,           -- Разрешить сортировку по колонке
 | ||
|     BFILTER                 in boolean := false,           -- Разрешить отбор по колонке
 | ||
|     RCOL_VALS               in TCOL_VALS := null,          -- Предопределённые значения колонки
 | ||
|     SHINT                   in varchar2 := null,           -- Текст всплывающей подсказки
 | ||
|     BCLEAR                  in boolean := false            -- Флаг очистки коллекции описаний колонок таблицы данных (false - не очищать, true - очистить коллекцию перед добавлением)
 | ||
|   )
 | ||
|   is
 | ||
|   begin
 | ||
|     /* Формируем описание и добавляем в коллекцию таблицы данных */
 | ||
|     TCOL_DEFS_ADD(RCOL_DEFS  => RDATA_GRID.RCOL_DEFS,
 | ||
|                   SNAME      => SNAME,
 | ||
|                   SCAPTION   => SCAPTION,
 | ||
|                   SDATA_TYPE => SDATA_TYPE,
 | ||
|                   SCOND_FROM => SCOND_FROM,
 | ||
|                   SCOND_TO   => SCOND_TO,
 | ||
|                   BVISIBLE   => BVISIBLE,
 | ||
|                   BORDER     => BORDER,
 | ||
|                   BFILTER    => BFILTER,
 | ||
|                   RCOL_VALS  => RCOL_VALS,
 | ||
|                   SHINT      => SHINT,
 | ||
|                   BCLEAR     => BCLEAR);
 | ||
|   end TDATA_GRID_ADD_COL_DEF;
 | ||
|   
 | ||
|   /* Добавление описания колонки к таблице данных */
 | ||
|   procedure TDATA_GRID_ADD_ROW
 | ||
|   (
 | ||
|     RDATA_GRID              in out nocopy TDATA_GRID, -- Описание таблицы данных
 | ||
|     RROW                    in TROW,                  -- Строка
 | ||
|     BCLEAR                  in boolean := false       -- Флаг очистки коллекции строк таблицы данных (false - не очищать, true - очистить коллекцию перед добавлением)
 | ||
|   )
 | ||
|   is
 | ||
|   begin
 | ||
|     /* Инициализируем коллекцию если необходимо */
 | ||
|     if ((RDATA_GRID.RROWS is null) or (BCLEAR)) then
 | ||
|       RDATA_GRID.RROWS := TROWS();
 | ||
|     end if;
 | ||
|     /* Добавляем элемент */
 | ||
|     RDATA_GRID.RROWS.EXTEND();
 | ||
|     RDATA_GRID.RROWS(RDATA_GRID.RROWS.LAST) := RROW;
 | ||
|   end TDATA_GRID_ADD_ROW;
 | ||
|   
 | ||
|   /* Сериализация таблицы данных */
 | ||
|   function TDATA_GRID_TO_XML
 | ||
|   (
 | ||
|     RDATA_GRID              in TDATA_GRID, -- Описание таблицы данных
 | ||
|     NINCLUDE_DEF            in number := 1 -- Включить описание колонок (0 - нет, 1 - да)
 | ||
|   ) return                  clob           -- XML-описание
 | ||
|   is
 | ||
|     CRES                    clob;          -- Буфер для результата
 | ||
|   begin
 | ||
|     /* Начинаем формирование XML */
 | ||
|     PKG_XFAST.PROLOGUE(ITYPE => PKG_XFAST.CONTENT_);
 | ||
|     /* Открываем корень */
 | ||
|     PKG_XFAST.DOWN_NODE(SNAME => SRESP_TAG_XDATA);
 | ||
|     /* Если необходимо включить описание колонок */
 | ||
|     if (NINCLUDE_DEF = 1) then
 | ||
|       TCOL_DEFS_TO_XML(RCOL_DEFS => RDATA_GRID.RCOL_DEFS);
 | ||
|     end if;
 | ||
|     /* Формируем описание строк */
 | ||
|     TROWS_TO_XML(RCOL_DEFS => RDATA_GRID.RCOL_DEFS, RROWS => RDATA_GRID.RROWS);
 | ||
|     /* Закрываем корень */
 | ||
|     PKG_XFAST.UP();
 | ||
|     /* Сериализуем */
 | ||
|     CRES := PKG_XFAST.SERIALIZE_TO_CLOB();
 | ||
|     /* Завершаем формирование XML */
 | ||
|     PKG_XFAST.EPILOGUE();
 | ||
|     /* Возвращаем полученное */
 | ||
|     return CRES;
 | ||
|   exception
 | ||
|     when others then
 | ||
|       /* Завершаем формирование XML */
 | ||
|       PKG_XFAST.EPILOGUE();
 | ||
|       /* Вернем ошибку */
 | ||
|       PKG_STATE.DIAGNOSTICS_STACKED();
 | ||
|       P_EXCEPTION(0, PKG_STATE.SQL_ERRM());
 | ||
|   end TDATA_GRID_TO_XML;
 | ||
|   
 | ||
|   /* Конвертация значений фильтра в число */
 | ||
|   procedure TFILTER_TO_NUMBER
 | ||
|   (
 | ||
|     RFILTER                 in TFILTER, -- Фильтр
 | ||
|     NFROM                   out number, -- Значение нижней границы диапазона
 | ||
|     NTO                     out number  -- Значение верхней границы диапазона
 | ||
|   )
 | ||
|   is
 | ||
|   begin
 | ||
|     /* Нижняя граница диапазона */
 | ||
|     if (RFILTER.SFROM is not null) then
 | ||
|       begin
 | ||
|         NFROM := PKG_P8PANELS_BASE.UTL_S2N(SVALUE => RFILTER.SFROM);
 | ||
|       exception
 | ||
|         when others then
 | ||
|           P_EXCEPTION(0,
 | ||
|                       'Неверный формат числа (%s) в указанной нижней границе диапазона фильтра.',
 | ||
|                       RFILTER.SFROM);
 | ||
|       end;
 | ||
|     end if;
 | ||
|     /* Верхняя граница диапазона */    
 | ||
|     if (RFILTER.STO is not null) then
 | ||
|       begin
 | ||
|         NTO := PKG_P8PANELS_BASE.UTL_S2N(SVALUE => RFILTER.STO);
 | ||
|       exception
 | ||
|         when others then
 | ||
|           P_EXCEPTION(0,
 | ||
|                       'Неверный формат числа (%s) в указанной верхней границе диапазона фильтра.',
 | ||
|                       RFILTER.STO);
 | ||
|       end;
 | ||
|     end if;
 | ||
|   end TFILTER_TO_NUMBER;
 | ||
|   
 | ||
|   /* Конвертация значений фильтра в дату */
 | ||
|   procedure TFILTER_TO_DATE
 | ||
|   (
 | ||
|     RFILTER                 in TFILTER, -- Фильтр
 | ||
|     DFROM                   out date,   -- Значение нижней границы диапазона
 | ||
|     DTO                     out date    -- Значение верхней границы диапазона
 | ||
|   )
 | ||
|   is
 | ||
|   begin
 | ||
|     /* Нижняя граница диапазона */
 | ||
|     if (RFILTER.SFROM is not null) then
 | ||
|       begin
 | ||
|         DFROM := PKG_P8PANELS_BASE.UTL_S2D(SVALUE => RFILTER.SFROM);
 | ||
|       exception
 | ||
|         when others then
 | ||
|           P_EXCEPTION(0,
 | ||
|                       'Неверный формат даты (%s) в указанной нижней границе диапазона фильтра.',
 | ||
|                       RFILTER.SFROM);
 | ||
|       end;
 | ||
|     end if;
 | ||
|     /* Верхняя граница диапазона */
 | ||
|     if (RFILTER.STO is not null) then
 | ||
|       begin
 | ||
|         DTO := PKG_P8PANELS_BASE.UTL_S2D(SVALUE => RFILTER.STO);
 | ||
|       exception
 | ||
|         when others then
 | ||
|           P_EXCEPTION(0,
 | ||
|                       'Неверный формат даты (%s) в указанной верхней границе диапазона фильтра.',
 | ||
|                       RFILTER.STO);
 | ||
|       end;
 | ||
|     end if;
 | ||
|   end TFILTER_TO_DATE;
 | ||
| 
 | ||
|   /* Формирование фильтра */
 | ||
|   function TFILTER_MAKE
 | ||
|   (
 | ||
|     SNAME                   in varchar2, -- Наименование
 | ||
|     SFROM                   in varchar2, -- Значение "с"
 | ||
|     STO                     in varchar2  -- Значение "по"
 | ||
|   ) return                  TFILTER      -- Результат работы
 | ||
|   is
 | ||
|     RRES                    TFILTER;    -- Буфер для результата
 | ||
|   begin
 | ||
|     /* Формируем объект */
 | ||
|     RRES.SNAME := SNAME;
 | ||
|     RRES.SFROM := SFROM;
 | ||
|     RRES.STO   := STO;
 | ||
|     /* Возвращаем результат */
 | ||
|     return RRES;
 | ||
|   end TFILTER_MAKE;
 | ||
|   
 | ||
|   /* Поиск фильтра в коллекции */
 | ||
|   function TFILTERS_FIND
 | ||
|   (
 | ||
|     RFILTERS                in TFILTERS, -- Коллекция фильтров
 | ||
|     SNAME                   in varchar2  -- Наименование
 | ||
|   ) return                  TFILTER      -- Найденный фильтр (null - если не нашли)
 | ||
|   is
 | ||
|   begin
 | ||
|     /* Обходим фильтры из коллекции */
 | ||
|     if ((RFILTERS is not null) and (RFILTERS.COUNT > 0)) then
 | ||
|       for I in RFILTERS.FIRST .. RFILTERS.LAST
 | ||
|       loop
 | ||
|         if (RFILTERS(I).SNAME = SNAME) then
 | ||
|           return RFILTERS(I);
 | ||
|         end if;
 | ||
|       end loop;
 | ||
|     end if;
 | ||
|     /* Ничего не нашли */
 | ||
|     return null;
 | ||
|   end TFILTERS_FIND;
 | ||
|   
 | ||
|   /* Десериализация фильтров */
 | ||
|   function TFILTERS_FROM_XML
 | ||
|   (
 | ||
|     CFILTERS                in clob              -- Сериализованное представление фильтров (BASE64(<filters><name>ИМЯ</name><from>ЗНАЧЕНИЕ</from><to>ЗНАЧЕНИЕ</to></filters>...))
 | ||
|   ) return                  TFILTERS             -- Результат работы
 | ||
|   is
 | ||
|     RFILTERS                TFILTERS;            -- Буфер для результата работы
 | ||
|     XDOC                    PKG_XPATH.TDOCUMENT; -- Документ XML
 | ||
|     XROOT                   PKG_XPATH.TNODE;     -- Корень документа XML
 | ||
|     XNODE                   PKG_XPATH.TNODE;     -- Буфер узла документа
 | ||
|     XNODES                  PKG_XPATH.TNODES;    -- Буфер коллекции узлов документа
 | ||
|   begin
 | ||
|     /* Вернём выходную коллекцию */
 | ||
|     RFILTERS := TFILTERS();
 | ||
|     /* Разбираем XML */
 | ||
|     XDOC := PKG_XPATH.PARSE_FROM_CLOB(LCXML => '<' || SRQ_TAG_XROOT || '>' ||
 | ||
|                                                BLOB2CLOB(LBDATA   => BASE64_DECODE(LCSRCE => CFILTERS),
 | ||
|                                                          SCHARSET => PKG_CHARSET.CHARSET_UTF_()) || '</' ||
 | ||
|                                                SRQ_TAG_XROOT || '>');
 | ||
|     /* Считываем корневой узел */
 | ||
|     XROOT := PKG_XPATH.ROOT_NODE(RDOCUMENT => XDOC);
 | ||
|     /* Считывание списка записей */
 | ||
|     XNODES := PKG_XPATH.LIST_NODES(RPARENT_NODE => XROOT, SPATTERN => '/' || SRQ_TAG_XROOT || '/' || SRQ_TAG_XFILTERS);
 | ||
|     /* Цикл по списку записией */
 | ||
|     for I in 1 .. PKG_XPATH.COUNT_NODES(RNODES => XNODES)
 | ||
|     loop
 | ||
|       /* Считаем элемент по его номеру */
 | ||
|       XNODE := PKG_XPATH.ITEM_NODE(RNODES => XNODES, INUMBER => I);
 | ||
|       /* Добавим его в коллекцию */
 | ||
|       RFILTERS.EXTEND();
 | ||
|       RFILTERS(RFILTERS.LAST) := TFILTER_MAKE(SNAME => PKG_XPATH.VALUE(RNODE => XNODE, SPATTERN => SRQ_TAG_SNAME),
 | ||
|                                               SFROM => PKG_XPATH.VALUE(RNODE => XNODE, SPATTERN => SRQ_TAG_SFROM),
 | ||
|                                               STO   => PKG_XPATH.VALUE(RNODE => XNODE, SPATTERN => SRQ_TAG_STO));
 | ||
|     end loop;
 | ||
|     /* Освободим документ */
 | ||
|     PKG_XPATH.FREE(RDOCUMENT => XDOC);
 | ||
|     /* Вернём результат */
 | ||
|     return RFILTERS;
 | ||
|   exception
 | ||
|     when others then
 | ||
|       /* Освободим документ */
 | ||
|       PKG_XPATH.FREE(RDOCUMENT => XDOC);
 | ||
|       /* Вернем ошибку */
 | ||
|       PKG_STATE.DIAGNOSTICS_STACKED();
 | ||
|       P_EXCEPTION(0, PKG_STATE.SQL_ERRM());
 | ||
|   end TFILTERS_FROM_XML;
 | ||
|   
 | ||
|   /* Применение параметров фильтрации в запросе */
 | ||
|   procedure TFILTERS_SET_QUERY
 | ||
|   (
 | ||
|     NIDENT                  in number,         -- Идентификатор отбора
 | ||
|     NCOMPANY                in number,         -- Рег. номер организации
 | ||
|     NPARENT                 in number := null, -- Рег. номер родителя
 | ||
|     SUNIT                   in varchar2,       -- Код раздела
 | ||
|     SPROCEDURE              in varchar2,       -- Наименование серверной процедуры отбора
 | ||
|     RDATA_GRID              in TDATA_GRID,     -- Описание таблицы данных
 | ||
|     RFILTERS                in TFILTERS        -- Коллекция фильтров
 | ||
|   )
 | ||
|   is
 | ||
|     RCOL_DEF                TCOL_DEF;          -- Описание текущей фильтруемой колонки
 | ||
|     BENUM                   boolean;           -- Флаг начиличия перечисляемых значений
 | ||
|     NFROM                   PKG_STD.TNUMBER;   -- Буфер для верхней границы диапазона отбора чисел
 | ||
|     NTO                     PKG_STD.TNUMBER;   -- Буфер для нижней границы диапазона отбора чисел
 | ||
|     DFROM                   PKG_STD.TLDATE;    -- Буфер для верхней границы диапазона отбора дат
 | ||
|     DTO                     PKG_STD.TLDATE;    -- Буфер для нижней границы диапазона отбора дат
 | ||
|   begin
 | ||
|     /* Формирование условий отбора - Пролог */
 | ||
|     PKG_COND_BROKER.PROLOGUE(IMODE => PKG_COND_BROKER.MODE_SMART_, NIDENT => NIDENT);
 | ||
|     /* Формирование условий отбора - Установка процедуры серверного отбора */
 | ||
|     PKG_COND_BROKER.SET_PROCEDURE(SPROCEDURE_NAME => SPROCEDURE);
 | ||
|     /* Формирование условий отбора - Установка раздела */
 | ||
|     PKG_COND_BROKER.SET_UNIT(SUNITCODE => SUNIT);
 | ||
|     /* Формирование условий отбора - Установка организации */
 | ||
|     PKG_COND_BROKER.SET_COMPANY(NCOMPANY => NCOMPANY);
 | ||
|     /* Формирование условий отбора - Установка родителя */
 | ||
|     if (NPARENT is not null) then
 | ||
|       PKG_COND_BROKER.SET_PARENT(NPARENT => NPARENT);
 | ||
|     end if;
 | ||
|     /* Обходим фильтр, если задан */
 | ||
|     if ((RFILTERS is not null) and (RFILTERS.COUNT > 0)) then
 | ||
|       for I in RFILTERS.FIRST .. RFILTERS.LAST
 | ||
|       loop
 | ||
|         /* Найдем фильтруемую колонку в описании */
 | ||
|         RCOL_DEF := TCOL_DEFS_FIND(RCOL_DEFS => RDATA_GRID.RCOL_DEFS, SNAME => RFILTERS(I).SNAME);
 | ||
|         if (RCOL_DEF.SNAME is not null) then
 | ||
|           /* Определимся с наличием перечисляемых значений */
 | ||
|           if ((RCOL_DEF.RCOL_VALS is not null) and (RCOL_DEF.RCOL_VALS.COUNT > 0)) then
 | ||
|             BENUM := true;
 | ||
|           else
 | ||
|             BENUM := false;
 | ||
|           end if;
 | ||
|           /* Установим для неё условие отобра согласно типу данных */
 | ||
|           case RCOL_DEF.SDATA_TYPE
 | ||
|             when SDATA_TYPE_STR then
 | ||
|               begin
 | ||
|                 if (BENUM) then
 | ||
|                   PKG_COND_BROKER.SET_CONDITION_ESTR(SCONDITION_NAME   => RCOL_DEF.SCOND_FROM,
 | ||
|                                                      SCONDITION_ESTR   => RFILTERS(I).SFROM,
 | ||
|                                                      ICASE_INSENSITIVE => 1);
 | ||
|                 else
 | ||
|                   PKG_COND_BROKER.SET_CONDITION_STR(SCONDITION_NAME   => RCOL_DEF.SCOND_FROM,
 | ||
|                                                     SCONDITION_VALUE  => RFILTERS(I).SFROM,
 | ||
|                                                     ICASE_INSENSITIVE => 1);
 | ||
|                 end if;
 | ||
|               end;
 | ||
|             when SDATA_TYPE_NUMB then
 | ||
|               begin
 | ||
|                 if (BENUM) then
 | ||
|                   PKG_COND_BROKER.SET_CONDITION_ENUM(SCONDITION_NAME => RCOL_DEF.SCOND_FROM,
 | ||
|                                                      SCONDITION_ENUM => RFILTERS(I).SFROM);
 | ||
|                 else
 | ||
|                   TFILTER_TO_NUMBER(RFILTER => RFILTERS(I), NFROM => NFROM, NTO => NTO);
 | ||
|                   if (NFROM is not null) then
 | ||
|                     PKG_COND_BROKER.SET_CONDITION_NUM(SCONDITION_NAME  => RCOL_DEF.SCOND_FROM,
 | ||
|                                                       NCONDITION_VALUE => NFROM);
 | ||
|                   end if;
 | ||
|                   if (NTO is not null) then
 | ||
|                     PKG_COND_BROKER.SET_CONDITION_NUM(SCONDITION_NAME => RCOL_DEF.SCOND_TO, NCONDITION_VALUE => NTO);
 | ||
|                   end if;
 | ||
|                 end if;
 | ||
|               end;
 | ||
|             when SDATA_TYPE_DATE then
 | ||
|               begin
 | ||
|                 if (BENUM) then                  
 | ||
|                   PKG_COND_BROKER.SET_CONDITION_EDATE(SCONDITION_NAME => RCOL_DEF.SCOND_FROM,
 | ||
|                                                       SCONDITION_EDATE => RFILTERS(I).SFROM);
 | ||
|                 else
 | ||
|                   TFILTER_TO_DATE(RFILTER => RFILTERS(I), DFROM => DFROM, DTO => DTO);
 | ||
|                   if (DFROM is not null) then
 | ||
|                     PKG_COND_BROKER.SET_CONDITION_DATE(SCONDITION_NAME  => RCOL_DEF.SCOND_FROM,
 | ||
|                                                        DCONDITION_VALUE => DFROM);
 | ||
|                   end if;
 | ||
|                   if (DTO is not null) then
 | ||
|                     PKG_COND_BROKER.SET_CONDITION_DATE(SCONDITION_NAME => RCOL_DEF.SCOND_TO, DCONDITION_VALUE => DTO);
 | ||
|                   end if;
 | ||
|                 end if;
 | ||
|               end;
 | ||
|             else
 | ||
|               P_EXCEPTION(0,
 | ||
|                           'Описание колонки "%s" таблицы данных содержит неподдерживаемый тип данных ("%s").',
 | ||
|                           RCOL_DEF.SNAME,
 | ||
|                           COALESCE(RCOL_DEF.SDATA_TYPE, '<НЕ ОПРЕДЕЛЁН>'));
 | ||
|           end case;
 | ||
|         end if;
 | ||
|       end loop;
 | ||
|     end if;
 | ||
|     /* Формирование условий отбора - Эпилог */
 | ||
|     PKG_COND_BROKER.EPILOGUE();
 | ||
|   end TFILTERS_SET_QUERY;
 | ||
|   
 | ||
|   /* Формирование сортировки */
 | ||
|   function TORDER_MAKE
 | ||
|   (
 | ||
|     SNAME                   in varchar2, -- Наименование
 | ||
|     SDIRECTION              in varchar2  -- Направление (см. константы SORDER_DIRECTION_*)
 | ||
|   ) return                  TORDER       -- Результат работы
 | ||
|   is
 | ||
|     RRES                    TORDER;      -- Буфер для результата
 | ||
|   begin
 | ||
|     /* Формируем объект */
 | ||
|     RRES.SNAME      := SNAME;
 | ||
|     RRES.SDIRECTION := SDIRECTION;
 | ||
|     /* Возвращаем результат */
 | ||
|     return RRES;
 | ||
|   end TORDER_MAKE;
 | ||
|   
 | ||
|   /* Десериализация сортировок */
 | ||
|   function TORDERS_FROM_XML
 | ||
|   (
 | ||
|     CORDERS                 in clob              -- Сериализованное представление сотрировок (BASE64(<orders><name>ИМЯ</name><direction>ASC/DESC</direction></orders>...))
 | ||
|   ) return                  TORDERS              -- Результат работы
 | ||
|   is
 | ||
|     RORDERS                 TORDERS;             -- Буфер для результата работы
 | ||
|     XDOC                    PKG_XPATH.TDOCUMENT; -- Документ XML
 | ||
|     XROOT                   PKG_XPATH.TNODE;     -- Корень документа XML
 | ||
|     XNODE                   PKG_XPATH.TNODE;     -- Буфер узла документа
 | ||
|     XNODES                  PKG_XPATH.TNODES;    -- Буфер коллекции узлов документа
 | ||
|   begin
 | ||
|     /* Инициализируем выходную коллекцию */
 | ||
|     RORDERS := TORDERS();
 | ||
|     /* Разбираем XML */
 | ||
|     XDOC := PKG_XPATH.PARSE_FROM_CLOB(LCXML => '<' || SRQ_TAG_XROOT || '>' ||
 | ||
|                                                BLOB2CLOB(LBDATA   => BASE64_DECODE(LCSRCE => CORDERS),
 | ||
|                                                          SCHARSET => PKG_CHARSET.CHARSET_UTF_()) || '</' ||
 | ||
|                                                SRQ_TAG_XROOT || '>');
 | ||
|     /* Считываем корневой узел */
 | ||
|     XROOT := PKG_XPATH.ROOT_NODE(RDOCUMENT => XDOC);
 | ||
|     /* Считывание списка записей */
 | ||
|     XNODES := PKG_XPATH.LIST_NODES(RPARENT_NODE => XROOT, SPATTERN => '/' || SRQ_TAG_XROOT || '/' || SRQ_TAG_XORDERS);
 | ||
|     /* Цикл по списку записией */
 | ||
|     for I in 1 .. PKG_XPATH.COUNT_NODES(RNODES => XNODES)
 | ||
|     loop
 | ||
|       /* Считаем элемент по его номеру */
 | ||
|       XNODE := PKG_XPATH.ITEM_NODE(RNODES => XNODES, INUMBER => I);
 | ||
|       /* Добавим его в коллекцию */
 | ||
|       RORDERS.EXTEND();
 | ||
|       RORDERS(RORDERS.LAST) := TORDER_MAKE(SNAME      => PKG_XPATH.VALUE(RNODE => XNODE, SPATTERN => SRQ_TAG_SNAME),
 | ||
|                                            SDIRECTION => PKG_XPATH.VALUE(RNODE => XNODE, SPATTERN => SRQ_TAG_SDIRECTION));
 | ||
|     end loop;
 | ||
|     /* Освободим документ */
 | ||
|     PKG_XPATH.FREE(RDOCUMENT => XDOC);
 | ||
|     /* Вернём результат */
 | ||
|     return RORDERS;
 | ||
|   exception
 | ||
|     when others then
 | ||
|       /* Освободим документ */
 | ||
|       PKG_XPATH.FREE(RDOCUMENT => XDOC);
 | ||
|       /* Вернем ошибку */
 | ||
|       PKG_STATE.DIAGNOSTICS_STACKED();
 | ||
|       P_EXCEPTION(0, PKG_STATE.SQL_ERRM());
 | ||
|   end TORDERS_FROM_XML;
 | ||
|   
 | ||
|   /* Применение параметров сортировки в запросе */
 | ||
|   procedure TORDERS_SET_QUERY
 | ||
|   (
 | ||
|     RDATA_GRID              in TDATA_GRID,      -- Описание таблицы
 | ||
|     RORDERS                 in TORDERS,         -- Коллекция сортировок
 | ||
|     SPATTERN                in varchar2,        -- Шаблон для подстановки условий отбора в запрос    
 | ||
|     CSQL                    in out nocopy clob  -- Буфер запроса
 | ||
|   )
 | ||
|   is
 | ||
|     CSQL_ORDERS             clob;               -- Буфер для условий сортировки в запросе
 | ||
|   begin
 | ||
|     /* Если сортировка задана */
 | ||
|     if ((RORDERS is not null) and (RORDERS.COUNT > 0)) then
 | ||
|       CSQL_ORDERS := ' order by ';
 | ||
|       for I in RORDERS.FIRST .. RORDERS.LAST
 | ||
|       loop
 | ||
|         /* Перед добавлением в запрос - обязательная проверка, чтобы избежать SQL-инъекций */
 | ||
|         if ((TCOL_DEFS_FIND(RCOL_DEFS => RDATA_GRID.RCOL_DEFS, SNAME => RORDERS(I).SNAME).SNAME is not null) and
 | ||
|            (RORDERS(I).SDIRECTION in (SORDER_DIRECTION_ASC, SORDER_DIRECTION_DESC))) then
 | ||
|           CSQL_ORDERS := CSQL_ORDERS || RORDERS(I).SNAME || ' ' || RORDERS(I).SDIRECTION;
 | ||
|           if (I < RORDERS.LAST) then
 | ||
|             CSQL_ORDERS := CSQL_ORDERS || ', ';
 | ||
|           end if;
 | ||
|         end if;
 | ||
|       end loop;
 | ||
|     end if;
 | ||
|     CSQL := replace(CSQL, SPATTERN, CSQL_ORDERS);
 | ||
|   end TORDERS_SET_QUERY;
 | ||
|   
 | ||
|   /* Проверка корректности наименования дополнительного атрибута задачи диаграммы Ганта */
 | ||
|   procedure TGANTT_TASK_ATTR_NAME_CHECK
 | ||
|   (
 | ||
|     SNAME                   in varchar2 -- Наименование
 | ||
|   )
 | ||
|   is
 | ||
|   begin
 | ||
|     if (SNAME in (SRESP_ATTR_ID,
 | ||
|                   SRESP_ATTR_RN,
 | ||
|                   SRESP_ATTR_NUMB,
 | ||
|                   SRESP_ATTR_CAPTION,
 | ||
|                   SRESP_ATTR_FULL_NAME,
 | ||
|                   SRESP_ATTR_START,
 | ||
|                   SRESP_ATTR_END,
 | ||
|                   SRESP_ATTR_TASK_PROGRESS,
 | ||
|                   SRESP_ATTR_TASK_BG_COLOR,
 | ||
|                   SRESP_ATTR_TASK_TEXT_COLOR,                  
 | ||
|                   SRESP_ATTR_TASK_RO,
 | ||
|                   SRESP_ATTR_TASK_RO_PRGRS,
 | ||
|                   SRESP_ATTR_TASK_RO_DATES,
 | ||
|                   SRESP_ATTR_TASK_DEPS)) then
 | ||
|       P_EXCEPTION(0,
 | ||
|                   'Наименование атрибута "%s" является зарезервированным.',
 | ||
|                   SNAME);
 | ||
|     end if;
 | ||
|   end TGANTT_TASK_ATTR_NAME_CHECK;
 | ||
|   
 | ||
|   /* Поиск атрибута задачи диаграммы Ганта по наименованию */
 | ||
|   function TGANTT_TASK_ATTR_FIND
 | ||
|   (
 | ||
|     RTASK_ATTRS             in TGANTT_TASK_ATTRS, -- Описание атрибутов задачи диаграммы Ганта
 | ||
|     SNAME                   in varchar2           -- Наименование
 | ||
|   ) return                  TGANTT_TASK_ATTR      -- Найденное описание (null - если не нашли)
 | ||
|   is
 | ||
|   begin
 | ||
|     /* Обходим атрибуты из описания */
 | ||
|     if ((RTASK_ATTRS is not null) and (RTASK_ATTRS.COUNT > 0)) then
 | ||
|       for I in RTASK_ATTRS.FIRST .. RTASK_ATTRS.LAST
 | ||
|       loop
 | ||
|         if (RTASK_ATTRS(I).SNAME = SNAME) then
 | ||
|           return RTASK_ATTRS(I);
 | ||
|         end if;
 | ||
|       end loop;
 | ||
|     end if;
 | ||
|     /* Ничего не нашли */
 | ||
|     return null;
 | ||
|   end TGANTT_TASK_ATTR_FIND;
 | ||
|   
 | ||
|   /* Поиск цвета задачи диаграммы Ганта по параметрам */
 | ||
|   function TGANTT_TASK_COLOR_FIND
 | ||
|   (
 | ||
|     RTASK_COLORS            in TGANTT_TASK_COLORS, -- Описание цветов задачи диаграммы Ганта
 | ||
|     SBG_COLOR               in varchar2 := null,   -- Цвет заливки задачи (формат - HTML-цвет, #RRGGBBAA)
 | ||
|     STEXT_COLOR             in varchar2 := null    -- Цвет текста заголовка задачи (формат - HTML-цвет, #RRGGBBAA)
 | ||
|   ) return                  TGANTT_TASK_COLOR      -- Найденное описание цвета (null - если не нашли)
 | ||
|   is
 | ||
|   begin
 | ||
|     /* Обходим цвета из описания */
 | ||
|     if ((RTASK_COLORS is not null) and (RTASK_COLORS.COUNT > 0)) then
 | ||
|       for I in RTASK_COLORS.FIRST .. RTASK_COLORS.LAST
 | ||
|       loop
 | ||
|         if ((CMP_VC2(V1 => RTASK_COLORS(I).SBG_COLOR, V2 => SBG_COLOR) = 1) and
 | ||
|            (CMP_VC2(V1 => RTASK_COLORS(I).STEXT_COLOR, V2 => STEXT_COLOR) = 1)) then
 | ||
|           return RTASK_COLORS(I);
 | ||
|         end if;
 | ||
|       end loop;
 | ||
|     end if;
 | ||
|     /* Ничего не нашли */
 | ||
|     return null;
 | ||
|   end TGANTT_TASK_COLOR_FIND;
 | ||
|   
 | ||
|   /* Формирование задачи для диаграммы Ганта */
 | ||
|   function TGANTT_TASK_MAKE
 | ||
|   (
 | ||
|     NRN                     in number,           -- Рег. номер
 | ||
|     SNUMB                   in varchar2,         -- Номер
 | ||
|     SCAPTION                in varchar2,         -- Заголовок
 | ||
|     SNAME                   in varchar2,         -- Наименование
 | ||
|     DSTART                  in date,             -- Дата начала
 | ||
|     DEND                    in date,             -- Дата окончания
 | ||
|     NPROGRESS               in number := null,   -- Прогресс (% готовности) задачи (null - не определен)
 | ||
|     SBG_COLOR               in varchar2 := null, -- Цвет заливки задачи (null - использовать цвет по умолчанию из стилей, формат - HTML-цвет, #RRGGBBAA)
 | ||
|     STEXT_COLOR             in varchar2 := null, -- Цвет текста заголовка задачи (null - использовать цвет по умолчанию из стилей, формат - HTML-цвет, #RRGGBBAA)
 | ||
|     BREAD_ONLY              in boolean := null,  -- Сроки и прогресс задачи только для чтения (null - как указано в описании диаграммы)
 | ||
|     BREAD_ONLY_DATES        in boolean := null,  -- Сроки задачи только для чтения (null - как указано в описании диаграммы)
 | ||
|     BREAD_ONLY_PROGRESS     in boolean := null   -- Прогресс задачи только для чтения (null - как указано в описании диаграммы)
 | ||
|   ) return                  TGANTT_TASK          -- Результат работы
 | ||
|   is
 | ||
|     RRES                    TGANTT_TASK;         -- Буфер для результата
 | ||
|   begin
 | ||
|     /* Проверим параметры */
 | ||
|     if ((NRN is null) or (SNUMB is null) or (SCAPTION is null) or (SNAME is null) or (DSTART is null) or (DEND is null)) then
 | ||
|       P_EXCEPTION(0,
 | ||
|                   'Регистрационный номер, номер, заголовок, наименование, даты начала и окончания являются обязательными при создании задачи для диаграммы Ганта.');
 | ||
|     end if;
 | ||
|     if ((NPROGRESS is not null) and (not (NPROGRESS between 0 and 100))) then
 | ||
|       P_EXCEPTION(0, 'Прогресс задачи должен быть значением от 0 до 100');
 | ||
|     end if;
 | ||
|     /* Формируем объект */
 | ||
|     RRES.NRN                 := NRN;
 | ||
|     RRES.SNUMB               := SNUMB;
 | ||
|     RRES.SCAPTION            := SCAPTION;
 | ||
|     RRES.SNAME               := SNAME;
 | ||
|     RRES.DSTART              := DSTART;
 | ||
|     RRES.DEND                := DEND;
 | ||
|     RRES.NPROGRESS           := NPROGRESS;
 | ||
|     RRES.SBG_COLOR           := SBG_COLOR;
 | ||
|     RRES.STEXT_COLOR         := STEXT_COLOR;
 | ||
|     RRES.BREAD_ONLY          := BREAD_ONLY;
 | ||
|     RRES.BREAD_ONLY_DATES    := BREAD_ONLY_DATES;
 | ||
|     RRES.BREAD_ONLY_PROGRESS := BREAD_ONLY_PROGRESS;
 | ||
|     RRES.RATTR_VALS          := TGANTT_TASK_ATTR_VALS();
 | ||
|     RRES.RDEPENDENCIES       := TGANTT_TASK_DEPENDENCIES();
 | ||
|     /* Возвращаем результат */
 | ||
|     return RRES;
 | ||
|   end TGANTT_TASK_MAKE;
 | ||
|   
 | ||
|   /* Добавление значения атрибута к задаче диаграммы Ганта */
 | ||
|   procedure TGANTT_TASK_ADD_ATTR_VAL
 | ||
|   (
 | ||
|     RGANTT                  in TGANTT,                 -- Описание диаграммы
 | ||
|     RTASK                   in out nocopy TGANTT_TASK, -- Описание задачи
 | ||
|     SNAME                   in varchar2,               -- Наименование
 | ||
|     SVALUE                  in varchar2,               -- Значение
 | ||
|     BCLEAR                  in boolean := false        -- Флаг очистки коллекции значений атрибутов (false - не очищать, true - очистить коллекцию перед добавлением)
 | ||
|   )
 | ||
|   is
 | ||
|   begin
 | ||
|     /* Проверим наименование */
 | ||
|     TGANTT_TASK_ATTR_NAME_CHECK(SNAME => SNAME);
 | ||
|     /* Проверим, что такой атрибут зарегистрирован */
 | ||
|     if (TGANTT_TASK_ATTR_FIND(RTASK_ATTRS => RGANTT.RTASK_ATTRS, SNAME => SNAME).SNAME is null) then
 | ||
|       P_EXCEPTION(0,
 | ||
|                   'Атрибут "%s" задачи диаграммы Ганта не зарегистрирован.',
 | ||
|                   SNAME);
 | ||
|     end if;
 | ||
|     /* Инициализируем коллекцию если необходимо */
 | ||
|     if ((RTASK.RATTR_VALS is null) or (BCLEAR)) then
 | ||
|       RTASK.RATTR_VALS := TGANTT_TASK_ATTR_VALS();
 | ||
|     end if;
 | ||
|     /* Добавляем элемент */
 | ||
|     RTASK.RATTR_VALS.EXTEND();
 | ||
|     RTASK.RATTR_VALS(RTASK.RATTR_VALS.LAST).SNAME := SNAME;
 | ||
|     RTASK.RATTR_VALS(RTASK.RATTR_VALS.LAST).SVALUE := SVALUE;
 | ||
|   end TGANTT_TASK_ADD_ATTR_VAL;
 | ||
|   
 | ||
|   /* Добавление предшествующей задачи к задаче диаграммы Ганта */
 | ||
|   procedure TGANTT_TASK_ADD_DEPENDENCY
 | ||
|   (
 | ||
|     RTASK                   in out nocopy TGANTT_TASK, -- Описание задачи
 | ||
|     NDEPENDENCY             in number,                 -- Рег. номер предшествующей задачи
 | ||
|     BCLEAR                  in boolean := false        -- Флаг очистки коллекции предшествущих задач (false - не очищать, true - очистить коллекцию перед добавлением)
 | ||
|   )
 | ||
|   is
 | ||
|   begin
 | ||
|     /* Инициализируем коллекцию если необходимо */
 | ||
|     if ((RTASK.RDEPENDENCIES is null) or (BCLEAR)) then
 | ||
|       RTASK.RDEPENDENCIES := TGANTT_TASK_DEPENDENCIES();
 | ||
|     end if;
 | ||
|     /* Добавляем элемент */
 | ||
|     RTASK.RDEPENDENCIES.EXTEND();
 | ||
|     RTASK.RDEPENDENCIES(RTASK.RDEPENDENCIES.LAST) := NDEPENDENCY;
 | ||
|   end TGANTT_TASK_ADD_DEPENDENCY;
 | ||
|   
 | ||
|   /* Сериализация описания задач диаграммы Ганта */
 | ||
|   procedure TGANTT_TASKS_TO_XML
 | ||
|   (
 | ||
|     RTASKS                  in TGANTT_TASKS   -- Коллекция задач диаграммы Ганта
 | ||
|   )
 | ||
|   is
 | ||
|     SDEPS                   PKG_STD.TLSTRING; -- Буфер для списка зависимых
 | ||
|   begin
 | ||
|     /* Обходим задачи из коллекции */
 | ||
|     if ((RTASKS is not null) and (RTASKS.COUNT > 0)) then
 | ||
|       for I in RTASKS.FIRST .. RTASKS.LAST
 | ||
|       loop
 | ||
|         /* Открываем строку */
 | ||
|         PKG_XFAST.DOWN_NODE(SNAME => SRESP_TAG_XGANTT_TASKS);
 | ||
|         /* Статические тарибуты */
 | ||
|         PKG_XFAST.ATTR(SNAME => SRESP_ATTR_ID, SVALUE => 'taskId' || RTASKS(I).NRN);
 | ||
|         PKG_XFAST.ATTR(SNAME => SRESP_ATTR_RN, NVALUE => RTASKS(I).NRN);
 | ||
|         PKG_XFAST.ATTR(SNAME => SRESP_ATTR_NUMB, SVALUE => RTASKS(I).SNUMB);
 | ||
|         PKG_XFAST.ATTR(SNAME => SRESP_ATTR_NAME, SVALUE => RTASKS(I).SCAPTION);
 | ||
|         PKG_XFAST.ATTR(SNAME => SRESP_ATTR_FULL_NAME, SVALUE => RTASKS(I).SNAME);
 | ||
|         PKG_XFAST.ATTR(SNAME => SRESP_ATTR_START, DVALUE => RTASKS(I).DSTART);
 | ||
|         PKG_XFAST.ATTR(SNAME => SRESP_ATTR_END, DVALUE => RTASKS(I).DEND);
 | ||
|         if (RTASKS(I).NPROGRESS is not null) then
 | ||
|           PKG_XFAST.ATTR(SNAME => SRESP_ATTR_TASK_PROGRESS, NVALUE => RTASKS(I).NPROGRESS);
 | ||
|         end if;
 | ||
|         if (RTASKS(I).SBG_COLOR is not null) then
 | ||
|           PKG_XFAST.ATTR(SNAME => SRESP_ATTR_TASK_BG_COLOR, SVALUE => RTASKS(I).SBG_COLOR);
 | ||
|         end if;
 | ||
|         if (RTASKS(I).STEXT_COLOR is not null) then
 | ||
|           PKG_XFAST.ATTR(SNAME => SRESP_ATTR_TASK_TEXT_COLOR, SVALUE => RTASKS(I).STEXT_COLOR);
 | ||
|         end if;
 | ||
|         if (RTASKS(I).BREAD_ONLY is not null) then
 | ||
|           PKG_XFAST.ATTR(SNAME => SRESP_ATTR_TASK_RO, BVALUE => RTASKS(I).BREAD_ONLY);
 | ||
|         end if;
 | ||
|         if (RTASKS(I).BREAD_ONLY_DATES is not null) then
 | ||
|           PKG_XFAST.ATTR(SNAME => SRESP_ATTR_TASK_RO_DATES, BVALUE => RTASKS(I).BREAD_ONLY_DATES);
 | ||
|         end if;
 | ||
|         if (RTASKS(I).BREAD_ONLY_PROGRESS is not null) then
 | ||
|           PKG_XFAST.ATTR(SNAME => SRESP_ATTR_TASK_RO_PRGRS, BVALUE => RTASKS(I).BREAD_ONLY_PROGRESS);
 | ||
|         end if;
 | ||
|         if ((RTASKS(I).RDEPENDENCIES is not null) and (RTASKS(I).RDEPENDENCIES.COUNT > 0)) then
 | ||
|           SDEPS := null;
 | ||
|           for J in RTASKS(I).RDEPENDENCIES.FIRST .. RTASKS(I).RDEPENDENCIES.LAST
 | ||
|           loop
 | ||
|             SDEPS := COALESCE(SDEPS, '') || 'taskId' || TO_CHAR(RTASKS(I).RDEPENDENCIES(J)) || ',';
 | ||
|           end loop;
 | ||
|           PKG_XFAST.ATTR(SNAME => SRESP_ATTR_TASK_DEPS, SVALUE => RTRIM(SDEPS, ','));
 | ||
|         end if;
 | ||
|         /* Динамические атрибуты */
 | ||
|         if ((RTASKS(I).RATTR_VALS is not null) and (RTASKS(I).RATTR_VALS.COUNT > 0)) then
 | ||
|           for J in RTASKS(I).RATTR_VALS.FIRST .. RTASKS(I).RATTR_VALS.LAST
 | ||
|           loop
 | ||
|             PKG_XFAST.ATTR(SNAME => RTASKS(I).RATTR_VALS(J).SNAME, SVALUE => RTASKS(I).RATTR_VALS(J).SVALUE);
 | ||
|           end loop;
 | ||
|         end if;
 | ||
|         /* Закрываем задачу */
 | ||
|         PKG_XFAST.UP();
 | ||
|       end loop;
 | ||
|     end if;
 | ||
|   end TGANTT_TASKS_TO_XML;
 | ||
| 
 | ||
|   /* Формирование диаграммы Ганта */
 | ||
|   function TGANTT_MAKE
 | ||
|   (
 | ||
|     STITLE                  in varchar2 := null,           -- Заголовок (null - не отображать)
 | ||
|     NZOOM                   in number := NGANTT_ZOOM_WEEK, -- Текущий масштаб (см. константы NGANTT_ZOOM_*)
 | ||
|     BZOOM_BAR               in boolean := true,            -- Обображать панель масштабирования
 | ||
|     BREAD_ONLY              in boolean := false,           -- Сроки и прогресс задач только для чтения
 | ||
|     BREAD_ONLY_DATES        in boolean := false,           -- Сроки задач только для чтения
 | ||
|     BREAD_ONLY_PROGRESS     in boolean := false            -- Прогресс задач только для чтения
 | ||
|   ) return                  TGANTT                         -- Результат работы
 | ||
|   is
 | ||
|     RRES                    TGANTT;                        -- Буфер для результата
 | ||
|   begin
 | ||
|     /* Формируем объект */
 | ||
|     RRES.STITLE              := STITLE;
 | ||
|     RRES.NZOOM               := COALESCE(NZOOM, NGANTT_ZOOM_WEEK);
 | ||
|     RRES.BZOOM_BAR           := COALESCE(BZOOM_BAR, true);
 | ||
|     RRES.BREAD_ONLY          := COALESCE(BREAD_ONLY, false);
 | ||
|     RRES.BREAD_ONLY_DATES    := COALESCE(BREAD_ONLY_DATES, false);
 | ||
|     RRES.BREAD_ONLY_PROGRESS := COALESCE(BREAD_ONLY_PROGRESS, false);
 | ||
|     RRES.RTASK_ATTRS         := TGANTT_TASK_ATTRS();
 | ||
|     RRES.RTASK_COLORS        := TGANTT_TASK_COLORS();
 | ||
|     RRES.RTASKS              := TGANTT_TASKS();
 | ||
|     /* Возвращаем результат */
 | ||
|     return RRES;
 | ||
|   end TGANTT_MAKE;
 | ||
|   
 | ||
|   /* Добавление описания атрибута карточки задачи диаграммы Ганта */
 | ||
|   procedure TGANTT_ADD_TASK_ATTR
 | ||
|   (
 | ||
|     RGANTT                  in out nocopy TGANTT, -- Описание диаграммы Ганта
 | ||
|     SNAME                   in varchar2,          -- Наименование
 | ||
|     SCAPTION                in varchar2,          -- Заголовок
 | ||
|     BCLEAR                  in boolean := false   -- Флаг очистки коллекции атрибутов (false - не очищать, true - очистить коллекцию перед добавлением)
 | ||
|   )
 | ||
|   is
 | ||
|   begin
 | ||
|     /* Проверим наименование */
 | ||
|     TGANTT_TASK_ATTR_NAME_CHECK(SNAME => SNAME);
 | ||
|     /* Проверим, что такого ещё нет */
 | ||
|     if (TGANTT_TASK_ATTR_FIND(RTASK_ATTRS => RGANTT.RTASK_ATTRS, SNAME => SNAME).SNAME is not null) then
 | ||
|       P_EXCEPTION(0,
 | ||
|                   'Атрибут "%s" задачи диаграммы Ганта уже зарегистрирован.',
 | ||
|                   SNAME);
 | ||
|     end if;
 | ||
|     /* Инициализируем коллекцию если необходимо */
 | ||
|     if ((RGANTT.RTASK_ATTRS is null) or (BCLEAR)) then
 | ||
|       RGANTT.RTASK_ATTRS := TGANTT_TASK_ATTRS();
 | ||
|     end if;
 | ||
|     /* Добавляем элемент */
 | ||
|     RGANTT.RTASK_ATTRS.EXTEND();
 | ||
|     RGANTT.RTASK_ATTRS(RGANTT.RTASK_ATTRS.LAST).SNAME := SNAME;
 | ||
|     RGANTT.RTASK_ATTRS(RGANTT.RTASK_ATTRS.LAST).SCAPTION := SCAPTION;
 | ||
|   end TGANTT_ADD_TASK_ATTR;
 | ||
| 
 | ||
|   /* Добавление описания цвета задачи диаграммы Ганта */
 | ||
|   procedure TGANTT_ADD_TASK_COLOR
 | ||
|   (
 | ||
|     RGANTT                  in out nocopy TGANTT, -- Описание диаграммы Ганта
 | ||
|     SBG_COLOR               in varchar2 := null,  -- Цвет заливки задачи (формат - HTML-цвет, #RRGGBBAA)
 | ||
|     STEXT_COLOR             in varchar2 := null,  -- Цвет текста заголовка задачи (формат - HTML-цвет, #RRGGBBAA)
 | ||
|     SDESC                   in varchar2,          -- Описание
 | ||
|     BCLEAR                  in boolean := false   -- Флаг очистки коллекции цветов (false - не очищать, true - очистить коллекцию перед добавлением)
 | ||
|   )
 | ||
|   is
 | ||
|   begin
 | ||
|     /* Проверим параметры */
 | ||
|     if ((SBG_COLOR is null) and (STEXT_COLOR is null)) then
 | ||
|       P_EXCEPTION(0,
 | ||
|                   'Должен быть указан цвет заливки или цвет текста задачи.');
 | ||
|     end if;
 | ||
|     if (SDESC is null) then
 | ||
|       P_EXCEPTION(0, 'Описание цвета должно быть задано.');
 | ||
|     end if;
 | ||
|     /* Проверим, что такого ещё нет */
 | ||
|     if (TGANTT_TASK_COLOR_FIND(RTASK_COLORS => RGANTT.RTASK_COLORS, SBG_COLOR => SBG_COLOR, STEXT_COLOR => STEXT_COLOR)
 | ||
|        .SDESC is not null) then
 | ||
|       P_EXCEPTION(0,
 | ||
|                   'Такое описание цвета для задачи диаграммы Ганта уже зарегистрировано.');
 | ||
|     end if;
 | ||
|     /* Инициализируем коллекцию если необходимо */
 | ||
|     if ((RGANTT.RTASK_COLORS is null) or (BCLEAR)) then
 | ||
|       RGANTT.RTASK_COLORS := TGANTT_TASK_COLORS();
 | ||
|     end if;
 | ||
|     /* Добавляем элемент */
 | ||
|     RGANTT.RTASK_COLORS.EXTEND();
 | ||
|     RGANTT.RTASK_COLORS(RGANTT.RTASK_COLORS.LAST).SBG_COLOR := SBG_COLOR;
 | ||
|     RGANTT.RTASK_COLORS(RGANTT.RTASK_COLORS.LAST).STEXT_COLOR := STEXT_COLOR;
 | ||
|     RGANTT.RTASK_COLORS(RGANTT.RTASK_COLORS.LAST).SDESC := SDESC;
 | ||
|   end TGANTT_ADD_TASK_COLOR;
 | ||
| 
 | ||
|   /* Добавление задачи к диаграмме Ганта */
 | ||
|   procedure TGANTT_ADD_TASK
 | ||
|   (
 | ||
|     RGANTT                  in out nocopy TGANTT, -- Описание диаграммы Ганта
 | ||
|     RTASK                   in TGANTT_TASK,       -- Задача
 | ||
|     BCLEAR                  in boolean := false   -- Флаг очистки коллекции задач диаграммы (false - не очищать, true - очистить коллекцию перед добавлением)
 | ||
|   )
 | ||
|   is
 | ||
|   begin
 | ||
|     /* Инициализируем коллекцию если необходимо */
 | ||
|     if ((RGANTT.RTASKS is null) or (BCLEAR)) then
 | ||
|       RGANTT.RTASKS := TGANTT_TASKS();
 | ||
|     end if;
 | ||
|     /* Добавляем элемент */
 | ||
|     RGANTT.RTASKS.EXTEND();
 | ||
|     RGANTT.RTASKS(RGANTT.RTASKS.LAST) := RTASK;
 | ||
|   end TGANTT_ADD_TASK;
 | ||
|   
 | ||
|   /* Сериализация описания заголовка диаграммы Ганта */
 | ||
|   procedure TGANTT_DEF_TO_XML
 | ||
|   (
 | ||
|     RGANTT                  in TGANTT   -- Описание диаграммы Ганта
 | ||
|   )
 | ||
|   is    
 | ||
|   begin
 | ||
|     /* Открываем описание заголовка */
 | ||
|     PKG_XFAST.DOWN_NODE(SNAME => SRESP_TAG_XGANTT_DEF);
 | ||
|     /* Cтатические атрибуты заголовка */
 | ||
|     PKG_XFAST.ATTR(SNAME => SRESP_ATTR_TITLE, SVALUE => RGANTT.STITLE);
 | ||
|     PKG_XFAST.ATTR(SNAME => SRESP_ATTR_ZOOM, NVALUE => RGANTT.NZOOM);
 | ||
|     PKG_XFAST.ATTR(SNAME => SRESP_ATTR_GANTT_ZOOM_BAR, BVALUE => RGANTT.BZOOM_BAR);
 | ||
|     PKG_XFAST.ATTR(SNAME => SRESP_ATTR_TASK_RO, BVALUE => RGANTT.BREAD_ONLY);
 | ||
|     PKG_XFAST.ATTR(SNAME => SRESP_ATTR_TASK_RO_DATES, BVALUE => RGANTT.BREAD_ONLY_DATES);
 | ||
|     PKG_XFAST.ATTR(SNAME => SRESP_ATTR_TASK_RO_PRGRS, BVALUE => RGANTT.BREAD_ONLY_PROGRESS);
 | ||
|     /* Если есть динамические атрибуты */
 | ||
|     if ((RGANTT.RTASK_ATTRS is not null) and (RGANTT.RTASK_ATTRS.COUNT > 0)) then
 | ||
|       /* Обходим динамические атрибуты задачи */
 | ||
|       for I in RGANTT.RTASK_ATTRS.FIRST .. RGANTT.RTASK_ATTRS.LAST
 | ||
|       loop
 | ||
|         /* Открываем динамический атрибут задачи */
 | ||
|         PKG_XFAST.DOWN_NODE(SNAME => SRESP_ATTR_TASK_ATTRIBUTES);
 | ||
|         /* Наполняем его атрибутами */
 | ||
|         PKG_XFAST.ATTR(SNAME => SRESP_ATTR_NAME, SVALUE => RGANTT.RTASK_ATTRS(I).SNAME);
 | ||
|         PKG_XFAST.ATTR(SNAME => SRESP_ATTR_CAPTION, SVALUE => RGANTT.RTASK_ATTRS(I).SCAPTION);
 | ||
|         /* Закрываем динамический атрибут задачи */
 | ||
|         PKG_XFAST.UP();
 | ||
|       end loop;
 | ||
|     end if;
 | ||
|     /* Если есть описание цветов */
 | ||
|     if ((RGANTT.RTASK_COLORS is not null) and (RGANTT.RTASK_COLORS.COUNT > 0)) then
 | ||
|       /* Обходим описание цветов задачи */
 | ||
|       for I in RGANTT.RTASK_COLORS.FIRST .. RGANTT.RTASK_COLORS.LAST
 | ||
|       loop
 | ||
|         /* Открываем описание цвета задачи */
 | ||
|         PKG_XFAST.DOWN_NODE(SNAME => SRESP_ATTR_TASK_COLORS);
 | ||
|         /* Наполняем его атрибутами */
 | ||
|         if (RGANTT.RTASK_COLORS(I).SBG_COLOR is not null) then
 | ||
|           PKG_XFAST.ATTR(SNAME => SRESP_ATTR_TASK_BG_COLOR, SVALUE => RGANTT.RTASK_COLORS(I).SBG_COLOR);
 | ||
|         end if;
 | ||
|         if (RGANTT.RTASK_COLORS(I).STEXT_COLOR is not null) then
 | ||
|           PKG_XFAST.ATTR(SNAME => SRESP_ATTR_TASK_TEXT_COLOR, SVALUE => RGANTT.RTASK_COLORS(I).STEXT_COLOR);
 | ||
|         end if;
 | ||
|         PKG_XFAST.ATTR(SNAME => SRESP_ATTR_DESC, SVALUE => RGANTT.RTASK_COLORS(I).SDESC);
 | ||
|         /* Закрываем описание цвета задачи */
 | ||
|         PKG_XFAST.UP();
 | ||
|       end loop;
 | ||
|     end if;
 | ||
|     /* Закрываем описание заголовка */
 | ||
|     PKG_XFAST.UP();
 | ||
|   end TGANTT_DEF_TO_XML;
 | ||
|   
 | ||
|   /* Сериализация диаграммы Ганта */
 | ||
|   function TGANTT_TO_XML
 | ||
|   (
 | ||
|     RGANTT                  in TGANTT,     -- Описание диаграммы Ганта
 | ||
|     NINCLUDE_DEF            in number := 1 -- Включить описание заголовка (0 - нет, 1 - да)
 | ||
|   ) return                  clob           -- XML-описание
 | ||
|   is
 | ||
|     CRES                    clob;          -- Буфер для результата
 | ||
|   begin
 | ||
|     /* Начинаем формирование XML */
 | ||
|     PKG_XFAST.PROLOGUE(ITYPE => PKG_XFAST.CONTENT_);
 | ||
|     /* Открываем корень */
 | ||
|     PKG_XFAST.DOWN_NODE(SNAME => SRESP_TAG_XDATA);
 | ||
|     /* Если необходимо включить описание колонок */
 | ||
|     if (NINCLUDE_DEF = 1) then
 | ||
|       TGANTT_DEF_TO_XML(RGANTT => RGANTT);
 | ||
|     end if;
 | ||
|     /* Формируем описание задач */
 | ||
|     TGANTT_TASKS_TO_XML(RTASKS => RGANTT.RTASKS);
 | ||
|     /* Закрываем корень */
 | ||
|     PKG_XFAST.UP();
 | ||
|     /* Сериализуем */
 | ||
|     CRES := PKG_XFAST.SERIALIZE_TO_CLOB();
 | ||
|     /* Завершаем формирование XML */
 | ||
|     PKG_XFAST.EPILOGUE();
 | ||
|     /* Возвращаем полученное */
 | ||
|     return CRES;
 | ||
|   exception
 | ||
|     when others then
 | ||
|       /* Завершаем формирование XML */
 | ||
|       PKG_XFAST.EPILOGUE();
 | ||
|       /* Вернем ошибку */
 | ||
|       PKG_STATE.DIAGNOSTICS_STACKED();
 | ||
|       P_EXCEPTION(0, PKG_STATE.SQL_ERRM());
 | ||
|   end TGANTT_TO_XML;
 | ||
|   
 | ||
|   /* Проверка корректности наименования дополнительного атрибута элемента данных графика */
 | ||
|   procedure TCHART_DATASET_ITEM_ATTR_NM_CH
 | ||
|   (
 | ||
|     SNAME                   in varchar2 -- Наименование
 | ||
|   )
 | ||
|   is
 | ||
|   begin
 | ||
|     if (SNAME in (SRESP_ATTR_CHART_DS_I_VAL)) then
 | ||
|       P_EXCEPTION(0,
 | ||
|                   'Наименование атрибута "%s" является зарезервированным.',
 | ||
|                   SNAME);
 | ||
|     end if;
 | ||
|   end TCHART_DATASET_ITEM_ATTR_NM_CH;
 | ||
|   
 | ||
|   /* Сериализация меток графика */
 | ||
|   procedure TCHART_LABELS_TO_XML
 | ||
|   (
 | ||
|     RLABELS                 in TCHART_LABELS -- Описание диаграммы Ганта
 | ||
|   )
 | ||
|   is    
 | ||
|   begin
 | ||
|     /* Если есть метки */
 | ||
|     if ((RLABELS is not null) and (RLABELS.COUNT > 0)) then
 | ||
|       /* Обходим метки */
 | ||
|       for I in RLABELS.FIRST .. RLABELS.LAST
 | ||
|       loop
 | ||
|         /* Открываем описание метки */
 | ||
|         PKG_XFAST.DOWN_NODE(SNAME => SRESP_ATTR_CHART_LABELS);
 | ||
|         /* Добавляем значение */
 | ||
|         PKG_XFAST.VALUE(SVALUE => RLABELS(I));
 | ||
|         /* Закрываем описание метки */
 | ||
|         PKG_XFAST.UP();
 | ||
|       end loop;
 | ||
|     end if;
 | ||
|   end TCHART_LABELS_TO_XML;
 | ||
|   
 | ||
|   /* Добавление дополнительного атрибута элемента данных графика */
 | ||
|   procedure TCHART_DATASET_ITM_ATTR_VL_ADD
 | ||
|   (
 | ||
|     RATTR_VALS              in out nocopy TCHART_DATASET_ITEM_ATTR_VALS, -- Коллекция дополнительных атрибутов элемента данных графика
 | ||
|     SNAME                   PKG_STD.TSTRING,                             -- Наименование
 | ||
|     SVALUE                  PKG_STD.TSTRING,                             -- Значение
 | ||
|     BCLEAR                  in boolean := false                          -- Флаг очистки коллекции дополнительных атрибутов элемента данных (false - не очищать, true - очистить коллекцию перед добавлением)
 | ||
|   )
 | ||
|   is
 | ||
|   begin
 | ||
|     /* Проверим корректность наименования */
 | ||
|     TCHART_DATASET_ITEM_ATTR_NM_CH(SNAME => SNAME);
 | ||
|     /* Инициализируем коллекцию если необходимо */
 | ||
|     if ((RATTR_VALS is null) or (BCLEAR)) then
 | ||
|       RATTR_VALS := TCHART_DATASET_ITEM_ATTR_VALS();
 | ||
|     end if;
 | ||
|     /* Добавляем элемент */
 | ||
|     RATTR_VALS.EXTEND();
 | ||
|     RATTR_VALS(RATTR_VALS.LAST).SNAME := SNAME;
 | ||
|     RATTR_VALS(RATTR_VALS.LAST).SVALUE := SVALUE;
 | ||
|   end TCHART_DATASET_ITM_ATTR_VL_ADD;
 | ||
|   
 | ||
|   /* Формирование набора данных графика */
 | ||
|   function TCHART_DATASET_MAKE
 | ||
|   (
 | ||
|     SCAPTION                in varchar2,         -- Заголовок
 | ||
|     SBORDER_COLOR           in varchar2 := null, -- Цвет границы элемента данных на графике (null - использовать цвет по умолчанию из стилей, формат - HTML-цвет, #RRGGBBAA)
 | ||
|     SBG_COLOR               in varchar2 := null  -- Цвет заливки элемента данных на графике (null - использовать цвет по умолчанию из стилей, формат - HTML-цвет, #RRGGBBAA)
 | ||
|   ) return                  TCHART_DATASET       -- Результат работы
 | ||
|   is
 | ||
|     RRES                    TCHART_DATASET;      -- Буфер для результата
 | ||
|   begin
 | ||
|     /* Формируем объект */
 | ||
|     RRES.SCAPTION      := SCAPTION;
 | ||
|     RRES.SBORDER_COLOR := SBORDER_COLOR;
 | ||
|     RRES.SBG_COLOR     := SBG_COLOR;
 | ||
|     RRES.RITEMS        := TCHART_DATASET_ITEMS();
 | ||
|     /* Возвращаем результат */
 | ||
|     return RRES;
 | ||
|   end TCHART_DATASET_MAKE;
 | ||
|   
 | ||
|   /* Добавление элемента в набор данных графика */
 | ||
|   procedure TCHART_DATASET_ADD_ITEM
 | ||
|   (
 | ||
|     RDATASET                in out nocopy TCHART_DATASET,             -- Описание набора данных графика
 | ||
|     NVALUE                  in number,                                -- Значение элемента данных, отображаемое на графике
 | ||
|     RATTR_VALS              in TCHART_DATASET_ITEM_ATTR_VALS := null, -- Значения дополнительных атрбутов (null - дополнительные атрибуты не определены)
 | ||
|     BCLEAR                  in boolean := false                       -- Флаг очистки коллекции элементов набора данных (false - не очищать, true - очистить коллекцию перед добавлением)
 | ||
|   )
 | ||
|   is
 | ||
|   begin
 | ||
|     /* Инициализируем коллекцию если необходимо */
 | ||
|     if ((RDATASET.RITEMS is null) or (BCLEAR)) then
 | ||
|       RDATASET.RITEMS := TCHART_DATASET_ITEMS();
 | ||
|     end if;
 | ||
|     /* Добавляем элемент */
 | ||
|     RDATASET.RITEMS.EXTEND();
 | ||
|     RDATASET.RITEMS(RDATASET.RITEMS.LAST).NVALUE := NVALUE;
 | ||
|     RDATASET.RITEMS(RDATASET.RITEMS.LAST).RATTR_VALS := RATTR_VALS;
 | ||
|   end TCHART_DATASET_ADD_ITEM;
 | ||
|   
 | ||
|   /* Сериализация коллекции наборов данных графика */
 | ||
|   procedure TCHART_DATASETS_TO_XML
 | ||
|   (
 | ||
|     RDATASETS               in TCHART_DATASETS -- Наборы данных графика
 | ||
|   )
 | ||
|   is
 | ||
|   begin
 | ||
|     /* Если есть наборы данных */
 | ||
|     if ((RDATASETS is not null) and (RDATASETS.COUNT > 0)) then
 | ||
|       /* Обходим наборы данных */
 | ||
|       for I in RDATASETS.FIRST .. RDATASETS.LAST
 | ||
|       loop
 | ||
|         /* Открываем набор данных */
 | ||
|         PKG_XFAST.DOWN_NODE(SNAME => SRESP_ATTR_CHART_DATASETS);
 | ||
|         /* Добавляем статические атрибуты */
 | ||
|         PKG_XFAST.ATTR(SNAME => SRESP_ATTR_CHART_DS_LABEL, SVALUE => RDATASETS(I).SCAPTION);
 | ||
|         if (RDATASETS(I).SBORDER_COLOR is not null) then
 | ||
|           PKG_XFAST.ATTR(SNAME => SRESP_ATTR_CHART_DS_BR_CLR, SVALUE => RDATASETS(I).SBORDER_COLOR);
 | ||
|         end if;
 | ||
|         if (RDATASETS(I).SBG_COLOR is not null) then
 | ||
|           PKG_XFAST.ATTR(SNAME => SRESP_ATTR_CHART_DS_BG_CLR, SVALUE => RDATASETS(I).SBG_COLOR);
 | ||
|         end if;
 | ||
|         /* Если в наборе данных есть элементы */
 | ||
|         if ((RDATASETS(I).RITEMS is not null) and (RDATASETS(I).RITEMS.COUNT > 0)) then
 | ||
|           /* Обходим элементы набора данных для формирования отображаемых значений */
 | ||
|           for J in RDATASETS(I).RITEMS.FIRST .. RDATASETS(I).RITEMS.LAST
 | ||
|           loop
 | ||
|             /* Открываем значение элемента набора данных */
 | ||
|             PKG_XFAST.DOWN_NODE(SNAME => SRESP_ATTR_CHART_DS_DATA);
 | ||
|             /* Формируем значение элемента */
 | ||
|             PKG_XFAST.VALUE(NVALUE => RDATASETS(I).RITEMS(J).NVALUE);
 | ||
|             /* Закрываем значение элемента набора данных */
 | ||
|             PKG_XFAST.UP();
 | ||
|           end loop;
 | ||
|           /* Обходим элементы набора данных для формирования из самих */
 | ||
|           for J in RDATASETS(I).RITEMS.FIRST .. RDATASETS(I).RITEMS.LAST
 | ||
|           loop
 | ||
|             /* Открываем элемент набора данных */
 | ||
|             PKG_XFAST.DOWN_NODE(SNAME => SRESP_ATTR_CHART_DS_ITEMS);
 | ||
|             /* Добавляем статические атрибуты */
 | ||
|             PKG_XFAST.ATTR(SNAME => SRESP_ATTR_CHART_DS_I_VAL, NVALUE => RDATASETS(I).RITEMS(J).NVALUE);
 | ||
|             /* Добавляем дополнительные атрибуты */
 | ||
|             if ((RDATASETS(I).RITEMS(J).RATTR_VALS is not null) and (RDATASETS(I).RITEMS(J).RATTR_VALS.COUNT > 0)) then
 | ||
|               for K in RDATASETS(I).RITEMS(J).RATTR_VALS.FIRST .. RDATASETS(I).RITEMS(J).RATTR_VALS.LAST
 | ||
|               loop
 | ||
|                 PKG_XFAST.ATTR(SNAME  => RDATASETS(I).RITEMS(J).RATTR_VALS(K).SNAME,
 | ||
|                                SVALUE => RDATASETS(I).RITEMS(J).RATTR_VALS(K).SVALUE);
 | ||
|               end loop;
 | ||
|             end if;
 | ||
|             /* Закрываем элемент набора данных */
 | ||
|             PKG_XFAST.UP();
 | ||
|           end loop;
 | ||
|         end if;
 | ||
|         /* Закрываем набор данных */
 | ||
|         PKG_XFAST.UP();
 | ||
|       end loop;
 | ||
|     end if;
 | ||
|   end TCHART_DATASETS_TO_XML;
 | ||
|   
 | ||
|   /* Формирование графика */
 | ||
|   function TCHART_MAKE
 | ||
|   (
 | ||
|     STYPE                   in varchar2,         -- Тип (см. константы SCHART_TYPE_*)
 | ||
|     STITLE                  in varchar2 := null, -- Заголовок (null - не отображать)
 | ||
|     SLGND_POS               in varchar2 := null  -- Расположение легенды (null - не отображать, см. константы SCHART_LGND_POS_*)
 | ||
|   ) return                  TCHART               -- Результат работы
 | ||
|   is
 | ||
|     RRES                    TCHART;              -- Буфер для результата
 | ||
|   begin
 | ||
|     /* Формируем объект */
 | ||
|     RRES.STYPE     := STYPE;
 | ||
|     RRES.STITLE    := STITLE;
 | ||
|     RRES.SLGND_POS := SLGND_POS;
 | ||
|     RRES.RLABELS   := TCHART_LABELS();
 | ||
|     RRES.RDATASETS := TCHART_DATASETS();
 | ||
|     /* Возвращаем результат */
 | ||
|     return RRES;
 | ||
|   end TCHART_MAKE;
 | ||
|   
 | ||
|   /* Добавление метки значения графика */
 | ||
|   procedure TCHART_ADD_LABEL
 | ||
|   (
 | ||
|     RCHART                  in out nocopy TCHART, -- Описание графика
 | ||
|     SLABEL                  in varchar2,          -- Метка значения
 | ||
|     BCLEAR                  in boolean := false   -- Флаг очистки коллекции меток (false - не очищать, true - очистить коллекцию перед добавлением)
 | ||
|   )
 | ||
|   is
 | ||
|   begin
 | ||
|     /* Инициализируем коллекцию если необходимо */
 | ||
|     if ((RCHART.RLABELS is null) or (BCLEAR)) then
 | ||
|       RCHART.RLABELS := TCHART_LABELS();
 | ||
|     end if;
 | ||
|     /* Добавляем элемент */
 | ||
|     RCHART.RLABELS.EXTEND();
 | ||
|     RCHART.RLABELS(RCHART.RLABELS.LAST) := SLABEL;
 | ||
|   end TCHART_ADD_LABEL;
 | ||
|   
 | ||
|   /* Добавление набора данных графика */
 | ||
|   procedure TCHART_ADD_DATASET
 | ||
|   (
 | ||
|     RCHART                  in out nocopy TCHART, -- Описание графика
 | ||
|     RDATASET                in TCHART_DATASET,    -- Набор данных
 | ||
|     BCLEAR                  in boolean := false   -- Флаг очистки коллекции наборов данных (false - не очищать, true - очистить коллекцию перед добавлением)
 | ||
|   )
 | ||
|   is
 | ||
|   begin
 | ||
|     /* Инициализируем коллекцию если необходимо */
 | ||
|     if ((RCHART.RDATASETS is null) or (BCLEAR)) then
 | ||
|       RCHART.RDATASETS := TCHART_DATASETS();
 | ||
|     end if;
 | ||
|     /* Добавляем элемент */
 | ||
|     RCHART.RDATASETS.EXTEND();
 | ||
|     RCHART.RDATASETS(RCHART.RDATASETS.LAST) := RDATASET;
 | ||
|   end TCHART_ADD_DATASET;
 | ||
|   
 | ||
|   /* Сериализация описания заголовка графика */
 | ||
|   procedure TCHART_DEF_TO_XML
 | ||
|   (
 | ||
|     RCHART                  in TCHART   -- Описание графика
 | ||
|   )
 | ||
|   is    
 | ||
|   begin
 | ||
|     /* Cтатические атрибуты заголовка */
 | ||
|     PKG_XFAST.ATTR(SNAME => SRESP_ATTR_TYPE, SVALUE => RCHART.STYPE);
 | ||
|     PKG_XFAST.ATTR(SNAME => SRESP_ATTR_TITLE, SVALUE => RCHART.STITLE);
 | ||
|     PKG_XFAST.ATTR(SNAME => SRESP_ATTR_CHART_LGND_POS, SVALUE => RCHART.SLGND_POS);
 | ||
|   end TCHART_DEF_TO_XML;
 | ||
|   
 | ||
|   /* Сериализация графика */
 | ||
|   function TCHART_TO_XML
 | ||
|   (
 | ||
|     RCHART                  in TCHART,     -- Описание графика
 | ||
|     NINCLUDE_DEF            in number := 1 -- Включить описание заголовка (0 - нет, 1 - да)
 | ||
|   ) return                  clob           -- XML-описание
 | ||
|   is
 | ||
|     CRES                    clob;          -- Буфер для результата
 | ||
|   begin
 | ||
|     /* Начинаем формирование XML */
 | ||
|     PKG_XFAST.PROLOGUE(ITYPE => PKG_XFAST.CONTENT_);
 | ||
|     /* Открываем корень */
 | ||
|     PKG_XFAST.DOWN_NODE(SNAME => SRESP_TAG_XDATA);
 | ||
|     /* Открываем график */
 | ||
|     PKG_XFAST.DOWN_NODE(SNAME => SRESP_TAG_XCHART);
 | ||
|     /* Если необходимо включить описание колонок */
 | ||
|     if (NINCLUDE_DEF = 1) then
 | ||
|       TCHART_DEF_TO_XML(RCHART => RCHART);
 | ||
|     end if;
 | ||
|     /* Формируем описание меток */
 | ||
|     TCHART_LABELS_TO_XML(RLABELS => RCHART.RLABELS);
 | ||
|     /* Формируем описание наборов данных */
 | ||
|     TCHART_DATASETS_TO_XML(RDATASETS => RCHART.RDATASETS);
 | ||
|     /* Закрываем график */
 | ||
|     PKG_XFAST.UP();
 | ||
|     /* Закрываем корень */
 | ||
|     PKG_XFAST.UP();
 | ||
|     /* Сериализуем */
 | ||
|     CRES := PKG_XFAST.SERIALIZE_TO_CLOB();
 | ||
|     /* Завершаем формирование XML */
 | ||
|     PKG_XFAST.EPILOGUE();
 | ||
|     /* Возвращаем полученное */
 | ||
|     return CRES;
 | ||
|   exception
 | ||
|     when others then
 | ||
|       /* Завершаем формирование XML */
 | ||
|       PKG_XFAST.EPILOGUE();
 | ||
|       /* Вернем ошибку */
 | ||
|       PKG_STATE.DIAGNOSTICS_STACKED();
 | ||
|       P_EXCEPTION(0, PKG_STATE.SQL_ERRM());
 | ||
|   end TCHART_TO_XML;
 | ||
|   
 | ||
| end PKG_P8PANELS_VISUAL;
 | ||
| /
 |