Рендеринг отчёта с разными параметрами

Обсуждение Stimulsoft Reports.NET
Леонид
Сообщения: 329
Зарегистрирован: 23 июл 2009, 09:53
Откуда: Moscow

Re: Рендеринг отчёта с разными параметрами

Сообщение Леонид »

Добрый день!

Итак, провели большое количество экспериментов. В результате понять, что является причиной такого поведения не удалось. Напомню, что проблемы есть только с переменными (объявленные в Dictionary), и именно, когда им присваиваются значения из полей DataSource.

В двух словах, у нас есть отчёт (они разные, Торг-12, Счёт-фактура и пр.), в нём есть переменная FacturaCaption1 типа String. Эту переменную инициализируем в событии BeforePrint, её значения выводятся, но не на каждой странице корректно, т.е., на первой странице выводит номер накладной и её дата, на второй нет, на третей нормально, и так рандомно, - так и не понял почему.
Сам отчёт максимально упростил до трёх полей, и вот какую корелляцию обнаружил, когда данные выбираются из таблицы DUAL адаптера StiOracleSource, то всё выбирается корректно, а когда меняю select на наш обычный, то происходит этот самый "рандомный" баг. Возможно, это не баг, а мы чего-то не знаем, но думаю, что причина всё-таки именно в адаптере данных Oracle в самом отчёте.

К слову, сказать, что пробовали, реально, всё что знаем, в т.ч. и печатать, как EndOfPage, но не помогает.

Для наглядности покажу код при котором корректно работает отчёт (он тоже будет во вложении) и при котором не работает.

1) Некорректная работа при вызове кода:

Код: Выделить всё

SELECT *
  FROM TABLE(DOCUMENTS_REPORTS_PKG.REP_FACTURA(:DOC_CODE, null))
Реальный код процедуры в базе:

