Быстрая проверка в run-time

База знаний

Модераторы: m0p3e, edward_K, Модераторы

Ответить
galover
Местный житель
Сообщения: 794
Зарегистрирован: 16 ноя 2007, 13:52

Быстрая проверка в run-time

Сообщение galover »

Встала задача динамического создания интерфейсов в режиме выполнения. Поизучал возможности V4A. К сожалению, оказалось V4A не может создавать полноценные интерфейсы (с элементами управления, view и т.д.). Зато в качестве проверки простенького кода, к тому же без возни с компиляцией и ресурсами может быть очень даже полезен. В общем, тем, кого не устраивают встроенные возможности вычисления выражений (Ctrl+F4), может пригодиться.
Сам интерфейс выглядит следующим образом:
Изображение
Текст кода должен начинаться после ключевого слова begin.
Можно проверять выполнение функций, довольно полезно при отладке:
Изображение
Можно также (это наверное самое полезное) проверять работу объектного интерфейса:
Изображение
Код интерфейса довольно простой:

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

#component "Utils"

interface TestScript 'Тестирование V4A скриптов';
   show at (,, 90, 35);

   const
      csTestScriptMemoType = 501;
   end;
   
   File _memoFile;

   create view
   as select
      AllMemo.nRec
   from
      AllMemo
   where
   ((
      cox$Users            == AllMemo.wTable and
      UserId()             == AllMemo.cRec   and
      csTestScriptMemoType == AllMemo.Tip
   ));

   text AllMemo.Mem;
      show at(,,, 31);

   screen scrMain;
      show at(, 32,,) fixed_Y;
      noTableNavigation;

      buttons
         cmRunScript;
<<

                                                                          <. Выполнить .>
