21 ноября, среда 13:32
Bankir.Ru

Объявление

Свернуть
Пока нет объявлений.

Универсальные транзакции TEMP-TABLE

Свернуть
X
  • Фильтр
  • Время
  • Показать
Очистить всё
новые сообщения

  • Универсальные транзакции TEMP-TABLE

    Очень хотелось бы следующий функционал:
    1. Производим некоторую обработку универсальной транзакцией;
    2. В результате создаем TEMP-TABLE;
    3. Вызываем процедуру на чистом ABL;
    4. Производим обработку данных из TEMP-TABLE в процедуре ABL.

    Хотелось и обратный вариант, когда в ABL создаем TEMP-TABLE, а в универсальной транзакции обрабатываем TEMP-TABLE.

    Умеет ли кто-нибудь такое делать?

  • #2
    Маслов Д. А.,
    не совсем понятно зачем такое городить. и почему не хватает функцирнала УТ.
    но как вариант можно подключить свою библиотеку и написать пару нужных функций.
    ЗЫ запуск 4gl процедуры - RUN(..)
    вызов тр-ии из 4gl описывался bulkload ом в ветке про УТ

    Комментарий


    • #3
      А чего ж здесь такого нагорожено?

      Пример, для первой возможности.
      Имеется транзакция по созданию документов на основе каких-либо данных. Очевидно, что лучше всего создание документов делать в УТ. Так же по созданным документам хочется создать НАИКРАСИВЕЙШИЙ отчет, причем не пост фактум (то есть по документам), а на основе данных по которым создаются документы. Предполагается данные и создание документов поручить УТ, а отчет ABL.


      Пример, для второй возможности:
      2.1 В какой-либо системе получаем данные на основе которых необходимо создать документ в АБС;
      2.2 Выгружаем данные в XML;
      2.3 Создаем TEMP-TABLE выполняем метод LOAD-XML;
      2.4 Запускаем УТ;
      2.5 В ней проходясь по TEMP-TABLE как обычной таблице выполняем создание документо.

      Комментарий


      • #4
        http://dom.bankir.ru/showpost.php?p=...&postcount=177
        Можно, достаточно вызвать процедуру g-trans.p, передав ей дату опердня и RECID op-kind. В принципе так можно вызвать любую ст. транзакцию не обязательно универсальную, правда вызывать надо процедуру указанную в поле ПРОЦЕДУРА

        Комментарий


        • #5
          Сообщение от Маслов Д. А. Посмотреть сообщение
          Так же по созданным документам хочется создать НАИКРАСИВЕЙШИЙ отчет, причем не пост фактум (то есть по документам)
          Это - логическая ошибка. Отчёт по документам обязан быть сделан по документам, ведь это же отчёт по документам.

          В целом, никаких проблем вызвать транзакцию из ABL нет (и примеров тому есть в бисквитовском коде масса):

          Код:
          {globals.i}
          def param in-op-date like op.op-date.
          in-op-date = today.
          find first op-kind no-lock.
          run value(op-kind.proc) (in-op-date, recid(op-kind)) no-error.
          Разумеется, это "скелет", т.е. присвоение дня, проверку дня на открытость, проверку на право работы в блокированном дне, поиск транзакции, обработку ошибок транзакции - надо делать вручную.
          /kiv

          Комментарий


          • #6
            Сообщение от Илюха Посмотреть сообщение
            Это - логическая ошибка. Отчёт
            А вот тут я с Вами не согласен. Действительно есть отчеты которые должны выполняться по документам, но есть отчеты на основании которых делаются документы. Пример, распоряжение на формирование резерва. На основании него делаются документы. И в этом случае логической ошибкой как раз является формирования распоряжения по уже готовым документам.

            Вызывать то вызовем, а как произвольные параметры передать??? Особенно если их много?

            Комментарий


            • #7
              Сообщение от Маслов Д. А. Посмотреть сообщение
              Вызывать то вызовем, а как произвольные параметры передать??? Особенно если их много?
              В универсальную можно так:

              {topkind.def}
              ...
              {empty tOpKindParams}
              TDAddParam("наименование параметра",значение_параметра).
              TDAddBuffer(хэндл_буфера,"наименование_буфера").
              RUN ex-trans.p ("транзакция", дата_опердня, TABLE tOpKindParams, OUTPUT vOk, OUTPUT vMessage).

              Возвращаемое:
              vOk - результат транзакции выполнилась/не выполнилась
              vMessage - или пусто (если vOk = YES) или текст "Ошибка выполнения транзакции ..." (если vOk = NO).

              Комментарий


              • #8
                Сообщение от Маслов Д. А. Посмотреть сообщение
                Вызывать то вызовем, а как произвольные параметры передать??? Особенно если их много?
                Наиболее гибко, через временную таблицу. Можно воспользоваться стандартной через GetSysConf / SetSysConf, можно сваять свою собственную. Врапперы - положить в pp-ptmp.p и не забыть перезайти в БИСквит после компиляции (как и прочие персистентные процедуры, кешируется при запуске).

                UPD: если у Вас и впрямь несколько автоматизированных систем и автоматический импорт-экспорт между ними, то
                - обязательно предусматривайте взаимную квитовку. В том числе, квитовку удаления
                - при импорте внутри транзакции (в терминах Progress, т.е. do trans: ... end.) БД расставляет на измяемые записи блокировки. Это, - операция оправданная при малом количестве блокировок (20-30 документов, ориентировочно), при большом количестве блокировок наблюдаем геометрическую прогрессию "торможения системы". Т.е. не импортируйте документы "большой пачкой все сразу", бейте пачки на группы.
                /kiv

                Комментарий


                • #9
                  Сообщение от Илюха Посмотреть сообщение
                  Наиболее гибко, через временную таблицу. Врапперы - положить в pp-ptmp.p и не забыть перезайти в БИСквит после компиляции (как и прочие персистентные процедуры, кешируется при запуске).
                  Не могли бы Вы более подробнее рассказать, особенно в части создания враппера?

                  Комментарий


                  • #10
                    В конец pp-ptmp кладёте код примерно такого вида:
                    Код:
                    {xttbl.def} /* определение глобальной временной таблицы */
                    {pfuncdef
                       &NAME          = "getParam"
                       &DESCRIPTION   = "Получает значение из временной таблицы"
                       &PARAMETERS    = "Наименование"
                       &RESULT        = "Значение"
                       &SAMPLE        = "getparam('НазначениеПлатежа')"
                       }
                       DEFINE INPUT  PARAMETER iparam      AS CHARACTER  NO-UNDO.
                       DEFINE OUTPUT PARAMETER out_Result  AS CHARACTER  NO-UNDO.
                       DEFINE OUTPUT PARAMETER is-ok       AS INTEGER    NO-UNDO.
                       find first xttbl where xttbl.name eq iparam no-lock no-error.
                       if avail xttbl then
                        out_result = xttbl.value.
                       else
                        out_result = "".
                    end procedure.
                    {pfuncdef
                       &NAME          = "setParam"
                       &DESCRIPTION   = "Устанавливает значение во временной таблице"
                       &PARAMETERS    = "Наименование, значение"
                       &RESULT        = "1"
                       &SAMPLE        = "setparam('oprecid',op(10))"
                       }
                       DEFINE INPUT  PARAMETER iparam      AS CHARACTER  NO-UNDO.
                       DEFINE INPUT  PARAMETER ivalue      AS CHARACTER  NO-UNDO.
                       DEFINE OUTPUT PARAMETER out_Result  AS CHARACTER  NO-UNDO.
                       DEFINE OUTPUT PARAMETER is-ok       AS INTEGER    NO-UNDO.
                       find first xttbl where xttbl.name eq iparam no-error.
                       if avail xttbl then
                        xttbl.value = ivalue.
                       else do:
                        create xttbl.
                        assign 
                         xttbl.name = iparam
                         xttbl.value = ivalue
                        .
                       end.
                    end procedure.
                    xttbl.def:
                    Код:
                    &IF DEFINED(XTTBL-DEF) EQ 0 &THEN
                    
                    DEFINE NEW GLOBAL SHARED TEMP-TABLE xttbl NO-UNDO
                       field name      as char
                       field value     as char
                    .
                    
                    &GLOB XTTBL-DEF YES
                    &ENDIF
                    pp-ptmp компилируете и включаете ptmp в список библиотек той УТ, которая нужна.

                    Это, опять же, скелет. Общая идея, думаю, понятна?
                    /kiv

                    Комментарий


                    • #11
                      Сообщение от Илюха Посмотреть сообщение
                      В конец pp-ptmp кладёте код примерно такого вида:
                      По сути это тот же GetSysConf / SetSysConf .

                      Комментарий


                      • #12
                        Сообщение от cypok Посмотреть сообщение
                        По сути это тот же GetSysConf / SetSysConf .
                        Да согласен с Вами. Меня же в большей степени интересовала возможность реализации следующего:
                        1. Пишет процедуру test1.p на ABL. Приблизительно следующего содержания.
                        Код:
                        DEFINE SHARED VARIABLE hTTable AS HANDLE.
                        CREATE TEMP-TABLE hTTable.
                        hTTable:READ-XML().
                        2. Пишем УТ из нескольких шаблонов.
                        а) В первом RUN test1.p;
                        б) Во втором осуществляем поиск по таблице
                        Код:
                        hTTable:DEFAULT-BUFFER-HANDLE
                        с возможностью использования стандартных возможностей УТ в частности
                        Код:
                        ГР_ТРАНЗАКЦИЯ()
                        ;
                        в) В третьем производим удаление hTTable.

                        Возможно ли такое? Или это мои несбыточные мечты?

                        Комментарий


                        • #13
                          Сообщение от Маслов Д. А. Посмотреть сообщение
                          Да согласен с Вами. Меня же в большей степени интересовала возможность реализации следующего:
                          ...
                          Возможно ли такое? Или это мои несбыточные мечты?
                          Пример:

                          0. В этой таблице допустим у вас будет поле field1 .

                          1. В test1.p в конце ставим RETURN STRING(hTTable).

                          2. Создаем Транзакция1 , в поле "выполнить до" ставим:
                          @Table1 = RUN(test1,"");
                          ГР_ТРАНЗАКЦИЯ("Транзакция2",@Table1);
                          1

                          3. Создаем Транзакция2 , в поле "выполить до" ставим:
                          MESSAGE("Поле field1 = " + @field1 , INFORMATION);
                          1

                          4. Запускаем это всё, на каждую запись из временной таблицы будет выведено сообщение со значением field1 .

                          Комментарий


                          • #14
                            Не было возможности отписаться раньше. Спасибо за помощь. Постараюсь на следующей недели попробовать. Правильно ли я полагаю, что возможна и обратная ситуация, когда в процедуру на ABL передается FilterTable из шаблона произвольного запроса к БД. А в процедуре уже производим преобразование в HANDLE и дальнейшую работу с таблицей?

                            Так же интересно возможно ли в УТ сформировать TEMP-TABLE? То есть чтобы ГР_ТРАНЗАКЦИЯ() формировала одну запись новой временной таблицы?

                            Комментарий


                            • #15
                              Сообщение от Маслов Д. А. Посмотреть сообщение
                              ... Правильно ли я полагаю, что возможна и обратная ситуация, когда в процедуру на ABL передается FilterTable из шаблона произвольного запроса к БД. А в процедуре уже производим преобразование в HANDLE и дальнейшую работу с таблицей?
                              Да, конечно, например:

                              в УТ делаем:
                              1. Шаблон класса Filter , действие Создать , с любой выборкой , с заданными полями для отбора (реквизит fields) , пусть например fields будет "op-buffer.op".
                              2. Делаем RUN("my-proc1",@FilterTable);

                              в my-proc1.p:
                              DEFINE INPUT PARAMETER iTableHdl AS CHARACTER NO-UNDO.
                              mFilterTable = WIDGET-HANDLE(iTableHdl).
                              mFilterBuffer = mFilterTableEFAULT-BUFFER-HANDLE.
                              /*
                              mFilterBuffer - хэнд на буфер TEMP-TABLE, которая заполнена записями отобранными в шаблоне, с полями заданными в реквизите fields, т.е. есть поле "op-buffer_op" (поля называются как "имя буфера" + "_" + "имя поля").
                              */
                              mFilterBuffer:FIND-FIRST("",NO-LOCK).
                              /* Выводим значение поля на экран */
                              MESSAGE mFilterBuffer:BUFFER-FIELD("op-buffer_op"):BUFFER-VALUE VIEW-AS ALERT-BOX.


                              Сообщение от Маслов Д. А. Посмотреть сообщение
                              Так же интересно возможно ли в УТ сформировать TEMP-TABLE? То есть чтобы ГР_ТРАНЗАКЦИЯ() формировала одну запись новой временной таблицы?
                              Свой TEMP-TABLE , кроме FilterTable в шаблоне класса Filter , к сожалению на стандартной версии создать пока невозможно.

                              Комментарий


                              • #16
                                Попробовал сделать обработку TEMP-TABLE из УТ. Получилось! Благодарю всех кто помогал разобраться. Особый респект сурок. Чтобы закрепить решение опишу, что сделал в итоге.
                                Врапер для работы с xml данными в УТ.
                                Код:
                                Часть ABL
                                getXml.p
                                /**********************************
                                 * Врапер для загрузки XML в УТ *
                                **********************************/
                                DEFINE INPUT PARAMETER cFileName AS CHARACTER.
                                
                                DEFINE NEW SHARED VARIABLE hTTable AS HANDLE.
                                CREATE TEMP-TABLE hTTable.
                                hTTable:READ-XML("FILE",cFileName,"EMPTY",?,?,?,?).
                                
                                RETURN STRING(hTTable).
                                Часть для УТ
                                Код:
                                @ResultTable=RUN("getXml","/home2/maslov/myxml.xml","Нет");
                                ГР_ТРАНЗАКЦИЯ('02',@ResultTable);
                                Структуру временной таблицы задаю в XML схеме. Ссылку на схему указываю в XML файл, например, так
                                Код:
                                ?xml version="1.0" encoding="UTF-8"?>
                                TDocCollect xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="/home/maslov/TDocCollect.xsd">
                                /TDocCollect>
                                .
                                Более подробно по XML в ABL OpenEdge® Development:
                                Working with XML

                                Комментарий


                                • #17
                                  Позвольте и мне также поблагодарить товарища с ником "Сурок".
                                  По его рецептам сделал импорт из текстового НЕСОРТИРОВАННОГО файла в динамическую темп-тейбл и дальше напустил на нее УТ.

                                  Комментарий


                                  • #18
                                    У меня такая беда - не могу удалить динамический темп-тейбл.
                                    Как правильно вызвать процедуру с кодом
                                    delete object hTTable.
                                    ?

                                    Комментарий


                                    • #19
                                      Сообщение от kabysdox Посмотреть сообщение
                                      У меня такая беда - не могу удалить динамический темп-тейбл.
                                      delete object hTTable.
                                      ?
                                      Должно работать.
                                      Доработанный выще пример:
                                      Код:
                                      DEFINE INPUT PARAMETER iTableHdl AS CHARACTER NO-UNDO.
                                      
                                      DEFINE VAR mFilterTable AS HANDLE NO-UNDO.
                                      DEFINE VAR mFilterBuffer AS HANDLE NO-UNDO.
                                      
                                      mFilterTable = WIDGET-HANDLE(iTableHdl).
                                      mFilterBuffer = mFilterTable:DEFAULT-BUFFER-HANDLE.
                                      /*
                                      mFilterBuffer - хэнд на буфер TEMP-TABLE, которая заполнена записями отобранными в шаблоне, с полями заданными в реквизите fields, т.е. есть поле "op-buffer_op" (поля называются как "имя буфера" + "_" + "имя поля").
                                      */
                                      mFilterBuffer:FIND-FIRST("",NO-LOCK).
                                      /* Выводим значение поля на экран */
                                      MESSAGE mFilterBuffer:BUFFER-FIELD("op-buffer_op"):BUFFER-VALUE VIEW-AS ALERT-BOX.
                                      
                                      DELETE OBJECT mFilterTable.
                                      MESSAGE "DELETED =" NOT VALID-HANDLE(mFilterTable) VIEW-AS ALERT-BOX.
                                      Первое сообщение покажет реквизит op.
                                      Второе сообщение покажет что TEMP-TABLE стало NOT VALID.

                                      Важно делать DELETE на хэндл от таблицы, а не от буфера (буфер здесь - mFilterBuffer, а таблица - mFilterTable)

                                      Комментарий


                                      • #20
                                        В дополнение - в D59 выйдут три новые функции универсальных транзакций:
                                        СОЗДАТЬ_ФИЛЬТР - создание своего фильтра (задаются поля и индексы).
                                        ДОБАВИТЬ_ЗАПИСЬ_ФИЛЬТРА - добавляет запись фильтра (с заданными значениями полей).
                                        УДАЛИТЬ_ЗАПИСЬ_ФИЛЬТРА - удаляет запись фильтра (с заданными значениями полей).
                                        Созданные фильтры удаляются сами по завершении транзакции.
                                        Плюс добавилась возможность делать фильтр по фильтру, пример:

                                        1. Получили как-то FilterTable (или через шаблон класса/подкласса Filter или через функцию СОЗДАТЬ_ФИЛЬТР).

                                        2. Создаем шаблон класса Filter.

                                        3. Задаем в реквизите tables :
                                        "TT_" + @FilterTable
                                        т.е. таблицей является ранее созданный TEMP-TABLE с хэндлом FilterTable.

                                        4. Задаем в реквизите buffers его название, например:
                                        TestTempTable

                                        5. Задаем в реквизите where выражение отбора, например:
                                        "FOR EACH TestTempTable WHERE TestTempTable.lala = 123 NO-LOCK"

                                        6. Задаем в реквизите fields поля отбора, например:
                                        "TestTempTable.lala,TestTempTable.bubu"

                                        Получаем ещё один @FilterTable , в котором только записи TestTempTable.lala = 123 , с таким FilterTable можно например использовать ГР_ТРАНЗАКЦИЯ или прогнать обработку такой таблицы через процедуру как указано выше.
                                        Т.е. спектр применения - неимоверно широкий.

                                        Комментарий


                                        • #21
                                          1.То есть удалять надо именно хендл на буфер,а НЕ на саму таблицу?
                                          2.Раньше же вроде тоже можно было делать фильтр по фильтру,указав в поле $FilterTable "выражение" @FilterTable(10),или я не прав?
                                          3.Милчеловек,ты нам укажи, что надо написать чтобы заголовок фрейма менять что-то осмысленное (например "Выберите счет" или еще что-то).$Title не прокатывает...
                                          Последний раз редактировалось kabysdox; 27.04.2010, 16:34.

                                          Комментарий


                                          • #22
                                            Сообщение от kabysdox Посмотреть сообщение
                                            То есть удалять надо именно хендл на буфер,а НЕ на саму таблицу?
                                            Да нет же. Надо делать DELETE на хэндл от таблицы, а не от буфера.

                                            Комментарий


                                            • #23
                                              Сообщение от cypok Посмотреть сообщение
                                              Да нет же. Надо делать DELETE на хэндл от таблицы, а не от буфера.
                                              Так я так и делал вроде.У меня ошибка возникала...

                                              Комментарий


                                              • #24
                                                Сообщение от kabysdox Посмотреть сообщение
                                                Так я так и делал вроде.У меня ошибка возникала...
                                                Было бы неплохо узнать какая ошибка.

                                                Комментарий


                                                • #25
                                                  Сообщение от cypok Посмотреть сообщение
                                                  Было бы неплохо узнать какая ошибка.
                                                  Сейчас все хорошо - спасибо еще раз.До этого я хендлы на буфер не делал...
                                                  По поводу заголовков у фреймов с броузерами можете подсказать?

                                                  Комментарий


                                                  • #26
                                                    Сообщение от kabysdox Посмотреть сообщение
                                                    Сейчас все хорошо - спасибо еще раз.До этого я хендлы на буфер не делал...
                                                    По поводу заголовков у фреймов с броузерами можете подсказать?
                                                    Что конкретно интересует по фреймам ?
                                                    Фрейм с браузером должен иметь те же атрибуты, что и фрейм без браузера.

                                                    PS: По поводу ошибки при DELETE OBJECT , там может возникнуть ошибка если хэндл не валидный, например:
                                                    Код:
                                                    DEFINE VAR vTestHdl AS HANDLE.
                                                    DELETE OBJECT vTestHdl.
                                                    получаем: "Invalid or inappropriate handle value given ...".
                                                    Для исключения такой ошибки делаем так:
                                                    Код:
                                                    DEFINE VAR vTestHdl AS HANDLE.
                                                    IF VALID-HANDLE(vTestHdl) THEN DELETE OBJECT vTestHdl.

                                                    Комментарий


                                                    • #27
                                                      Код:
                                                      DEFINE VAR vTestHdl AS HANDLE.
                                                      IF VALID-HANDLE(vTestHdl) THEN DELETE OBJECT vTestHdl.
                                                      [/QUOTE]
                                                      Так и делал...
                                                      У нас получится оффтоп :как поменять заголовок фрейма(или броузера)?Каким реквизитом это делается?

                                                      Комментарий


                                                      • #28
                                                        Сообщение от kabysdox Посмотреть сообщение
                                                        ... как поменять заголовок фрейма(или броузера)?Каким реквизитом это делается?
                                                        Код:
                                                        DEFINE VAR vTest AS CHAR INIT "LOOK FOR TITLE" NO-UNDO.
                                                        FORM
                                                           vTest FORMAT "x(30)"
                                                        WITH FRAME TestFrame TITLE "[ Title1 ]" WIDTH 50.
                                                        
                                                        DISPLAY vTest WITH FRAME TestFrame.
                                                        PAUSE.
                                                        
                                                        FRAME TestFrame:TITLE = "[ Title2 ]".
                                                        
                                                        DISPLAY vTest WITH FRAME TestFrame.
                                                        PAUSE.
                                                        Видимо так.

                                                        Комментарий


                                                        • #29
                                                          Хахаха - это я знаю...
                                                          В броузерах вызываемых из УТ не могу поменять заголовок на тот,который хочу...

                                                          Комментарий


                                                          • #30
                                                            Сообщение от kabysdox Посмотреть сообщение
                                                            Хахаха - это я знаю...
                                                            В броузерах вызываемых из УТ не могу поменять заголовок на тот,который хочу...
                                                            Хахаха, впервые вижу, человек легко пишет на прогрессе, а в данном ему в комплекте коде поглядеть не может.

                                                            См. например, dps-op.p, в районе переменной vBrTtl, откуда она берётся и как применяется.

                                                            Кстати, повторю ещё раз. Всё, чем можно управлять браузером из УТ - это filter-table. В неё и только в неё смотрите.
                                                            /kiv

                                                            Комментарий

                                                            Пользователи, просматривающие эту тему

                                                            Свернуть

                                                            Присутствует 1. Участников: 0, гостей: 1.

                                                            Обработка...
                                                            X