Код: Выделить всё

  FUNCTION REP_FACTURA(in_DOC_CODE IN NUMBER, 
                       in_FACTURA_CODE IN NUMBER DEFAULT NULL) RETURN TAB_REP_FACTURA PIPELINED
  AS
    v_rec REC_REP_FACTURA := REC_REP_FACTURA(null, null, null, null, null, null, null, null, null, null, 
                                             null, null, null, null, null, null, null, null, null, null, 
                                             null, null, null, null, null, null, null, null, null, null, 
                                             null, null, null, null, null, null, null, null, null, null,
                                             null, null, null, null, null, null, null, null);   
    v_currency_code NUMBER(15);        
    v_is_blocked    VARCHAR2(1) := 'N';            
    v_prev_factura_code NUMBER(15);     
    v_voucher_doc_date  DATE;  
    v_doc_currency_code NUMBER(15);      
    v_factura_code NUMBER(15) := in_FACTURA_CODE;     
    v_param NUMBER(15);
    v_last_cor_factura_num NUMBER(15);
    
    CURSOR cur_factura IS
      SELECT cf.FACTURA_CODE
        FROM corrective_factura cf
       WHERE cf.DOC_CODE = in_DOC_CODE
         AND cf.FACTURA_CODE < v_factura_code         
         AND cf.FACTURA_TYPE = 2
    ORDER BY cf.FACTURA_CODE DESC;
    
  BEGIN
    -- Получаем данные по валюте
    SELECT c.CURRENCY_CODE, c.CURRENCY_NAME, c.INTERNATIONAL_CODE
      INTO v_currency_code, v_rec.CURRENCY_NAME, v_rec.CURRENCY_INTERNATIONAL_CODE
      FROM currency c
     WHERE c.F_NATIONAL_CURRENCY = 'Y';  
    
    -- Находим данные по СФ 
    IF (v_factura_code IS NULL) THEN
      SELECT v.FACTURA_CODE
        INTO v_factura_code
        FROM vouchers v 
       WHERE v.DOC_CODE = in_DOC_CODE;
    END IF;
    
    IF (v_factura_code IS NULL) THEN 
      RAISE err_pkg.e_document_not_found;
    END IF;
    
    
    -- Проверяем, были ли корректировочные сф до текущей СФ
    OPEN cur_factura;
    FETCH cur_factura INTO v_param;
    v_rec.USE_CORRECTIVE_FACTURA := (case when cur_factura%FOUND then 'Y' else 'N' end);
    CLOSE cur_factura; 
    
    -- Если были корректировочные СФ, то находим последнюю
    IF v_rec.USE_CORRECTIVE_FACTURA = 'Y' THEN
      SELECT cf.FACTURA_NUM, cf.FACTURA_DATE
        INTO v_last_cor_factura_num, v_rec.LAST_COR_FACTURA_DATE
        FROM corrective_factura cf
       WHERE cf.FACTURA_CODE = v_param;  
    END IF;
    
           
    FOR curr IN (SELECT cf2.FACTURA_CODE as PREV_FACTURA_CODE,
                        cf.IS_BLOCKED,
                        cf.FACTURA_NUM || (case when cf.FACTURA_TYPE <> 1 then org.DOC_INFORMATION end) as FACTURA_NUM_DET,
                        cf.FACTURA_DATE  as FACTURA_DATE,
                        cf.FACTURA_TYPE  as FACTURA_TYPE,
                        cf2.FACTURA_NUM || (case when cf2.FACTURA_TYPE <> 1 then org.DOC_INFORMATION end) as PREV_FACTURA_NUM_DET,
                        cf2.FACTURA_DATE as PREV_FACTURA_DATE,
                        cf2.FACTURA_TYPE as  PREV_FACTURA_TYPE,            
                        cf1.FACTURA_NUM || org.DOC_INFORMATION  as ORIGINAL_FACTURA_NUM_DET,
                        cf1.FACTURA_DATE  as ORIGINAL_FACTURA_DATE,
                        cf.NOTE,
                        v.GOODS,
                        v.DOC_DATE,
                        v.CURRENCY_CODE,
                        c.PROPERTY || ' ' || c.CLIENT_NAME as CLIENT_NAME,
                        (case when c.is_carry = 'Y' then '' else 'X' end) as IS_CARRY,
                        clients_pkg.SELECT_CLIENT_ADDRESS(c.CLIENT_CODE) || (case when c.PHONE IS NULL then '' else ' Телефон ' end) || NVL(c.PHONE, '') as CLIENT_ADDRESS,
                        clients_pkg.SELECT_CLIENT_ADDRESS2(c.CLIENT_CODE) as CLIENT_ADDRESS2, 
                        c.INN as CLIENT_INN,
                        c.OKPO as CLIENT_OKPO,
                        c.KPP as CLIENT_KPP,

                        TRIM(NVL(c.INN_KPP_FACTURA, '')) as INN_KPP_FACTURA,
                        TRIM(NVL(c.ADDRESS_BUYER_FACTURA, '')) as ADDRESS_BUYER_FACTURA,
                        TRIM(NVL(c.SENDER_FACTURA, '')) as SENDER_FACTURA,
                        TRIM(NVL(c.RECIPIENT_FACTURA, '')) as RECIPIENT_FACTURA,
                        TRIM(NVL(c.BUYER_FACTURA, '')) as BUYER_FACTURA,

                        'Банк ' || cb.BANK_NAME || ' БИК ' || cb.BIC || ' р/с ' || cb.ACCOUNT || ' к/с '|| cb.COR_ACCOUNT as CLIENT_BANK,
                        fi.PROPERTY || ' ' || fi.FIRM_NAME as SUPPLIER_NAME, 
                        NVL(fi.ADDRESS, '') || (case when fi.PHONE IS NULL then '' else ' Телефон ' end) || NVL(fi.PHONE, '') as SUPPLIER_ADDRESS,
                        fi.ADDRESS2 as  SUPPLIER_ADDRESS2,
                        fi.OKPO as SUPPLIER_OKPO,
                        fi.INN as SUPPLIER_INN,
                        fi.KPP as SUPPLIER_KPP,                       
                        orgg.ACCOUNTANT_NAME,
                        orgg.CHIEF_NAME,
                        org.DOC_INFORMATION
                   FROM corrective_factura cf
                        inner join vouchers v on v.DOC_CODE = cf.DOC_CODE
                        inner join corrective_factura cf1 on cf1.FACTURA_CODE = v.FIRST_FACTURA_CODE
                        inner join organization org on org.ORG_CODE = v.ORG_CODE 
                        inner join firms fi on v.MY_FIRM = fi.FIRM_CODE
                        inner join clients c on c.CLIENT_CODE = v.CLIENT_CODE
                        inner join rds$users r_us on r_us.USER_NAME = utils_pkg.C_USER_NAME
                        inner join rds$access_organizations orgg on orgg.USER_CODE = r_us.USER_CODE AND orgg.ORG_CODE = v.ORG_CODE
                        left join firm_banks fb on fb.BANK_CODE = c.FIRM_BANK_CODE
                        left join client_banks cb on c.BANK_CODE = cb.BANK_CODE
                        left join corrective_factura cf2 on cf2.FACTURA_CODE = cf.PREV_FACTURA_CODE       
                  WHERE cf.FACTURA_CODE = v_factura_code) 
    LOOP    
      v_rec.USE_CORRECTIVE_FACTURA := (case when curr.FACTURA_TYPE = 2 then 'Y' else v_rec.USE_CORRECTIVE_FACTURA end);
      v_prev_factura_code   := curr.PREV_FACTURA_CODE;
      v_is_blocked          := curr.IS_BLOCKED;
      v_rec.FACTURA_NUM_DET := curr.FACTURA_NUM_DET;
      v_rec.FACTURA_DATE    := curr.FACTURA_DATE;
      v_rec.FACTURA_TYPE    := curr.FACTURA_TYPE;
      v_rec.PREV_FACTURA_NUM_DET  := curr.PREV_FACTURA_NUM_DET;
      v_rec.PREV_FACTURA_DATE     := curr.PREV_FACTURA_DATE;
      v_rec.PREV_FACTURA_TYPE     := curr.PREV_FACTURA_TYPE;           
      v_rec.ORIGINAL_FACTURA_NUM_DET := curr.ORIGINAL_FACTURA_NUM_DET;
      v_rec.ORIGINAL_FACTURA_DATE := curr.ORIGINAL_FACTURA_DATE;
      v_rec.LAST_COR_FACTURA_NUM_DET := v_last_cor_factura_num || curr.DOC_INFORMATION;
            
      v_rec.NOTE     := curr.NOTE;
      v_rec.IS_CARRY := curr.IS_CARRY;
      
      v_voucher_doc_date  := curr.DOC_DATE;
      v_doc_currency_code := curr.CURRENCY_CODE;
                  
      IF curr.GOODS = 'приход' THEN
        v_rec.RECIPIENT_FACTURA := (case when LENGTH(curr.SENDER_FACTURA) > 1 then curr.SENDER_FACTURA else curr.SUPPLIER_NAME || curr.SUPPLIER_ADDRESS end);   --Строка грузополучателя в СЧЕТЕ-ФАКТУРЕ
        v_rec.SENDER_FACTURA    := (case when LENGTH(curr.RECIPIENT_FACTURA) > 1 then curr.RECIPIENT_FACTURA else curr.CLIENT_NAME || curr.CLIENT_ADDRESS end); --Строка грузоотправителя в СЧЕТЕ-ФАКТУРЕ  
        v_rec.ADDRESS_BUYER_FACTURA := curr.SUPPLIER_ADDRESS;                                                                                                   --Строка адреса покупателя в СЧЕТЕ-ФАКТУРЕ
        v_rec.BUYER_FACTURA   := curr.SUPPLIER_NAME;                                                                                                            --Строка покупателя в СЧЕТЕ-ФАКТУРЕ
        v_rec.INN_KPP_FACTURA := (case when LENGTH(curr.INN_KPP_FACTURA) > 1 then curr.INN_KPP_FACTURA else curr.SUPPLIER_INN || '/' || curr.SUPPLIER_KPP end); --Строка ИНН/КПП покупателя в СЧЕТЕ-ФАКТУРЕ 
        
        v_rec.SUPPLIER_NAME := curr.CLIENT_NAME;
        v_rec.SUPPLIER_ADDRESS := curr.CLIENT_ADDRESS;
        v_rec.SUPPLIER_INN := curr.CLIENT_INN;

        v_rec.CLIENT_NAME := curr.SUPPLIER_NAME ;
        v_rec.CLIENT_ADDRESS := curr.SUPPLIER_ADDRESS;
        v_rec.CLIENT_ADDRESS2 := curr.SUPPLIER_ADDRESS2;
        v_rec.CLIENT_INN := curr.SUPPLIER_INN;

      ELSIF curr.GOODS = 'расход' THEN 
        v_rec.RECIPIENT_FACTURA := (case when LENGTH(curr.RECIPIENT_FACTURA) > 1 then curr.RECIPIENT_FACTURA else curr.CLIENT_NAME || curr.CLIENT_ADDRESS2 end); --Строка грузополучателя в СЧЕТЕ-ФАКТУРЕ
        v_rec.SENDER_FACTURA    := (case when LENGTH(curr.SENDER_FACTURA) > 1 then curr.SENDER_FACTURA else curr.SUPPLIER_NAME || curr.SUPPLIER_ADDRESS2 end);   --Строка грузоотправителя в СЧЕТЕ-ФАКТУРЕ
        v_rec.ADDRESS_BUYER_FACTURA := (case when LENGTH(curr.ADDRESS_BUYER_FACTURA) > 1 then curr.ADDRESS_BUYER_FACTURA else curr.CLIENT_ADDRESS end);          --Строка адреса покупателя в СЧЕТЕ-ФАКТУРЕ
        v_rec.BUYER_FACTURA     := (case when LENGTH(curr.BUYER_FACTURA) > 1 then curr.BUYER_FACTURA else curr.CLIENT_NAME end);                                 --Строка покупателя в СЧЕТЕ-ФАКТУРЕ
        v_rec.INN_KPP_FACTURA   := (case when LENGTH(curr.INN_KPP_FACTURA) > 1 then curr.INN_KPP_FACTURA else curr.CLIENT_INN || '/' || curr.CLIENT_KPP end);    --Строка ИНН/КПП покупателя в СЧЕТЕ-ФАКТУРЕ  
        
        v_rec.SUPPLIER_NAME := 'Общество с ограниченной ответственностью "САКС Игрушки", ' || curr.SUPPLIER_NAME ;
        v_rec.SUPPLIER_ADDRESS := curr.SUPPLIER_ADDRESS;
        v_rec.SUPPLIER_INN := curr.SUPPLIER_INN || '/' || curr.SUPPLIER_KPP;

        v_rec.CLIENT_NAME := curr.CLIENT_NAME;
        v_rec.CLIENT_ADDRESS := curr.CLIENT_ADDRESS;
        v_rec.CLIENT_ADDRESS2 := curr.CLIENT_ADDRESS2;
        v_rec.CLIENT_INN := curr.CLIENT_INN;
        
        v_rec.CHIEF_ACCOUNTANT_NAME := curr.ACCOUNTANT_NAME;
        v_rec.CHIEF_NAME := curr.CHIEF_NAME;

      END IF;
    END LOOP;                     
                  
    FOR curr IN (SELECT g.WARE_NAME, 
                        g.PRODUCER_CODE, 
                        g.ARTICLE, 
                        z.QUANTITY, 
                        utils_pkg.EXCHANGE(v_voucher_doc_date, v_doc_currency_code, v_currency_code, z.F_PRICE) as N_PRICE, 
                        utils_pkg.EXCHANGE(v_voucher_doc_date, v_doc_currency_code, v_currency_code, z.F_SUM)   as N_SUM,
                        z.NDS, 
                        utils_pkg.EXCHANGE(v_voucher_doc_date, v_doc_currency_code, v_currency_code, z.F_SUM_NDS)   as N_SUM_NDS,                
                        utils_pkg.EXCHANGE(v_voucher_doc_date, v_doc_currency_code, v_currency_code, z.F_TOTAL_SUM) as N_TOTAL_SUM, 
                        z.WARE_CODE, 
                        z.NUMBER_GTD,
                        z.OLD_QUANTITY, 
                        utils_pkg.EXCHANGE(v_voucher_doc_date, v_doc_currency_code, v_currency_code, z.OLD_F_PRICE) as OLD_N_PRICE, 
                        utils_pkg.EXCHANGE(v_voucher_doc_date, v_doc_currency_code, v_currency_code, z.OLD_F_SUM)   as OLD_N_SUM, 
                        z.OLD_NDS,
                        utils_pkg.EXCHANGE(v_voucher_doc_date, v_doc_currency_code, v_currency_code, z.OLD_F_SUM_NDS) as OLD_N_SUM_NDS, 
                        utils_pkg.EXCHANGE(v_voucher_doc_date, v_doc_currency_code, v_currency_code, z.OLD_F_TOTAL_SUM)   as OLD_N_TOTAL_SUM,                 
                        cs.COUNTRY_NAME,
                        cs.INTERNATIONAL_CODE as COUNTRY_INTERNATIONAL_CODE
                  FROM (SELECT t.WARE_CODE,  
                               NVL(MAX(t.COUNTRY_CODE), MAX(t.OLD_COUNTRY_CODE)) as COUNTRY_CODE,  
                               SUM(t.QUANTITY) as QUANTITY,  
                               SUM(t.F_PRICE) as F_PRICE,  
                               SUM(t.F_SUM) as F_SUM,   
                               MAX(t.NDS) as NDS,  
                               SUM(t.F_SUM_NDS) as F_SUM_NDS,  
                               SUM(t.F_TOTAL_SUM) as F_TOTAL_SUM, 
                               NVL(MAX(t.NUMBER_GTD), MAX(t.OLD_NUMBER_GTD)) as NUMBER_GTD, 
                               SUM(t.OLD_QUANTITY) as OLD_QUANTITY, 
                               SUM(t.OLD_F_PRICE) as OLD_F_PRICE, 
                               SUM(t.OLD_F_SUM) as OLD_F_SUM, 
                               MAX(t.OLD_NDS) as OLD_NDS,
                               SUM(t.OLD_F_SUM_NDS) as OLD_F_SUM_NDS, 
                               SUM(t.OLD_F_TOTAL_SUM) as OLD_F_TOTAL_SUM          
                         FROM (SELECT cfa.WARE_CODE,             
                                      (case when cfa.FACTURA_CODE = v_prev_factura_code then NULL else cfa.COUNTRY_CODE end) as COUNTRY_CODE,  
                                      (case when cfa.FACTURA_CODE = v_prev_factura_code then 0 else cfa.QUANTITY    end) as QUANTITY,
                                      (case when cfa.FACTURA_CODE = v_prev_factura_code then 0 else cfa.F_PRICE     end) as F_PRICE,  
                                      (case when cfa.FACTURA_CODE = v_prev_factura_code then 0 else cfa.F_SUM       end) as F_SUM,   
                                      (case when cfa.FACTURA_CODE = v_prev_factura_code then NULL else cfa.NDS      end) as NDS,  
                                      (case when cfa.FACTURA_CODE = v_prev_factura_code then 0 else cfa.F_SUM_NDS   end) as F_SUM_NDS,  
                                      (case when cfa.FACTURA_CODE = v_prev_factura_code then 0 else cfa.F_TOTAL_SUM end) as F_TOTAL_SUM, 
                                      (case when cfa.FACTURA_CODE = v_prev_factura_code then NULL else cfa.NUMBER_GTD end) as NUMBER_GTD,
                                      (case when cfa.FACTURA_CODE = v_prev_factura_code then cfa.QUANTITY    else 0  end) as OLD_QUANTITY,
                                      (case when cfa.FACTURA_CODE = v_prev_factura_code then cfa.F_PRICE     else 0  end) as OLD_F_PRICE,  
                                      (case when cfa.FACTURA_CODE = v_prev_factura_code then cfa.F_SUM       else 0  end) as OLD_F_SUM,   
                                      (case when cfa.FACTURA_CODE = v_prev_factura_code then cfa.NDS         else NULL end) as OLD_NDS,  
                                      (case when cfa.FACTURA_CODE = v_prev_factura_code then cfa.F_SUM_NDS   else 0  end) as OLD_F_SUM_NDS,  
                                      (case when cfa.FACTURA_CODE = v_prev_factura_code then cfa.F_TOTAL_SUM else 0  end) as OLD_F_TOTAL_SUM,
                                      (case when cfa.FACTURA_CODE = v_prev_factura_code then cfa.COUNTRY_CODE else NULL end) as OLD_COUNTRY_CODE, 
                                      (case when cfa.FACTURA_CODE = v_prev_factura_code then cfa.NUMBER_GTD   else NULL end) as OLD_NUMBER_GTD      
                                 FROM corrective_factura_assort cfa  
                                WHERE cfa.FACTURA_CODE = v_prev_factura_code
                                   OR cfa.FACTURA_CODE = v_factura_code AND v_is_blocked = utils_pkg.C_YES 
                             union all
                               SELECT a.WARE_CODE,  
                                      a.COUNTRY_CODE,  
                                      a.QUANTITY,  
                                      a.F_PRICE,  
                                      a.F_SUM,   
                                      a.NDS,  
                                      a.F_SUM_NDS,  
                                      a.F_TOTAL_SUM, 
                                      a.NUMBER_GTD, 
                                      0 as OLD_QUQNTITY, 
                                      0 as OLD_F_PRICE, 
                                      0 as OLD_F_SUM, NULL as OLD_NDS, 
                                      0 as OLD_F_SUM_NDS, 
                                      0 as OLD_F_TOTAL_SUM,
                                      NULL as OLD_COUNTRY_CODE,
                                      NULL as OLD_NUMBER_GTD
                                 FROM assortments a      
                                WHERE a.DOC_CODE = in_DOC_CODE 
                                  AND v_is_blocked = utils_pkg.C_NO) t 
                     GROUP BY t.WARE_CODE) z          
                       inner join goods g on z.WARE_CODE = g.WARE_CODE
                       inner join countries cs on z.COUNTRY_CODE = cs.COUNTRY_CODE        
               ORDER BY g.PRODUCER_CODE, 
                        g.ARTICLE) 
    LOOP
      v_rec.WARE_NAME := curr.WARE_NAME;
      v_rec.ARTICLE := curr.ARTICLE;
      v_rec.QUANTITY := curr.QUANTITY;
      v_rec.PRICE := curr.N_PRICE;
      v_rec.SUM_ := curr.N_SUM;
      v_rec.NDS := curr.NDS;
      v_rec.SUM_NDS := curr.N_SUM_NDS;
      v_rec.TOTAL_SUM := curr.N_TOTAL_SUM;
      v_rec.OLD_QUANTITY := curr.OLD_QUANTITY;
      v_rec.OLD_PRICE := curr.OLD_N_PRICE;
      v_rec.OLD_SUM_ := curr.OLD_N_SUM;
      v_rec.OLD_NDS := curr.OLD_NDS;
      v_rec.OLD_SUM_NDS := curr.OLD_N_SUM_NDS;
      v_rec.OLD_TOTAL_SUM := curr.OLD_N_TOTAL_SUM;
      v_rec.NUMBER_GTD := curr.NUMBER_GTD;
      v_rec.COUNTRY_NAME := curr.COUNTRY_NAME;
      v_rec.COUNTRY_INTERNATIONAL_CODE := curr.COUNTRY_INTERNATIONAL_CODE;
      PIPE ROW(v_rec);
    END LOOP;                        
  END REP_FACTURA;
