Operlog. Проводки. Транзакции.
Скачать (ARJ-файл; Размер - 7774)Обсудить в форуме
Описание
В связи с некоторыми случаями "криков" оперов: "я документ проводила, а он пропал, а я ничего не делала" (на самом деле сама же удалила), пришлось сделать свою примочку для работы с operlog.dbt, т.к. стандартная в 5.0 очень тупо задает фильтр по дате (не по ключу, а методом перебора - поседеешь, пока дождешься). Примочка помимо всего прочего позволяет перекинуть документ в отложенные, а также вывести распечатку в ёксель. Для работы нужен промежуточный рабочий файл следующей структуры:
0, Number, Long - номер поля
1, Name, String, 25 - имя поля
2, ValueBefore, String 251 - значение поля до изменения
3, ValueAfter, String, 251 - значение поле после изменения
Ключ 0 по Number.
Еще в примерчике реализован простенький, но гибкий механизм, по наложению заранее неизвестной стуктуры на переменную часть записи.
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;