Operlog. Проводки. Транзакции.

Автор:григ
Дата:23.01.2002
Просмотров:5740
Скачиваний:1003
Оценка:, Оценок - 3
Скачать (ARJ-файл; Размер - 7774)

Обсудить в форуме

Описание

В связи с некоторыми случаями "криков" оперов: "я документ проводила, а он пропал, а я ничего не делала" (на самом деле сама же удалила), пришлось сделать свою примочку для работы с operlog.dbt, т.к. стандартная в 5.0 очень тупо задает фильтр по дате (не по ключу, а методом перебора - поседеешь, пока дождешься). Примочка помимо всего прочего позволяет перекинуть документ в отложенные, а также вывести распечатку в ёксель. Для работы нужен промежуточный рабочий файл следующей структуры:
0, Number, Long - номер поля
1, Name, String, 25 - имя поля
2, ValueBefore, String 251 - значение поля до изменения
3, ValueAfter, String, 251 - значение поле после изменения
Ключ 0 по Number.
Еще в примерчике реализован простенький, но гибкий механизм, по наложению заранее неизвестной стуктуры на переменную часть записи.

Текст примера

 /*DTB.D32: Конструктор форм. Луппов Г.Б., Крысов Ю.А.*/
/*operlog.dbt - транзакции и проводки*/
import dtb,BankInter,rslx,lgxs,doctor,"excel.mac";
 array op,tt,
  fn,  /*названия полей*/
  fv1, /*значения до операции*/
  fv2, /*значения после операции*/
  fd,  /*названия групп документов*/
  fdn; /*названия файлов документов*/

 file opl (operlog) key 0;
 file post (postdoc) write key 0;
 {recid}=null;

 {dbfile}=GetInIString("DATABASEDIR")+"\\OCB\\";
 {workdir}=GetInIString("WORKDIR")+"\\";

 op(0)="Все";
 op(1)="Ввод";
 op(2)="Изменение";
 op(3)="Удаление";
 {base}=1004;  

 fd(0)="Все файлы";             fdn(0)="";
 fd(1)="~Ввести имя файла~";    fdn(1)="";
 fd(2)="Проведенные документы"; fdn(2)="document.dbt";
 fd(3)="Архивные документы";    fdn(3)="arhdoc.dbt";
 fd(4)="Картотека N 2";         fdn(4)="index2.dbt";
 fd(5)="Отложенные документы";  fdn(5)="postdoc.dbt";

 {do}={curdate};
 {op}=0;
 {opr}=0;
 {file}="";

 List1=TlgList("Oper");
 List2=TlgList("Operation");
 List3=TlgList("File");

 ol=TlgFile("operlog.dbt");
  res=ol.Open;
  if(not res) MsgBox("Не могу открыть файл!","operlog.dbt"); exit(1); end;
  ol.First();
  olbdDateRec=ol.AddField("bdDateRec");
  olbtTimeRec=ol.AddField("btTimeRec");
  oliOper=ol.AddField("iOper");
  oliOperation=ol.AddField("iOperation");
  olszFileName=ol.AddField("szFileName");
  olOperation=ol.AddField("Operation"); olOperation.UserCalculated="GetOperation";
   macro GetOperation(obj)
    Value="";
    a=oliOperation.Value-{base};
    if((a>=0) and (a<3))
     Value=op(a+1);
    end;
    obj.Value=Value;
   end;

 FORM1=TjkForm("FORM1");
  FORM1.ColorSchem=5;
  FORM1.Status="~ESC~выход ~ENTER~документ ~F2~в отложенные ~F4~поиск ~F5~фильтр ~F7~отчет";
  FORM1.Title="Транзакции (проводки)";
  FORM1.Width=50;

 Grid0=FORM1.AddGrid(20);
  Grid0.Border=1;
  Grid0.Name="Grid0";
  Grid0.Titles=True;
  Grid0.VScrollBar=True;
  Grid0.HScrollBar=True;
  Grid0.Width=48;
  Grid0.Y=2;

 EDITG0=Grid0.AddField(olbdDateRec);
  EDITG0.Name="EDITG0";
  EDITG0.TitleLabel="Дата";

 EDITG1=Grid0.AddField(olbtTimeRec);
  EDITG1.Name="EDITG1";
  EDITG1.TitleLabel="Время";
  EDITG1.Width=8;

 EDITG2=Grid0.AddField(oliOper);
  EDITG2.Name="EDITG2";
  EDITG2.TitleLabel="Опер";
  EDITG2.Width=4;

 EDITG3=Grid0.AddField(olOperation);
  EDITG3.Name="EDITG3";
  EDITG3.TitleLabel="Операция";

 EDITG4=Grid0.AddField(olszFileName);
  EDITG4.Name="EDITG4";
  EDITG4.TitleLabel="Файл";
  EDITG4.Width=12;

 /*Форма - расшифровка операции*/
 ff=TlgFile("fields.dbt",{dbfile}+"dtb_ocb.def");
  ffNumber=ff.AddField("Number");
  ffName=ff.AddField("Name");
  ffValueBefore=ff.AddField("ValueBefore");
  ffValueAfter=ff.AddField("ValueAfter");
  res=ff.Open(0,0,{dbfile}+"fields.dbt");
  if(not res) MsgBox("Не могу открыть файл!",{dbfile}+"fields.dbt"); exit(1); end;
  ff.Clone({workdir}+string(UserNumber)+".dbt",0,0);
  ff.First();

 FORM2=TjkForm("FORM2");
  FORM2.ColorSchem=6;
  FORM2.Status="~ESC~выход";
  FORM2.Title="Расшифровка операции";

 Grid0=FORM2.AddGrid(18);
  Grid0.Border=1;
  Grid0.Titles=True;
  Grid0.VScrollBar=True;
  Grid0.Width=78;
  Grid0.Y=2;

 EDITG0=Grid0.AddField(ffName);
  EDITG0.Color=48;
  EDITG0.CursorColor=31;
  EDITG0.Name="EDITG0";
  EDITG0.TitleLabel="Название поля";
  EDITG0.Width=24;

 EDITG1=Grid0.AddField(ffValueBefore);
  EDITG1.Color=48;
  EDITG1.CursorColor=31;
  EDITG1.Cursor=True;
  EDITG1.Name="EDITG1";
  EDITG1.TitleLabel="Значение до операции";
  EDITG1.Length=250;
  EDITG1.Width=26;

 EDITG2=Grid0.AddField(ffValueAfter);
  EDITG2.Color=48;
  EDITG2.CursorColor=31;
  EDITG2.Cursor=True;
  EDITG2.Name="EDITG2";
  EDITG2.TitleLabel="Значение после операции";
  EDITG2.Length=250;
  EDITG2.Width=26;
  EDITG2.OnDraw="OnDraw";

 Edit0=FORM2.AddEdit(ffValueBefore);
  Edit0.Color=48;
  Edit0.CursorColor=31;
  Edit0.Name="Edit0";
  Edit0.TabStop=False;
  Edit0.X=0;
  Edit0.Y=21;
  Edit0.Length=250;
  Edit0.Width=80;

 Edit1=FORM2.AddEdit(ffValueAfter);
  Edit1.Color=48;
  Edit1.CursorColor=31;
  Edit1.Name="Edit1";
  Edit1.TabStop=False;
  Edit1.X=0;
  Edit1.Y=22;
  Edit1.Length=250;
  Edit1.Width=80;

 /***********************************************/
 /*Поиск перебором*/
 macro f_search(id,field,len)
  if(valtype(len)!=V_INTEGER) len=30; end;
  if((len<=0) or (len>76)) len=76; end;
  if(id.empty) return false; end;
  obr=field.Value;
  vtype=valtype(obr);
  t="Образец поиска";
  if(vtype==V_INTEGER)
   if(GetInt(obr,t)) else return false; end;
  elif(vtype==V_STRING)
   if(GetString(obr,t,len)) else return false; end;
   obr=StrUpr(obr);
  elif(vtype==V_DOUBLE)
   if(GetDouble(obr,t)) else return false; end;
  elif(vtype==V_MONEY)
   if(GetMoney(obr,t)) else return false; end;
  elif(vtype==V_DOUBLEL)
   if(GetDouble(obr,t)) else return false; end;
   obr=doubleL(obr);
  elif(vtype==V_MONEYL)
   if(GetMoney(obr,t)) else return false; end;
   obr=moneyL(obr);
  end;

     connect=id.Connect; id.Connect=false;
     nrec=id.GetPos; cont=true; find=false;
     if(id.Next!=1) id.First; end;
     while(cont)
      if(id.GetPos==nrec) cont=false;
      else
       if(((vtype==V_STRING) and (index(StrUpr(field.Value),obr)>0)) or ((vtype!=V_STRING) and (obr==field.Value)))
        find=true; cont=false;
       else
        if(id.Next!=1) id.First; end;
       end;
      end;
     end;
     id.Connect=connect;
     return find;
 end;

 macro f1_f4(Sender,Key)
  field=Sender.Field(Sender.iCol).SourceField;
  id=Sender.Field(0).SourceField.SourceFile;
  if(id.empty) return; end;
  if(f_search(id,field,Sender.Field(Sender.iCol).Width)) Sender.Refresh; end;
 end;

 /*удалить все узлы списка*/
 macro f_DeleteAll(obj)
  len=obj.Size; i=0;
  while(i<len)
    obj.Del(0);
   i=i+1;
  end;
 end;

 /*заполнить вспомогательный файлик данными*/
 macro f_Fill(id)
  {recid}=id;
  connect=ff.Connect; ff.Connect=false;
  ff.Clone;
  GetDirect(opl,ol.GetPos);
  SetRecordAddr(id,opl);
  i=0; len=FldNumber(id);
  while(i<len)
   ffNumber.Set(i);
   ffName.Set(FldName(id,i));
   if((oliOperation.Value==1004) or (oliOperation.Value==1005))
    ffValueAfter.Set(string(id(i)));
   elif(oliOperation.Value==1006) 
    ffValueBefore.Set(string(id(i)));
   end;
   ff.insert;
   i=i+1;
  end;

  if(oliOperation.Value==1005)
   ff.First;
   SetRecordAddr(id,opl,1);
   i=0;
   while(not ff.eof)
    ffValueBefore.Set(string(id(i)));
    ff.update; ff.next;
    i=i+1;
   end;
  end;
  ff.first;
  ff.Connect=connect;
 end;

 /*копирование в отложенные*/
 macro f_Post(id)
  GetDirect(opl,ol.GetPos);
  if(oliOperation.Value==1005)
   SetRecordAddr(id,opl,1);
  else
   SetRecordAddr(id,opl);
  end;
  copy(post,id);
  insert(post);
 end;

 /*сгенерить макрофайлик и вызвать его*/
 macro f_macro(nameproc)
  namef={workdir}+string(UserNumber)+".mac";
  SetOutPut(namef);
  println("record rec(\""+olszFileName.Value+"\");");
  println("macro Main(nameproc)");
  println(" execmacro(nameproc,rec);");
  println("end;");
  SetOutPut(Null);
  ExecMacroFile(namef,"Main",nameproc);
 end;

 /*расшифровка операции на экране*/
 macro f_enter(Sender,Key)
  f_macro("f_Fill");
  Form2.Show;
 end;

 /*Скопировать в отложенные*/
 macro f1_f2(Sender,Key)
  f_macro("f_Post");
  MsgBox("Документ скопирован в отложенные!");
 end;

 /******************************Вывод в Excel*****************************/
 macro f_f7(obj)

  macro f_gety(i)
   t=""; i=i-1;
   while(i>25)
    t=StrFor(i-int(i/26)*26+65)+t;
    i=int(i/26)-1;
   end;
   return StrFor(i+65)+t;
  end;
  /**/
  macro f_getxy(y,x)
   return (f_gety(y)+string(x));
  end;

  message("Вывод отчета в Excel...");

  if(IsStandAlone()) ob=ActiveX("Excel.Application",null,true);
  else ob=TlgActiveX("Excel.Application",true); end;