И её типы (Types):

Код: Выделить всё

CREATE OR REPLACE TYPE MERCHANT.REC_REP_FACTURA AS OBJECT(
    FACTURA_NUM_DET NVARCHAR2(20),
    FACTURA_DATE    DATE,
    FACTURA_TYPE    NUMBER(1),
    PREV_FACTURA_NUM_DET NVARCHAR2(20),
    PREV_FACTURA_DATE DATE,
    PREV_FACTURA_TYPE NUMBER(1),          
    ORIGINAL_FACTURA_NUM_DET NVARCHAR2(20),
    ORIGINAL_FACTURA_DATE DATE,    
    LAST_COR_FACTURA_NUM_DET NVARCHAR2(20),
    LAST_COR_FACTURA_DATE DATE,
    SUPPLIER_NAME NVARCHAR2(200),
    SUPPLIER_ADDRESS NVARCHAR2(200),
    SUPPLIER_ADDRESS2 NVARCHAR2(200),
    SUPPLIER_INN NVARCHAR2(100),
    CLIENT_NAME NVARCHAR2(200),
    IS_CARRY VARCHAR2(1),
---------
    INN_KPP_FACTURA NVARCHAR2(1000),
    ADDRESS_BUYER_FACTURA NVARCHAR2(1000),
    SENDER_FACTURA NVARCHAR2(1000),
    RECIPIENT_FACTURA NVARCHAR2(1000),
    BUYER_FACTURA NVARCHAR2(1000),
---------
    CLIENT_ADDRESS NVARCHAR2(200),
    CLIENT_ADDRESS2 NVARCHAR2(253),
    CLIENT_INN NVARCHAR2(100),
    CLIENT_KPP NVARCHAR2(100),
    NOTE NVARCHAR2(300),
    WARE_NAME NVARCHAR2(200),
    ARTICLE NVARCHAR2(100),
    QUANTITY NUMBER,
    PRICE NUMBER(15,2),
    SUM_ NUMBER(15,2),
    NDS NUMBER(15,2),
    SUM_NDS NUMBER(15,2),
    TOTAL_SUM NUMBER(15,2),
    OLD_QUANTITY NUMBER,
    OLD_PRICE NUMBER(15,2),
    OLD_SUM_ NUMBER(15,2),
    OLD_NDS NUMBER(15,2),
    OLD_SUM_NDS NUMBER(15,2),
    OLD_TOTAL_SUM NUMBER(15,2),
    NUMBER_GTD NVARCHAR2(100),
    CHIEF_NAME NVARCHAR2(80),
    CHIEF_ACCOUNTANT_NAME NVARCHAR2(80),
    CURRENCY_NAME NVARCHAR2(40),
    COUNTRY_NAME NVARCHAR2(40),
    CURRENCY_INTERNATIONAL_CODE NUMBER,
    COUNTRY_INTERNATIONAL_CODE NUMBER,
    USE_CORRECTIVE_FACTURA VARCHAR2(1));
