Инструменти за потребители

Инструменти за сайта


kak_da:spravki_scriptove

Разлики

Тук са показани разликите между избраната и текущата версия на страницата.

Препратка към сравнението на версиите

Both sides previous revisionПредходна версия
Следваща версия
Предходна версия
kak_da:spravki_scriptove [2019/01/02 15:31] – [Свойства на колони в динамични справки] t.lalovakak_da:spravki_scriptove [2020/07/31 10:59] (текуща) – [Системна процедура SYS$SLEEP] t.lalova
Ред 23: Ред 23:
  
 begin begin
-  ------- ЗАРЕЖДЕАНЕ НА ПРЕВОДИ --------------+  ------- ЗАРЕЖДАНЕ НА ПРЕВОДИ --------------
   LANG_1=null;  --  LANG_1 в config е not null, така че тук инициализацията е само за красота   LANG_1=null;  --  LANG_1 в config е not null, така че тук инициализацията е само за красота
   LANG_2=null;   LANG_2=null;
Ред 1266: Ред 1266:
 2. Всичко трябва да е заградено в <FieldProperties> ... </FieldProperties> \\ 2. Всичко трябва да е заградено в <FieldProperties> ... </FieldProperties> \\
 3. Какво свойства има: \\ 3. Какво свойства има: \\