time1=time;
lgSetAnswer(2);
  /*вывод на экран*/
  ob.Visible=true;

  ob.Workbooks.Add;
  sheet1=ob.Sheets(1);

   /*шапка*/
   macro f_zag(x,y)
    Value=null; i=0;
    while(GetParm(i+2,Value) and (valtype(Value)!=V_UNDEF))
     ob1=sheet1.cells(y,x+i);
     vtype=valtype(Value);
     if((vtype==V_DOUBLE) or (vtype==V_DOUBLEL) or (vtype==V_MONEY) or (vtype==V_MONEYL))
      ob1.NumberFormat="# ##0,00";
     end;
     ob1.HorizontalAlignment=xlCenter; ob1.Font.Bold=true;
     ob1.Value=Value;
     i=i+1;
    end;
   end;

   /*строка*/
   macro f_str(x,y)
    Value=null; i=0;
    while(GetParm(i+2,Value) and (valtype(Value)!=V_UNDEF))
     ob1=sheet1.cells(y,x+i);
     vtype=valtype(Value);
     if((vtype==V_DOUBLE) or (vtype==V_DOUBLEL) or (vtype==V_MONEY) or (vtype==V_MONEYL))
      ob1.NumberFormat="# ##0,00";
     end;
     ob1.Value=Value;
     i=i+1;
    end;
   end;

  /*Формат ячеек*/
  y=4; fontsize=8; delx=5; x=1;
  prom=f_gety(1); prom1=f_gety(delx);
  ob1=sheet1.Columns(prom+":"+prom1); ob1.NumberFormat="@"; ob1.Font.Size=fontsize;

  /*заголовок*/
  ob1=sheet1.cells(1,1); ob1.Value={Name_Bank};
  ob1=sheet1.cells(2,1); ob1.Value="Список транзакций за "+string({do});

  connect1=ol.Connect; ol.Connect=false;
  connect2=ff.Connect; ff.Connect=false;

  /*шапка таблицы*/
  j=0; InitProgress(ol.nrecords,NULL,"Вывод отчета в Excel");
  ol.first;
  while(not ol.eof)
   f_zag(x,y,"Дата","Время","Опер","Операция","Файл"); y=y+1;
   f_str(x,y,string(olbdDateRec.Value),string(olbtTimeRec.Value),oliOper.Value,olOperation.Value,olszFileName.Value); y=y+1;
   f_macro("f_Fill");
   f_zag(x+1,y,"Название поля","Значение до операции","Значение после операции"); y=y+1;
   ff.First;
   while(not ff.eof)
    t="";
    if((oliOperation.Value==1005) and (ffValueBefore.Value!=ffValueAfter.Value))
     t="X";
    end;
    f_str(x+1,y,ffName.Value,ffValueBefore.Value,ffValueAfter.Value,t); y=y+1;
    ff.next;
   end;
   y=y+1;

   ol.next; j=j+1; UseProgress(j);
  end;                            
  RemProgress;

  lgSetAnswer(0);
  lgSendQueue();