/
Здесь и далее можно упростить до 3-х полей для наглядности: factura_date, factura_num_det и ware_name.

2) Корректная работа при вызове кода:

Код: Выделить всё

select (case when :DOC_CODE = 111 then TO_DATE('11.01.2016')
             when :DOC_CODE = 222 then TO_DATE('12.01.2016')
             when :DOC_CODE = 333 then TO_DATE('13.01.2016')
             when :DOC_CODE = 444 then TO_DATE('14.01.2016')
             when :DOC_CODE = 555 then TO_DATE('15.01.2016')
        end) as factura_date,
        
        (case when :DOC_CODE = 111 then '65/1'
             when :DOC_CODE = 222 then '66/1'
             when :DOC_CODE = 333 then '67/1'
             when :DOC_CODE = 444 then '68/1'
             when :DOC_CODE = 555 then '69/1'
        end) as factura_num_det,
        
        (case when :DOC_CODE = 111 then 'Игрушка 100'
             when :DOC_CODE = 222 then 'Игрушка 200'
             when :DOC_CODE = 333 then 'Игрушка 300'
             when :DOC_CODE = 444 then 'Игрушка 400'
             when :DOC_CODE = 555 then 'Игрушка 500'
        end) as ware_name       
  from dual
  
union all

select (case when :DOC_CODE = 111 then TO_DATE('11.01.2016')
             when :DOC_CODE = 222 then TO_DATE('12.01.2016')
             when :DOC_CODE = 333 then TO_DATE('13.01.2016')
             when :DOC_CODE = 444 then TO_DATE('14.01.2016')
             when :DOC_CODE = 555 then TO_DATE('15.01.2016')
        end) as factura_date,
        
        (case when :DOC_CODE = 111 then '65/1'
             when :DOC_CODE = 222 then '66/1'
             when :DOC_CODE = 333 then '67/1'
             when :DOC_CODE = 444 then '68/1'
             when :DOC_CODE = 555 then '69/1'
        end) as factura_num_det,
        
        (case when :DOC_CODE = 111 then 'Игрушка 101'
             when :DOC_CODE = 222 then 'Игрушка 201'
             when :DOC_CODE = 333 then 'Игрушка 301'
             when :DOC_CODE = 444 then 'Игрушка 401'
             when :DOC_CODE = 555 then 'Игрушка 501'
        end) as ware_name       
  from dual
  