-  *   name - име на поле +  *   name - име на поле 
-  *   displaylabel - Наименование на полето в таблицата (изгледа) - използва се "|" за създаване на бандове +  *   displaylabel - Наименование на полето в таблицата (изгледа) - използва се "|" за създаване на бандове 
-  *   displaywidth - Размер на полето в таблицата (цяло число) +  *   displaywidth - Размер на полето в таблицата (цяло число) 
-  *   readonly - Ако "false" - полето ще е разрешено за редакция (дефолт не е разрешено) +  *   readonly - Ако "false" - полето ще е разрешено за редакция (дефолт не е разрешено) 
-  *   focusing - Ако "true" - полето ще може да се клика върху него (дефолт - не може и зависи от справката дали има поне една колона за редакция!!!) +  *   focusing - Ако "true" - полето ще може да се клика върху него (дефолт - не може и зависи от справката дали има поне една колона за редакция!!!) 
-  *   visible - Ако е "false" се поставя за скрито (дефолт - полето е видимо) +  *   visible - Ако е "false" се поставя за скрито (дефолт - полето е видимо) 
-  *   is_checkbox - Ако "true" означава, че полето ще бъде CHECK BOX  +  *   is_checkbox - Ако "true" означава, че полето ще бъде CHECK BOX  
-  *   is_memo - Ако "true" означава, че полето е текст  +  *   is_memo - Ако "true" означава, че полето е текст  
-  *   is_icon_index - Ако "true" означава, че в полето има индекс на икона и ще се визуализира някоя от запазените картинки () +  *   is_icon_index - Ако "true" означава, че в полето има индекс на икона и ще се визуализира някоя от запазените картинки () 
-  *   is_picture - Ако "true" означава, че полето е снимка +  *   is_picture - Ако "true" означава, че полето е снимка 
-  *   displayformat - ако има такова свойство се поставя като формат на показване на полето  +  *   displayformat - ако има такова свойство се поставя като формат на показване на полето  
-  *   display_format - аналогично на displayformat +  *   display_format - аналогично на displayformat 
-  *   group_level - кое ниво на групране е полето (цяло число). Ако има такова свойство се търси и до кое ниво има разпънатост +  *   group_level - кое ниво на групране е полето (цяло число). Ако има такова свойство се търси и до кое ниво има разпънатост 
-  *   expand_level - до кое ниво да се разпъва - зависи от конкретното поле - очаква "true" +  *   expand_level - до кое ниво да се разпъва - зависи от конкретното поле - очаква "true" 
-  *   aggregate_type - възможни стойности: SUM, AVG, COUNT, MIN, MAX +  *   aggregate_type - възможни стойности: SUM, AVG, COUNT, MIN, MAX 
-  *   aggregate_postion - Основните са 1, 2 и 4. 1 - Поставя се в Тотала, 2 - поставя се и в Колонтитула по групи , 4 - поставя се в заглавието на групите (трябва да има групиране поне на 1 ниво!!!) +  *   aggregate_postion - Основните са 1, 2 и 4. 1 - Поставя се в Тотала, 2 - поставя се и в Колонтитула по групи , 4 - поставя се в заглавието на групите (трябва да има групиране поне на 1 ниво!!!)1 - TOTAL, 2 - GROUP TOTAL, 3 - GROUP TOTAL & TOTAL 4 - GROUP HEADER, 5 - 1 + 4, 6 - 2 + 4, 7 - 1 + 2 + 4 
-  *       1 - TOTAL, 2 - GROUP TOTAL, 3 - GROUP TOTAL & TOTAL 4 - GROUP HEADER, 5 - 1 + 4, 6 - 2 + 4, 7 - 1 + 2 + 4 +  *   freezing - очаква "LEFT" ("1") или "RIGHT" ("2"   
-  *   freezing - очаква "LEFT" ("1") или "RIGHT" ("2"   +
      
   Забележка ("false" може да се заменя с "0", а "true" с "1")   Забележка ("false" може да се заменя с "0", а "true" с "1")
Ред 1290: Ред 1289:
 Дейтасет с Колони (по ТД): GROUP_LEVEL_1, GROUP_LEVEL_2, GROUP_LEVEL_3, ITEM_NAME, VALUE_WITH_VAT, FOR_PAY_CHK, PAY_SUM \\ Дейтасет с Колони (по ТД): GROUP_LEVEL_1, GROUP_LEVEL_2, GROUP_LEVEL_3, ITEM_NAME, VALUE_WITH_VAT, FOR_PAY_CHK, PAY_SUM \\
 Искаме да групираме по GROUP_LEVEL_1 и да сложим сума на двете числови полета \\ Искаме да групираме по GROUP_LEVEL_1 и да сложим сума на двете числови полета \\
 +<code xml>
 <FieldProperties>  \\ <FieldProperties>  \\
  <field name="GROUP_LEVEL_1" group_level="1" displaylabel="Група|Ниво 1"/> \\  <field name="GROUP_LEVEL_1" group_level="1" displaylabel="Група|Ниво 1"/> \\
Ред 1299: Ред 1299:
  <field name="PAY_SUM" displayformat="0,.00" displaylabel="Документ|Сума Сторниране" aggregate_type="SUM" aggregate_postion="1"/> \\  <field name="PAY_SUM" displayformat="0,.00" displaylabel="Документ|Сума Сторниране" aggregate_type="SUM" aggregate_postion="1"/> \\
 </FieldProperties> \\ </FieldProperties> \\
 +</code>
 +
 +===== Системна процедура SYS$SLEEP =====
 +
 +Функция **SYS$SLEEP** служи за прекъсване на изпълнението на процедура, блок или тригер за определен брой милисекунди.
 +Може да се използва в случай на заключване на записи и изчакване за последващото освобождаване.
 +
 +Пример 1: Използване на процедурата в стейтмънт за извличане на номер от автоматична номерация (кочан).
 +
 +<code pascal>
 + NEW_DOC_NUMBER = null;
 +    if (DOC_NUM_GENERATOR_REF is not null) then
 +    begin
 +      STMT = 'execute block
 +      (
 +        WRH_DOC_TYPE_REF DM_REF = :WRH_DOC_TYPE_REF,
 +        DOC_NUM_GENERATOR_REF DM_REF = :DOC_NUM_GENERATOR_REF,
 +        WRH_DOC_DATE DM_DATE = :WRH_DOC_DATE
 +      )
 +      returns
 +      (
 +        NEW_DOC_NUMBER DM_REF
 +      )
 +      as
 +      declare variable MIN_RANGE DM_BIGINT;
 +      declare variable MAX_RANGE DM_BIGINT;
 +      declare variable CHECK_LAST_INVOICES_DATE DM_INT;
 +      declare variable LAST_INVOICE_DATE DM_DATE;
 +      declare variable LAST_INVOICE_YEAR DM_INT;
 +      declare variable LAST_INVOICE_MONTH DM_INT;
 +      declare variable LAST_INVOICE_DAY DM_INT;
 +      declare variable repeat_count DM_123;
 +      begin
 +         MIN_RANGE = null;
 +         MAX_RANGE = null;
 +         select
 +           DNG.RANGE_MIN, DNG.RANGE_MAX
 +         from
 +           NOM$DOC_NUM_GENERATORS DNG
 +           join NOM$DOC_NUM_GENERATOR_TYPES DNGT on DNGT.DOC_NUM_GENERATORS_REF = DNG.ID
 +           join CONFIG C on C.CURRENT_COM_ID = DNG.CURRENT_COM_REF
 +         where
 +           DNG.ID = :DOC_NUM_GENERATOR_REF and
 +           DNGT.GENERATOR_DOC_TYPE = :WRH_DOC_TYPE_REF and
 +           DNG.GENERATOR_TYPE = 1
 +         into :MIN_RANGE, :MAX_RANGE;
 +     
 +         repeat_count = 0;
 +         NEW_DOC_NUMBER = null;
 +         while ((repeat_count < 5) and (NEW_DOC_NUMBER is null)) do
 +         begin
 +            repeat_count = repeat_count + 1;
 +            NEW_DOC_NUMBER = null;
 +            update
 +              NOM$DOC_NUM_GENERATORS G
 +            set
 +              G.CURRENT_VALUE = G.CURRENT_VALUE + 1
 +            where
 +              G.ID = :DOC_NUM_GENERATOR_REF
 +            returning
 +              G.CURRENT_VALUE - 1
 +            into
 +              :NEW_DOC_NUMBER;
 +            when any do
 +            begin
 +              execute procedure SYS$SLEEP(200);
 +              NEW_DOC_NUMBER = null;
 +            end
 +          end
 +          if (NEW_DOC_NUMBER is null) then
 +              exception CLEAN_TEXT_ERROR ''There was a problem getting an invoice number for the warehouse document!'';  
 +        
 +          if (((MAX_RANGE is not null) and (NEW_DOC_NUMBER >= MAX_RANGE)) or
 +             ((MIN_RANGE is not null) and (NEW_DOC_NUMBER < MIN_RANGE))) then
 +          begin
 +            -- exausted range of the generator
 +            execute procedure SYS$EXCEPTION_CLEAN(64);
 +          end
 +
 +           CHECK_LAST_INVOICES_DATE = null;
 +           select
 +             WDT2.CHECK_LAST_INVOICES_DATE
 +           from
 +             WRH$DOC_TYPES2 WDT2
 +           where
 +             WDT2.ID = :WRH_DOC_TYPE_REF
 +           into
 +             :CHECK_LAST_INVOICES_DATE;
 +
 +           if ((CHECK_LAST_INVOICES_DATE is not null) and (CHECK_LAST_INVOICES_DATE > 0)) then
 +           begin
 +             -- check if the date of the previous invoice is not past the date of the current invoice
 +             LAST_INVOICE_DATE = null;
 +             select
 +               first 1
 +               WD.DOC_DATE, extract(year from WD.DOC_DATE), extract(month from WD.DOC_DATE),
 +               extract(day from WD.DOC_DATE)
 +             from
 +               WRH$DOCS WD
 +             where
 +               (WD.DOC_NUMBER < :NEW_DOC_NUMBER) and
 +               (WD.DOC_NUMBER >= (:NEW_DOC_NUMBER - :CHECK_LAST_INVOICES_DATE)) and
 +               (WD.DOC_STATUS >= 0) and
 +               (WD.DOC_NUM_GENERATOR_REF = :DOC_NUM_GENERATOR_REF)
 +             order by
 +               WD.DOC_NUMBER desc
 +             into
 +               :LAST_INVOICE_DATE, :LAST_INVOICE_YEAR, LAST_INVOICE_MONTH, :LAST_INVOICE_DAY;
 +
 +             if ((LAST_INVOICE_DATE is not null) and
 +                (LAST_INVOICE_DATE > :WRH_DOC_DATE)) then
 +             begin
 +               execute procedure SYS$EXCEPTION_CLEAN(71,
 +               '' '' || LAST_INVOICE_DAY || ''.'' || LAST_INVOICE_MONTH || ''.'' || LAST_INVOICE_YEAR);
 +             end
 +           end
 +         suspend;
 +      end';
 +      
 +      
 +      execute statement (STMT) (WRH_DOC_TYPE_REF := WRH_DOC_TYPE_REF, DOC_NUM_GENERATOR_REF := :DOC_NUM_GENERATOR_REF, WRH_DOC_DATE := :WRH_DOC_DATE) WITH AUTONOMOUS TRANSACTION
 +      into
 +        :NEW_DOC_NUMBER;
 +
 +</code>
 +
 +Пример 2: Показва изпълнението само в случая за изтегляне на номер и изчакването за следващ опит. Този пример е част от горната процедура. 
 +
 +При изтегляне на номер на фактура от кочан се извършва ъпдейт и изтегляне на номера в една транзакция. Ако транзакцията продължи около 1 секунда, то през това време, никой друг не може да достъпи същия кочан и да изтегли пореден номер.
 +
 +В този случай при грешка можем да изчакаме определено време (колкото преценим, че е добре) и да опитаме отново.
 +Пример за точно такова изчакване е в следващия пример:
 +
 +<code pascal>
 +         repeat_count = 0;
 +         NEW_DOC_NUMBER = null;
 +         while ((repeat_count < 5) and (NEW_DOC_NUMBER is null)) do
 +         begin
 +            repeat_count = repeat_count + 1;
 +            NEW_DOC_NUMBER = null;
 +            update
 +              NOM$DOC_NUM_GENERATORS G
 +            set
 +              G.CURRENT_VALUE = G.CURRENT_VALUE + 1
 +            where
 +              G.ID = :DOC_NUM_GENERATOR_REF
 +            returning
 +              G.CURRENT_VALUE - 1
 +            into
 +              :NEW_DOC_NUMBER;
 +            when any do
 +            begin
 +              execute procedure SYS$SLEEP(200); -- ако поискаме повече от 200 мс трябва да поставим съответното време за изчакване тук!
 +              NEW_DOC_NUMBER = null;
 +            end
 +          end
 +          if (NEW_DOC_NUMBER is null) then
 +              exception CLEAN_TEXT_ERROR ''There was a problem getting an invoice number for the warehouse document!'';  
  
 +</code>   
kak_da/spravki_scriptove.1546443110.txt.gz · Последна промяна: 2019/01/02 15:31 от t.lalova