time2=time;
/*MsgBox(time1," ",time2);*/

  /*Автоподбор ширины*/
  prom=f_gety(1);
  ob1=sheet1.Columns(prom+":"+prom); ob1.ColumnWidth=9.14;
  prom=f_gety(2);
  ob1=sheet1.Columns(prom+":"+prom); ob1.AutoFit;
  prom=f_gety(3);
  ob1=sheet1.Columns(prom+":"+prom); ob1.ColumnWidth=40; ob1.WrapText=true;
  prom=f_gety(4);
  ob1=sheet1.Columns(prom+":"+prom); ob1.ColumnWidth=40; ob1.WrapText=true;
  prom=f_gety(5);
  ob1=sheet1.Columns(prom+":"+prom); ob1.AutoFit;

  t=f_getxy(1,4)+":"+f_getxy(x+delx-1,y-2);
  ob1=ob.Range(t); ob1.Borders.LineStyle=1;

/*
 /*Установки для печати*/
 t="A1:"+f_gety(delx)+string(y);
 sheet1.PageSetup.PrintArea = t;
 sheet1.PageSetup.LeftMargin = ob.InchesToPoints(0.3);
 sheet1.PageSetup.RightMargin = ob.InchesToPoints(0);
 sheet1.PageSetup.TopMargin = ob.InchesToPoints(0);
 sheet1.PageSetup.BottomMargin = ob.InchesToPoints(0);
 sheet1.PageSetup.HeaderMargin = ob.InchesToPoints(0);
 sheet1.PageSetup.FooterMargin = ob.InchesToPoints(0);
 sheet1.PageSetup.Orientation = xlLandscape;
 sheet1.PageSetup.Zoom = false;
 sheet1.PageSetup.FitToPagesWide = 1;
 sheet1.PageSetup.FitToPagesTall = 1;