union all

select (case when :DOC_CODE = 111 then TO_DATE('11.01.2016')
             when :DOC_CODE = 222 then TO_DATE('12.01.2016')
             when :DOC_CODE = 333 then TO_DATE('13.01.2016')
             when :DOC_CODE = 444 then TO_DATE('14.01.2016')
             when :DOC_CODE = 555 then TO_DATE('15.01.2016')
        end) as factura_date,
        
        (case when :DOC_CODE = 111 then '65/1'
             when :DOC_CODE = 222 then '66/1'
             when :DOC_CODE = 333 then '67/1'
             when :DOC_CODE = 444 then '68/1'
             when :DOC_CODE = 555 then '69/1'
        end) as factura_num_det,
        
        (case when :DOC_CODE = 111 then 'Игрушка 102'
             when :DOC_CODE = 222 then 'Игрушка 202'
             when :DOC_CODE = 333 then 'Игрушка 302'
             when :DOC_CODE = 444 then 'Игрушка 402'
             when :DOC_CODE = 555 then 'Игрушка 502'
        end) as ware_name       
  from dual
  
union all

select (case when :DOC_CODE = 111 then TO_DATE('11.01.2016')
             when :DOC_CODE = 222 then TO_DATE('12.01.2016')
             when :DOC_CODE = 333 then TO_DATE('13.01.2016')
             when :DOC_CODE = 444 then TO_DATE('14.01.2016')
             when :DOC_CODE = 555 then TO_DATE('15.01.2016')
        end) as factura_date,
        
        (case when :DOC_CODE = 111 then '65/1'
             when :DOC_CODE = 222 then '66/1'
             when :DOC_CODE = 333 then '67/1'
             when :DOC_CODE = 444 then '68/1'
             when :DOC_CODE = 555 then '69/1'
        end) as factura_num_det,
        
        (case when :DOC_CODE = 111 then 'Игрушка 103'
             when :DOC_CODE = 222 then 'Игрушка 203'
             when :DOC_CODE = 333 then 'Игрушка 303'
             when :DOC_CODE = 444 then 'Игрушка 403'
             when :DOC_CODE = 555 then 'Игрушка 503'
        end) as ware_name       
  from dual
  