>>
   end

   tableEvent table AllMemo;
      cmUpdateRecord:
      {
         update current AllMemo;
      }
   end;
   
   private procedure RunScript;
   {      
      if (not _memoFile.OpenMemo(AllMemo.Mem))
         exit;
      
      if (_memoFile.GetSize() <> 0)
      {  
         var scrNumber : longint;      
         scrNumber := vaGetFreeHandle();
         
         vaAddStr(scrNumber, 'script __TestScript;'); // Добавляем имя скрипта
      
         var wasScrEnd : boolean; // Признак наличия завершающего тега скрипта -> .end
         wasScrEnd := false;
      
         _memoFile.Seek(0); 

         while(not _memoFile.EOF())
         {
            var str : string;   

            _memoFile.ReadLn(str);
            vaAddStr(scrNumber, str);
         
            if (InStr('end.', str) > 0)
               wasScrEnd := true;
         }

         if (not wasScrEnd)
            vaAddStr(scrNumber, 'end.'); // Добавляем завершающий тег скрипта
 
         var scrHandle : longint;      
      
         scrHandle := vaCompile(scrNumber);
         vaFreeSource(scrNumber);

         if (scrHandle <> -1)
         {
            var res : void;

            vaExecute(scrHandle, res);
            vaFree(scrHandle);         
         }
         else
         {
            Message(vaErrorText(), Error);       
         }
      }
      
      _memoFile.Close();
   }

   handleEvent
	   cmRunScript:
      {
         RunScript();
      }
      cmInit:
      {
         if (getfirst fastfirstrow AllMemo <> tsOk)
         {
            ClearBuffer(#AllMemo);
            AllMemo.Name := 'Проверка тестового скрипта';

            insert current AllMemo;
         }
      }
   end;
end.
В общем пока других значительных преимуществ V4A для себя не обнаружил. Ну еще как вариант вижу возможность использования в качестве инструмента создания плагинов без внешнего представления, т.е. что-то получить от внешнего окружения, выполнить и вернуть результат. Идея в общем неплохая, но без полноценной поддержки создания интерфейсов на лету, не то( Кто-нибудь вообще использует этот V4A?
LaaLaa

Re: Быстрая проверка в run-time

Сообщение LaaLaa »

Через V4A в Галактике сделаны алгоритмы начисления амортизации ОС/НМА.
Vik
Местный житель
Сообщения: 370
Зарегистрирован: 28 сен 2006, 15:43
Откуда: Санкт-Петербург
Контактная информация:

Re: Быстрая проверка в run-time

Сообщение Vik »

Мы использовали эти скрипты в планировании производства при написании алгоритма установки времени пролеживания операций.
Алгоритм этот постоянно менялся, поэтому, чтобы не переписывать его, сделали точку входа в определенном месте, оставили возможность менять код, отвечающий за возврат значения, используя заранее определенные переменные. Получилось достаточно удобно.
Dmitry_Sol
Постоянный гость
Сообщения: 76
Зарегистрирован: 07 июн 2007, 12:32
Откуда: Витебск
Контактная информация:

Re: Быстрая проверка в run-time

Сообщение Dmitry_Sol »

Возможно ли использование в этом механизме - работы с физическими таблицами,
например create view?
или record as table persons;

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

begin
 type trecperson = record as table persons with x$position;
 var buf:trecperson;
 buf:=Trecperson(buf)
 Message('Hello'+buf.nrec)
Написал так. Вроде не ругается. Теперь непонятно. как считать запись в persons по определенному нрек.

Гуру помогите пожалуйста :-?
galover
Местный житель
Сообщения: 794
Зарегистрирован: 16 ноя 2007, 13:52

Re: Быстрая проверка в run-time

Сообщение galover »

Почитай в vipprogr.chm раздел Скрипты V4A (Vip For Application). Там немного и доступно. view объявлять нельзя (есть запрет на интерфейсы). Сам скрипт будет видеть лишь переменные (встроенных типов), описанные в главной view, родительского фейса.
Прогнал дезу про видимость view родительского фейса из скрипта. Там все сложней :( Чтобы читать таблицу в скрипте, нужно получить ее объектную оболочку (например, утилитой tbl2obj из поставки Атлантиса) и уже затем инициализировать в самом скрипте.
galover
Местный житель
Сообщения: 794
Зарегистрирован: 16 ноя 2007, 13:52

Re: Быстрая проверка в run-time

Сообщение galover »

Погонял еще чуть-чуть этот V4A. Разочаровался окончательно - то ли сырой, то ли непродуманный, то ли я не понял мощной задумки разработчиков. Столько приседаний нужно сделать, чтобы элементарно прочитать что-то из таблицы, не говоря уже о том, что операторы модификации данных (update/insert/delete) просто не поддерживаются V4A, т.е. скрипты могут быть только на чтение данных.
Чтобы немного облегчить использование интерфейса, дополнил функционал возможностью чтения таблиц (без гемороя с генерацией табличных оберток - obj и vip интерфейсов). Теперь в коде скрипта можно написать так:

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

begin
  #InitTable(Имя_таблицы, Имя__табличной_переменной) // Объявляем переменную на объектный-интерфейс (обертку над таблицей)
  
 _loop Имя_переменной
 {
    чтение свойств табличной_переменной
 }
 
 getfirst | getnext | getlast | getprev табличной_переменной
Пример чтения таблицы договоров
Изображение
Сами обертки таблиц компилируется вместе с вызывающим скрипт интерфейсом (генерировал с помощью утилиты Tbl2obj). Не на все таблицы получилось сделать обертку. Tbl2obj не умеет генерировать код для таблиц, с отсутствующим суррогатным ключом. Список таблиц, которые не получится использовать в скрипте (если конечно не написать обертку ручками):

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

ACTIVEMODULES
ACTSALDO
ADDPICKR
AGGREGATE
ALIMENTV
ANKAUND
ANKAUNS
AQACHECKFUNCS
AQACHECKPOINTS
AQAFIELDLIST
AVTOPUT
AVTOVED
BIGHEAP
BUILD_RT
BWPCARD
CHILDOPL
CHILDVOZ
CONVZ
CURLS
CURLS1
CURLSCHET
D$RELATE
DAYUCH
DAYUCH51
DELTAVAL
EXPSETDTO
FORMARKS
FORPRINT
FPADDFLD
FPBUDOUT
FPKOEFF
FPLOCKDATA
GETSALDO
GROUPOBPLM
HIERZAR
INTCLSTS
ITERKOLM
JOBTARF
JOBTARIF
KATEGOV
KLPRPER
KODHEAP
KOLDOG
KOLGROUPM
KOLMC
LIMZAMM
MFORREP
MOVCUT
MOVLINK
MOVSALDO
NACHTMP
NONALMC
OBORPICK
OBORSTR
OBORSUB1
OBSUBSCH
OBVALUT
PARLINKOPM
PARPRICE
PCKPRCUS
PEAKENTRY
PICK
PICKENUM
PICKMTR
PICKOE
PICKPRIC
PICKRECE
PICKVIP
PICKVIP2
PICKVIP3
PICKVIP4
PICKVIP5
PLANINFO
POSTPOTR
PREMOVE
PREREAL
PRIORRASM
PRITTMP
PRITTMP1
PRNCAPPR
PROFTMP
PRVIDTMP
PRVTMP
PUSTDATA
PUSTOGR
RAS_ORD
RELIEFE
REMARXZD
REPCPR
REPHSOPR
RESITERM
ROTG_R01
ROUTERS
RSVREG
SAVEPICK
SAVEVED
SAVEVEDD
SAVPRC
SEESALDO
SI_RELATE2
SI_XFIELDS2
SI_XFILES2
SI_XINDEXES2
SPBUHREP
SPCHECK
SPRASVSP
SPSPLIMOSTM
SUMDOG
SUPPL
SVODTMP
SYSTEMCOMPONENTS
TABLTMP
TBACKG
TDOOC
TEMPDB
TEMPGS
TEMPIER
TEMPKOL
TEMPKR
TEMPNO
TEMPNO2
TEMPOP
TEMPPART
TEMPRCONS
TEMPTXO
TMP12
TMP12PR
TMPAVLINFOM
TMPDOOC
TMPGRN
TMPKAUPRED
TMPREEN
TMPSALDO2
TMPSALDO3
TMPSKLMOL
TMPSPNAL
TMPSPORD
TMP_PLVED
TMP_POMETKI
TMP_SOPR
TMP_TAB
TMP_TABN
TMP_ZN1
TMP_ZN2
TNALF
TREESPEC
TREESUMS
VALCAP
VDETAIL
VEDGROUP
VEDSB
VENTFLD
VIDKAUOS
VIDKAUPR
VLOCKS
VROPERM
VUSERFLT
X$ATTR
X$FIELDS
X$FILES
X$INDEXES
X$OBJREL
X$OBJTAB
X$REGISTERTABLES
X$RELATE
X$SEMAFORS
X$SURRKEYS
ZAR_USER
ZKAUVED
В качестве основного минуса - долгая компиляция интерфейса (не скриптов) и размер выходного ресурсника (около 17 Мб), включающего свыше 2 тысяч объектных интерфейсов. Если компилить влом, то готовый ресурсник можно взять по ссылке.
Исходники и ресурс (собирал 5.4.35): http://ifolder.ru/23655950
galover
Местный житель
Сообщения: 794
Зарегистрирован: 16 ноя 2007, 13:52

Re: Быстрая проверка в run-time

Сообщение galover »

upd Нашел таки способ обновлять данные в скрипте. Для облегчения, добавил новые макроопределения:
InsertCurrent
UpdateCurrent
DeleteCurrent
RecordsInTable
Теперь можно писать так:
Изображение
Думаю для одноразовых изменений БД, без возни с компиляцией и ресурсами, может пригодиться. Обновленный код http://ifolder.ru/23703319
Ответить