*/

  ol.Connect=connect1;
  ff.Connect=connect2;
  ol.First;
  obj.Refresh;
  message(obj.Owner.Status);
 end;

 /*Выбор файла*/
 macro f_choicef()
  t="";
  nm=menu(fd,"","Файл");
  if(nm==1)
   if(GetString(t,"Введите имя файла")) else t=""; end;
  else t=fdn(nm);
  end;           
  return t;
 end;

 /*Фильтрация*/
 macro f1_f5(Sender,Key)
  array tt;
  tt(0)="Фильтр по дате";
  tt(1)="Фильтр по операционисту";
  tt(2)="Фильтр по операции";
  tt(3)="Фильтр по файлу";
  nm=menu(tt);
  if(nm<0) return; end;
  if(nm==0)
   if(GetDate({do},"За дату:")) else return; end;
   olbdDateRec.SetMinMax({do},{do});
  elif(nm==1)
   if(GetInt({opr},"Операционист")) else return; end;
   if({opr}>0)
    oliOper.SetMinMax({opr},{opr});
   else 
    oliOper.SetMinMax(1,0);
   end;
  elif(nm==2)
   {op}=menu(op);
   if({op}<0) return; end;
   if({op}==0) oliOperation.SetMinMax({base},{base}+2); end;
   if({op}>0)
    oliOperation.SetMinMax({op}+{base}-1,{op}+{base}-1);
   end;
  elif(nm==3)
   {file}=f_choicef();
   /*if(GetString({file},"Имя файла")) else exit(1); end;*/
   {file}=trim({file});
   if({file}>"") olszFileName.SetMinMax({file},{file});
   else olszFileName.SetMinMax(1,0);
   end;
  end;

  ol.First;
  Sender.Refresh;
 end;

 /*Накопить статистику*/
 macro f_stat()
  f_DeleteAll(List1);
  f_DeleteAll(List2);
  f_DeleteAll(List3);

  connect=ol.Connect; ol.Connect=false;
  i=0; InitProgress(ol.nrecords,null,"Накопление статистики...");
  ol.First;
  while(not ol.eof)

   value=string(oliOper.Value);
   node=List1.Get(value);
   if(valtype(node)==V_UNDEF)
    node=List1.Add(value,TlgList(),value);
   end;

   value=olOperation.Value;
   node1=node.Object.Get(Value);
   if(valtype(node1)==V_UNDEF)
    node1=node.Object.Add(value,TlgList(),value);
   end;
   node3=List2.Get(value);
   if(valtype(node3)==V_UNDEF)
    node3=List2.Add(value,0,value);
   end;
   node3.Object=node3.Object+1;

   value=olszFileName.Value;
   node2=node1.Object.Get(Value);
   if(valtype(node2)==V_UNDEF)
    node2=node1.Object.Add(value,0,value);
   end;
   node2.Object=node2.Object+1;
   node3=List3.Get(value);
   if(valtype(node3)==V_UNDEF)
    node3=List3.Add(value,0,value);
   end;
   node3.Object=node3.Object+1;

   node=null; node1=null; node2=null; node3=null;
   ol.Next; i=i+1; UseProgress(i);
  end;
  RemProgress;
  ol.First;
  ol.Connect=connect;
 end;
 /*Вывести статистику*/
 macro f_cf7(Sender,Key)
  macro f_gety(i)
   t=""; i=i-1;
   while(i>25)
    t=StrFor(i-int(i/26)*26+65)+t;
    i=int(i/26)-1;
   end;
   return StrFor(i+65)+t;
  end;
  /**/
  macro f_getxy(y,x)
   return (f_gety(y)+string(x));
  end;

  f_stat();
  List1.Sort; List2.Sort; List3.Sort;
  message("Вывод отчета в Excel...");

  if(IsStandAlone()) ob=ActiveX("Excel.Application",null,true);
  else ob=TlgActiveX("Excel.Application",true); end;

  time1=time;
  lgSetAnswer(2);
  /*вывод на экран*/
  ob.Visible=true;

  ob.Workbooks.Add;

  len=List1.Size; i=len-3;
  while(i>0) ob.Sheets.Add(); i=i-1; end;
  i=1; node=List1.GetFirstNode;
  while(i<=len)
   sheet1=ob.Sheets(i); sheet1.Name="Опер "+node.Name;

   y=1; x=1;
   prom=f_gety(x);
   ob1=sheet1.Columns(prom+":"+prom); ob1.ColumnWidth=12.30;
   x=x+1;
   node3=List2.GetFirstNode;
   while(valtype(node3)==V_GENOBJ)
    prom=f_gety(x);
    ob1=sheet1.Columns(prom+":"+prom); ob1.ColumnWidth=12.30;
    ob1=sheet1.cells(y,x); ob1.Value=node3.Name; x=x+1;
    node3=node3.GetNextNode;
   end;
   y=2; x=1;
   node3=List3.GetFirstNode;
   while(valtype(node3)==V_GENOBJ)
    ob1=sheet1.cells(y,x); ob1.Value=node3.Name; y=y+1;
    node3=node3.GetNextNode;
   end;

   node1=node.Object.GetFirstNode;
   while(valtype(node1)==V_GENOBJ)
    x=List2.NodeNumber(node1.Name)+2;
    node2=node1.Object.GetFirstNode;
    while(valtype(node2)==V_GENOBJ)
     y=List3.NodeNumber(node2.Name)+2;