union all

select (case when :DOC_CODE = 111 then TO_DATE('11.01.2016')
             when :DOC_CODE = 222 then TO_DATE('12.01.2016')
             when :DOC_CODE = 333 then TO_DATE('13.01.2016')
             when :DOC_CODE = 444 then TO_DATE('14.01.2016')
             when :DOC_CODE = 555 then TO_DATE('15.01.2016')
        end) as factura_date,
        
        (case when :DOC_CODE = 111 then '65/1'
             when :DOC_CODE = 222 then '66/1'
             when :DOC_CODE = 333 then '67/1'
             when :DOC_CODE = 444 then '68/1'
             when :DOC_CODE = 555 then '69/1'
        end) as factura_num_det,
        
        (case when :DOC_CODE = 111 then 'Игрушка 104'
             when :DOC_CODE = 222 then 'Игрушка 204'
             when :DOC_CODE = 333 then 'Игрушка 304'
             when :DOC_CODE = 444 then 'Игрушка 404'
             when :DOC_CODE = 555 then 'Игрушка 504'
        end) as ware_name       
  from dual
Вложения
Неверная печать данных из полей
Неверная печать данных из полей
incorrect.png (72.63 КБ) 3190 просмотров
Верная печать данных из полей
Верная печать данных из полей
correct.png (88.98 КБ) 3190 просмотров
Счёт-фактура.mrt
Сам отчёт (упрощённая версия - используются 3 поля)
(74.34 КБ) 291 скачивание
Aleksey
Сообщения: 2907
Зарегистрирован: 22 апр 2010, 06:57

Re: Рендеринг отчёта с разными параметрами

Сообщение Aleksey »

Здравствуйте,
1) Некорректная работа при вызове кода:
CODE: SELECT ALL
SELECT *
FROM TABLE(DOCUMENTS_REPORTS_PKG.REP_FACTURA(:DOC_CODE, null))
Могли бы вы упростить свою процедуру и прислать тестовые данные для нее, чтобы можно было воспроизвести некорректную работу именно с процедурой.

Спасибо.
Леонид
Сообщения: 329
Зарегистрирован: 23 июл 2009, 09:53
Откуда: Moscow

Re: Рендеринг отчёта с разными параметрами

Сообщение Леонид »

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

Вызов процедуры:

Код: Выделить всё

  SELECT factura_date, factura_num_det и ware_name
     FROM TABLE(DOCUMENTS_REPORTS_PKG.REP_FACTURA(:DOC_CODE)
Тело процедуры:

Код: Выделить всё

FUNCTION REP_FACTURA(in_DOC_CODE IN NUMBER) RETURN TAB_REP_FACTURA PIPELINED
  AS
    v_rec REC_REP_FACTURA := REC_REP_FACTURA(null, null, null);   
  BEGIN           
    FOR curr IN (SELECT cf.FACTURA_NUM_DET,
                        cf.FACTURA_DATE,
                        cf.WARE_NAME
                   FROM corrective_factura cf
                        inner join goods g on g.WARE_CODE = cf.WARE_CODE
                  WHERE cf.FACTURA_CODE = :in_DOC_CODE)
    LOOP    
      v_rec.FACTURA_NUM_DET := curr.FACTURA_NUM_DET;
      v_rec.FACTURA_DATE    := curr.FACTURA_DATE;
      v_rec.WARE_NAME       := curr.WARE_NAME;

      PIPE ROW(v_rec);
    END LOOP;
  END REP_FACTURA;
Типы данных для процедуры:

Код: Выделить всё

CREATE OR REPLACE TYPE MERCHANT.REC_REP_FACTURA AS OBJECT(
    FACTURA_NUM_DET NVARCHAR2(20),
    FACTURA_DATE    DATE,
    WARE_NAME NVARCHAR2(200)
);
Aleksey
Сообщения: 2907
Зарегистрирован: 22 апр 2010, 06:57

Re: Рендеринг отчёта с разными параметрами

Сообщение Aleksey »

Здравствуйте,

К сожалению, не хватает нескольких объектов - TAB_REP_FACTURA, DOCUMENTS_REPORTS_PKG.

Спасибо.
Леонид
Сообщения: 329
Зарегистрирован: 23 июл 2009, 09:53
Откуда: Moscow

Re: Рендеринг отчёта с разными параметрами

Сообщение Леонид »

не хватает нескольких объектов - TAB_REP_FACTURA

Код: Выделить всё

CREATE OR REPLACE TYPE MERCHANT.TAB_REP_FACTURA AS TABLE OF MERCHANT.REC_REP_FACTURA;
DOCUMENTS_REPORTS_PKG

Код: Выделить всё

CREATE OR REPLACE PACKAGE BODY MERCHANT.DOCUMENTS_REPORTS_PKG AS

FUNCTION REP_FACTURA(in_DOC_CODE IN NUMBER) RETURN TAB_REP_FACTURA PIPELINED
  AS
    v_rec REC_REP_FACTURA := REC_REP_FACTURA(null, null, null);   
  BEGIN           
    FOR curr IN (SELECT cf.FACTURA_NUM_DET,
                        cf.FACTURA_DATE,
                        cf.WARE_NAME
                   FROM corrective_factura cf
                        inner join goods g on g.WARE_CODE = cf.WARE_CODE
                  WHERE cf.FACTURA_CODE = :in_DOC_CODE)
    LOOP    
      v_rec.FACTURA_NUM_DET := curr.FACTURA_NUM_DET;
      v_rec.FACTURA_DATE    := curr.FACTURA_DATE;
      v_rec.WARE_NAME       := curr.WARE_NAME;

      PIPE ROW(v_rec);
    END LOOP;
  END REP_FACTURA;

END DOCUMENTS_REPORTS_PKG;
Aleksey
Сообщения: 2907
Зарегистрирован: 22 апр 2010, 06:57

Re: Рендеринг отчёта с разными параметрами

Сообщение Aleksey »

Здравствуйте,

Все закинули в базу. Получаем следующую ошибку, при выполнении запроса:

Спасибо.
Вложения
01.PNG
01.PNG (70.48 КБ) 3162 просмотра
Леонид
Сообщения: 329
Зарегистрирован: 23 июл 2009, 09:53
Откуда: Moscow

Re: Рендеринг отчёта с разными параметрами

Сообщение Леонид »

Попробуйте создать декларацию packagе DOCUMENTS_REPORTS_PKG так:

Код: Выделить всё

CREATE OR REPLACE PACKAGE DOCUMENTS_REPORTS_PKG  AS

  FUNCTION REP_FACTURA(in_DOC_CODE IN NUMBER) RETURN TAB_REP_FACTURA PIPELINED;
END DOCUMENTS_REPORTS_PKG ;
а так же таблицу goods (т.к. есть ссылка в select'е) с полем ware_name. Данные в таблицах можно использовать те же, что из первого select'а:

Код: Выделить всё

select (case when :DOC_CODE = 111 then TO_DATE('11.01.2016')
             when :DOC_CODE = 222 then TO_DATE('12.01.2016')
             when :DOC_CODE = 333 then TO_DATE('13.01.2016')
             when :DOC_CODE = 444 then TO_DATE('14.01.2016')
             when :DOC_CODE = 555 then TO_DATE('15.01.2016')
        end) as factura_date,
        
        (case when :DOC_CODE = 111 then '65/1'
             when :DOC_CODE = 222 then '66/1'
             when :DOC_CODE = 333 then '67/1'
             when :DOC_CODE = 444 then '68/1'
             when :DOC_CODE = 555 then '69/1'
        end) as factura_num_det,
        
        (case when :DOC_CODE = 111 then 'Игрушка 100'
             when :DOC_CODE = 222 then 'Игрушка 200'
             when :DOC_CODE = 333 then 'Игрушка 300'
             when :DOC_CODE = 444 then 'Игрушка 400'
             when :DOC_CODE = 555 then 'Игрушка 500'
        end) as ware_name       
  from dual
  
union all

select (case when :DOC_CODE = 111 then TO_DATE('11.01.2016')
             when :DOC_CODE = 222 then TO_DATE('12.01.2016')
             when :DOC_CODE = 333 then TO_DATE('13.01.2016')
             when :DOC_CODE = 444 then TO_DATE('14.01.2016')
             when :DOC_CODE = 555 then TO_DATE('15.01.2016')
        end) as factura_date,
        
        (case when :DOC_CODE = 111 then '65/1'
             when :DOC_CODE = 222 then '66/1'
             when :DOC_CODE = 333 then '67/1'
             when :DOC_CODE = 444 then '68/1'
             when :DOC_CODE = 555 then '69/1'
        end) as factura_num_det,
        
        (case when :DOC_CODE = 111 then 'Игрушка 101'
             when :DOC_CODE = 222 then 'Игрушка 201'
             when :DOC_CODE = 333 then 'Игрушка 301'
             when :DOC_CODE = 444 then 'Игрушка 401'
             when :DOC_CODE = 555 then 'Игрушка 501'
        end) as ware_name       
  from dual
  
union all

select (case when :DOC_CODE = 111 then TO_DATE('11.01.2016')
             when :DOC_CODE = 222 then TO_DATE('12.01.2016')
             when :DOC_CODE = 333 then TO_DATE('13.01.2016')
             when :DOC_CODE = 444 then TO_DATE('14.01.2016')
             when :DOC_CODE = 555 then TO_DATE('15.01.2016')
        end) as factura_date,
        
        (case when :DOC_CODE = 111 then '65/1'
             when :DOC_CODE = 222 then '66/1'
             when :DOC_CODE = 333 then '67/1'
             when :DOC_CODE = 444 then '68/1'
             when :DOC_CODE = 555 then '69/1'
        end) as factura_num_det,
        
        (case when :DOC_CODE = 111 then 'Игрушка 102'
             when :DOC_CODE = 222 then 'Игрушка 202'
             when :DOC_CODE = 333 then 'Игрушка 302'
             when :DOC_CODE = 444 then 'Игрушка 402'
             when :DOC_CODE = 555 then 'Игрушка 502'
        end) as ware_name       
  from dual
  
union all

select (case when :DOC_CODE = 111 then TO_DATE('11.01.2016')
             when :DOC_CODE = 222 then TO_DATE('12.01.2016')
             when :DOC_CODE = 333 then TO_DATE('13.01.2016')
             when :DOC_CODE = 444 then TO_DATE('14.01.2016')
             when :DOC_CODE = 555 then TO_DATE('15.01.2016')
        end) as factura_date,
        
        (case when :DOC_CODE = 111 then '65/1'
             when :DOC_CODE = 222 then '66/1'
             when :DOC_CODE = 333 then '67/1'
             when :DOC_CODE = 444 then '68/1'
             when :DOC_CODE = 555 then '69/1'
        end) as factura_num_det,
        
        (case when :DOC_CODE = 111 then 'Игрушка 103'
             when :DOC_CODE = 222 then 'Игрушка 203'
             when :DOC_CODE = 333 then 'Игрушка 303'
             when :DOC_CODE = 444 then 'Игрушка 403'
             when :DOC_CODE = 555 then 'Игрушка 503'
        end) as ware_name       
  from dual
  
union all

select (case when :DOC_CODE = 111 then TO_DATE('11.01.2016')
             when :DOC_CODE = 222 then TO_DATE('12.01.2016')
             when :DOC_CODE = 333 then TO_DATE('13.01.2016')
             when :DOC_CODE = 444 then TO_DATE('14.01.2016')
             when :DOC_CODE = 555 then TO_DATE('15.01.2016')
        end) as factura_date,
        
        (case when :DOC_CODE = 111 then '65/1'
             when :DOC_CODE = 222 then '66/1'
             when :DOC_CODE = 333 then '67/1'
             when :DOC_CODE = 444 then '68/1'
             when :DOC_CODE = 555 then '69/1'
        end) as factura_num_det,
        
        (case when :DOC_CODE = 111 then 'Игрушка 104'
             when :DOC_CODE = 222 then 'Игрушка 204'
             when :DOC_CODE = 333 then 'Игрушка 304'
             when :DOC_CODE = 444 then 'Игрушка 404'
             when :DOC_CODE = 555 then 'Игрушка 504'
        end) as ware_name       
  from dual
Леонид
Сообщения: 329
Зарегистрирован: 23 июл 2009, 09:53
Откуда: Moscow

Re: Рендеринг отчёта с разными параметрами

Сообщение Леонид »

Ах да, забыл сказать, что мы пробовали "завернуть" этот простой select (из DUAL), возвращающий 5 строк в функцию, - в результате всё работает, как и в случае с вашим первым примером, т.е. не работает что-то именно при выборе из package.
Леонид
Сообщения: 329
Зарегистрирован: 23 июл 2009, 09:53
Откуда: Moscow

Re: Рендеринг отчёта с разными параметрами

Сообщение Леонид »

Кстати, у вас на скриншоте ...REP_FACTURA(in_DOC_CODE, null) - это неверно, т.к. второго параметра нет, посмотрите, там в предыдущем посте коротенькая процедура с единственным входным параметром.
Aleksey
Сообщения: 2907
Зарегистрирован: 22 апр 2010, 06:57

Re: Рендеринг отчёта с разными параметрами

Сообщение Aleksey »

Здравствуйте, Леонид

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

Спасибо.
Вложения
Снимок2.PNG
Снимок2.PNG (50.44 КБ) 3151 просмотр
Снимок1.PNG
Снимок1.PNG (69.86 КБ) 3151 просмотр
Ответить