/*println("x=",x," y=",y," ",node1.Name," ",node2.Name);*/
     ob1=sheet1.cells(y,x); ob1.Value=node2.Object;
     node2=node2.GetNextNode; 
    end;
    node1=node1.GetNextNode;
   end;
   
   i=i+1; node=node.GetNextNode;
  end;
  node=null; node1=null; node2=null; node3=null;

  lgSetAnswer(0);
  lgSendQueue();
  time2=time;
  message(Sender.Owner.Status);
 end;

 /***********************************************/


 /*обработка событий формы при нажатии клавиш*/
 macro FORM1_OnKey(Sender,Key)
  if(Key==13) execmacro("f_enter",Sender,Key);
  elif(key==316) execmacro("f1_f2",Sender,key);
  elif(key==318) execmacro("f1_f4",Sender,key);
  elif(key==319) execmacro("f1_f5",Sender,key);
  elif(key==321) execmacro("f_f7",Sender,key);
  elif(key==356) execmacro("f_cf7",Sender,key);
  end;
 end;

 /*обработка событий формы при нажатии клавиш*/
 macro FORM2_OnKey(Sender,Key)
 end;

 if(GetDate({do},"За дату:")) else exit(1); end;
 olbdDateRec.SetMinMax({do},{do});
 if(GetInt({opr},"Операционист")) else exit(1); end;
 if({opr}>0)
  oliOper.SetMinMax({opr},{opr});
 end;

 {op}=menu(op);
 if({op}<0) exit(1); end;
 if({op}==0) oliOperation.SetMinMax({base},{base}+2); end;
 if({op}>0)
  oliOperation.SetMinMax({op}+{base}-1,{op}+{base}-1);
 end;

 {file}=f_choicef();
/* if(GetString({file},"Имя файла")) else exit(1); end;*/
 {file}=trim({file});
 if({file}>"") olszFileName.SetMinMax({file},{file}); end;

 ol.ApplyRange;
 ol.First;

   macro OnDraw(Sender)
    if(oliOperation.Value==1005)
     if(ffValueBefore.Value!=ffValueAfter.Value)
      Sender.Color=EDITG1.Color/16*16+12;
     else
      Sender.Color=EDITG1.Color;
     end;
    end;
   end;

 FORM1.Show;

end;

Файл excel.mac содержит константы для Excel:
/*Константы для Excel*/
import "resource.mac";

CONST xlSolid=1, xlLigthDown=13, xlAutomatic=-4105,
      xlLeft=-4131, xlBottom=-4107, xlCenter=-4108, xlRight=-4152,
      xlUnderlineStyleNone=-4142, xlLandscape=2, xlPortrait=1,
      xlLightUp=14, xlLightHorizontal=11, xlLightVertical=12,
      xlDiagonalDown=5, xlDiagonalUp=6, xlEdgeLeft=7, xlEdgeTop=8,
      xlEdgeBottom=9, xlEdgeRight=10, xlContinuous=1, xlMedium=-4138,
      xlInsideVertical=11, xlInsideHorizontal=12, xlGeneral=1, xlTop=-4160,
      xlJustify=-4130, xlFill=5, xlCenterAcrossSelection=7, xlThin=2;

/*
 res=lgResUpdate("..\\mac","","lgx.ver");
 if(res!="") MsgBox(res); end;
*/
end;