Пример подстановок по таблице.
Рассмотрим задачу расширения списка рабочих таблиц с Memo полем в vip коде основного интерфейса:
Код: Выделить всё
! Корм для Рефала
!
!
!
! 26.11.2010 CEH
const
cfpSDIWindow=1054;ColorMark=19;sci178InsPM=6959;cmSelectAll=1219;cmUnSelectAll=1220;cmMarkUnMark=1221;cmInvertAll=1222;ftLVar=14;cmProcessText=3000;cmRefC=3001;cmRefGo=3002;cmRefTr=3003;cmSF_ViewTable=3004;cmImportFileToMemo=3005;cmExportMemoToFile=3006;
cmCompressLevel=3035;cmShowAll=3036;cmHideAll=3106;
end;
table struct mTbl ""
(
nTbl : string[21] "Имя таблицы",
nFld : string[21] "Имя Memo поля",
nNrec: string[21] "Имя Nrec поля",
nT : byte "№ п/а таблицы"
)
with index
(
byNTbl = nTbl
);
!----------------------------------------------------------------------------
interface MemoTbl '' ('',,scInterface) EscClose, Cyan;
create view as select X$FIELDS.XE$NAME, XF$NAME, xf.XE$NAME, mTbl.*
from X$FIELDS, X$FILES, synonym X$FIELDS xf, mTbl
where((
root == X$FIELDS.XE$CODE and (byte(14) = X$FIELDS.XE$DATATYPE) and
X$FIELDS.XE$FILECODE == XF$CODE and
X$FIELDS.XE$FILECODE == xf.XE$FILECODE and
word(ftLVar) == xf.XE$CODE and
XF$NAME == nTbl
));
handleEvent
cmInit: begin
if( getFirst X$FIELDS = 0 )
do {
nTbl:=XF$NAME; nFld:=X$FIELDS.XE$NAME; nNrec:=xf.XE$NAME;
if( insert current mTbl = 0 ) {};
} while getNext X$FIELDS = 0;
abort;
end;
end;
end.
!----------------------------------------------------------------------------
interface Ref5 'refc+refgo' ('компиляции компиляции компиляции ... :)',,scInterface) EscClose, Cyan;
show at (0,0,64,24);
var
iDict,cI:byte;
n:array [0..127] of comp;
nI,m:array [1..127] of byte;
ref5Prog,inTxtFile,outTxtFile,refGoModulParams,refGoArgParams,refGoArgParams2:string;
batch,commit:word;
MarkerNT,IndexNT:longint;
Marker_ALGCALC,Index_ALGCALC:longint;
Marker_ALGCALCTMPL,Index_ALGCALCTMPL:longint;
function selectMarker(x:byte):longint;
begin
selectMarker:=bcase(x=0:0
,x=1:Marker_ALGCALC
,x=2:Marker_ALGCALCTMPL
);
end;
create view as
select nI[nT](FieldName=nInT)
,if(SearchMarker(MarkerNT,mTbl.nT,IndexNT),'+',' ')(FieldName=picked)
,GetMarkerCount(selectMarker(nT))(FieldName=ins)
,if(SearchMarker(Marker_ALGCALC,ALGCALC.NREC,Index_ALGCALC),'+',' ')(FieldName=picked_ALGCALC)
,if(SearchMarker(Marker_ALGCALCTMPL,ALGCALCTMPL.NREC,Index_ALGCALCTMPL),'+',' ')(FieldName=picked_ALGCALCTMPL)
,*
from
mTbl
,ALGCALC
,ALGCALCTMPL
where((
root==mTbl.nTbl
and n[1]==ALGCALC.NREC
and n[2]==ALGCALCTMPL.NREC
));
parameters iDict;
File Dict,Memo;
browse brwRef5 ' ' ('',,sci178InsPM);
show at (,,,3);
table mTbl;
fields { font = { bold = (nI[nT]>0); color = if(picked='+',ColorMark,0) } };
nInT '№' : [2], Skip, Centered, NoAutoSize;
picked ' ' : [1], Skip, Centered, NoAutoSize;
ins 'ins' : [5], Skip, NoAutoSize;
nTbl 'таблицы' : [10], protect;
nFld 'поля' : [10], protect;
nNrec 'nrec' : [10], protect;
nT '№ п/а' : [4], protect;
end;
screen scrRef5 ' ';
show (,4,,11) fixed_y;
fields
ref5Prog : noProtect;
inTxtFile : noProtect;
outTxtFile : noProtect;
batch : noProtect;
commit : noProtect;
refGoModulParams : noProtect;
refGoArgParams : noProtect;
refGoArgParams2 : noProtect;
buttons
cmSF_ViewTable; cmProcessText; cmRefC; cmImportFileToMemo; cmExportMemoToFile; cmRefTr; cmRefGo;
<<
<. SF_ViewTable .>`-выбор записей в таблицах с Memo полем`
.@@@@@@@@@@@@@@@@`-.ref Рефал` `редактор-`<. ProcessText .>
`компилятор-`<. RefC .>
.@@@@@@@@@@@@@@@@ <. ImportFileToMemo .>
.@@@@@@@@@@@@@@@@ <. ExportMemoToFile .> [.] batch` [.] commit`
.@@@@@@@@@@@@@@@@`-mods` параметры `args-`.@@@@@@@@@@@.@@@@
<. RefTr .>`-tracer` `интерпретатор-`<. RefGo .>
>>
end;
screen m_nT ' ';
show (,12,,);
fields
<<
>>
end;
text memoID=m_ALGCALC ALGCALC.DESCRIPT ' ALGCALC' : noProtect; show (,12,,);
text memoID=m_ALGCALCTMPL ALGCALCTMPL.DESCRIPT ' ALGCALCTMPL' : noProtect; show (,12,,);
tableEvent table mTbl
cmPositionChanged: begin
if(GetMarkerCount(MarkerNT)=0) refGoArgParams:='('+nT+' 1)';
if(nI[nT]>0) SetFormat(-65535+nI[nT]+1)
else SetFormat(m_nT);
ReDrawPanel(0);
end;
cmSetDefault: begin abort; exit; end;
end;
function PictMarker:string;
begin
var i,b,c:byte;
var s:string;
s:=''; c:=0;
for(i:=1;i<=127;i:=i+1)
if(m[i]=0) { if(c>0) { s:=s+'('+b+' '+c+')'; c:=0; }
}else{ if(c=0) b:=m[i]; c:=c+1; };
if(c>0) s:=s+'('+b+' '+c+')';
PictMarker:=s;
end;
procedure loop_InsertMarker(x:byte);
begin
bcase(x=0:x:=0
,x=1:_loop ALGCALC InsertMarker(selectMarker(nT),ALGCALC.NREC);
,x=2:_loop ALGCALCTMPL InsertMarker(selectMarker(nT),ALGCALCTMPL.NREC);
);
end;
procedure loop_InvertMarker(x:byte);
begin
bcase(x=0:x:=0
,x=1:_loop ALGCALC InvertMarker(selectMarker(nT),ALGCALC.NREC);
,x=2:_loop ALGCALCTMPL InvertMarker(selectMarker(nT),ALGCALCTMPL.NREC);
);
end;
function expFileToMemo(x:byte):boolean;
begin
expFileToMemo:=bcase(x=0:x=0
,x=1:ExportMemoToFile(ALGCALC.DESCRIPT,outTxtFile,false)
,x=2:ExportMemoToFile(ALGCALCTMPL.DESCRIPT,outTxtFile,false)
);
end;
function impFileToMemo(x:byte):boolean;
begin
impFileToMemo:=bcase(x=0:x=0
,x=1:ImportFileToMemo(ALGCALC.DESCRIPT,inTxtFile,false)
,x=2:ImportFileToMemo(ALGCALCTMPL.DESCRIPT,inTxtFile,false)
);
end;
function getNextInsRecord(x:byte;c:comp):boolean;
begin
getNextInsRecord:=bcase(x=0:x=0
,x=1:getFirst ALGCALC where ((c==ALGCALC.NREC))=0
,x=2:getFirst ALGCALCTMPL where ((c==ALGCALCTMPL.NREC))=0
);
end;
function exitExec(var i,j:longint; var b:byte):boolean;
begin
var c:comp;
exitExec:=false;
if(GetMarker(selectMarker(b),j,c)) if(getNextInsRecord(b,c)) { j:=j+1; exitExec:=true; exit; };
SetBounds(nI[b]);
if(GetMarkerCount(MarkerNT)=0) { ReDrawPanel(nI[nT]); exit; };
var oldb:byte; oldb:=b;
while GetMarker(MarkerNT,i,b) { i:=i+1; if(nI[b]>0) break; }; if(b=oldb) { ReDrawPanel(CurFormatInArea(m_nT)+65535-1); exit; };
if(GetMarkerCount(selectMarker(b))>0) { j:=0; ReSetBounds(nI[b]);
if(GetMarker(selectMarker(b),j,c)) if(getNextInsRecord(b,c)) { j:=j+1; exitExec:=true; exit; };
};
end;
function initExec(var i,j:longint; var b:byte):boolean;
begin
var c:comp;
initExec:=false;
if(batch=0) { initExec:=true; exit; };
if(GetMarkerCount(MarkerNT)=0) { if(nI[nT]=0) exit; b:=nT;
}else{ i:=0; while GetMarker(MarkerNT,i,b) { i:=i+1; if(nI[b]>0) break; }; if(nI[b]=0) exit; };
if(GetMarkerCount(selectMarker(b))>0) { j:=0; ReSetBounds(nI[b]);
if(GetMarker(selectMarker(b),j,c)) if(getNextInsRecord(b,c)) { j:=j+1; initExec:=true; exit; };
};
end;
#declare MacroWinMemo(N,T,F,FN)
window win_#T '#T';
browse brw_#T ' ' ('',,sci178InsPM);
show at (,,20,);
table #T;
fields { font = { bold = (#T.#FN=n[#N]); color = if(picked_#T='+',ColorMark,0) } };
picked_#T ' ' : [1], Skip, Centered, NoAutoSize;
#T.#FN '#FN' : [10], protect;
end;
text memoID=mw_#T #T.#F ' #T' : noProtect;
show (21,,,);
tableEvent table #T
cmInsertRecord: begin abort; exit; end;
cmDeleteRecord: begin abort; exit; end;
cmUpdateRecord: begin update current #T; end;
cmSetDefault: begin abort; exit; end;
end;
handleEvent
cmInit: begin ReSetBounds(tn#T); end;
cmDefault: begin n[#N]:=#T.#FN; ReReadRecord(tn#T); end;
cmDone: begin SetBounds(tn#T); end;
cmSelectAll: begin
PushPos(tn#T); ClearMarker(Marker_#T);
_loop #T InsertMarker(Marker_#T,#T.#FN);
PopPos(tn#T); ReReadRecord(tn#T);
end;
cmUnSelectAll: begin
ClearMarker(Marker_#T);
ReReadRecord(tn#T);
end;
cmMarkUnMark: begin
if(SearchMarker(Marker_#T,#T.#FN,Index_#T)) DeleteMarker(Marker_#T,#T.#FN)
else InsertMarker(Marker_#T,#T.#FN);
RedrawCurrentAndGo(GetCurrentFormat,true);
end;
cmInvertAll: begin
PushPos(tn#T);
_loop #T InvertMarker(Marker_#T,#T.#FN);
PopPos(tn#T); ReReadRecord(tn#T);
end;
cmInsert: begin stop; exit; end;
cmDelete: begin stop; exit; end;
end;
end;
#end
#MacroWinMemo(1,ALGCALC,DESCRIPT,NREC)
#MacroWinMemo(2,ALGCALCTMPL,DESCRIPT,NREC)
function updateCurrentTable(x:byte):boolean;
begin
updateCurrentTable:=bcase(x=0:x=0
,x=1:update current ALGCALC=0
,x=2:update current ALGCALCTMPL=0
);
end;
handleEvent
cmInit: begin
var i,j:byte;
var str,s1,s2,s3,s4:string;
if(not ExistFile('dict.txt')) iDict:=1;
if(iDict=1) { Dict.OpenFile('dict.txt',stCreate);
RunInterface(MemoTbl);
i:=1;
if(getFirst mTbl=0)
do {
nT:=i; i:=i+1;
if(update current mTbl=0) { Dict.WriteLn(string(nT)+' '+nTbl+' '+nFld+' '+nNrec); };
} while getNext mTbl=0;
} else { Dict.OpenFile('dict.txt',stOpenRead);
do { Dict.ReadLn(str);
s1:=substr(str,1,Pos(' ',str)-1); str:=substr(str,length(s1)+2,255);
s2:=substr(str,1,Pos(' ',str)-1); str:=substr(str,length(s2)+2,255);
s3:=substr(str,1,Pos(' ',str)-1); str:=substr(str,length(s3)+2,255);
s4:=str;
nT:=s1; nTbl:=s2; nFld:=s3; nNrec:=s4;
if(insert current mTbl=0) {};
} while not Dict.EOF;
};
if( getFirst mTbl = 0 ) {};
Dict.Close;
MarkerNT:=InitMarker('Ref5',1,127,10,true);
i:=1;
nI[1]:=i; i:=i+1; Marker_ALGCALC:=InitMarker('Ref5_ALGCALC',8,100,10,true);
nI[2]:=i; i:=i+1; Marker_ALGCALCTMPL:=InitMarker('Ref5_ALGCALCTMPL',8,100,10,true);
cI:=1; for(i:=1;i<=127;i:=i+1) if(cI<nI[i]) cI:=nI[i]; cI:=cI+1;
if(not ReadMyDsk(m,'Ref5_m',false)) {i:=0; while GetMarker(MarkerNT,i,j) {i:=i+1; m[j]:=j; }; };
var cIc:byte;
if(not ReadMyDsk(cIc,'Ref5_cI',false)) cIc:=1;
if(cIc>cI) cIc:=1;
if(cIc>1) if(not ReadMyDsk(n,'Ref5_n',false)) cIc:=1;
for(i:=cIc;i<cI;i:=i+1) { j:=FindItem(nI,i);
ReSetBounds(nI[j]);
if(bcase(j=0:j=0
,j=1:getFirst ALGCALC=0
,j=2:getFirst ALGCALCTMPL=0
)) bcase(j=0:j:=0
,j=1:n[j]:=ALGCALC.NREC
,j=2:n[j]:=ALGCALCTMPL.NREC
) else n[j]:=0;
SetBounds(nI[j]);
};
if(not ReadMyDsk(ref5Prog,'Ref5_ref5Prog',false)) ref5Prog:='rev';
if(not ReadMyDsk(inTxtFile,'Ref5_inTxtFile',false)) inTxtFile:='input.txt';
if(not ReadMyDsk(outTxtFile,'Ref5_outTxtFile',false)) outTxtFile:='output.txt';
if(not ReadMyDsk(refGoModulParams,'Ref5_refGoModulParams',false)) refGoModulParams:='reflib -e';
ReadMyDsk(batch,'Ref5_batch',false);
ReadMyDsk(commit,'Ref5_commit',false);
if(GetMarkerCount(MarkerNT)=0) refGoArgParams:='(1 1)'
else refGoArgParams:=PictMarker; ReDrawPanel(0);
cIc:=cI-1;
refGoArgParams2:=FindItem(nI,cIc);
cfsSetProp('win_ALGCALC',cfpSDIWindow,true);
cfsSetProp('win_ALGCALCTMPL',cfpSDIWindow,true);
end;
cmDone: begin DoneMarker(MarkerNT,'Ref5');
DoneMarker(Marker_ALGCALC,'Ref5_ALGCALC');
DoneMarker(Marker_ALGCALCTMPL,'Ref5_ALGCALCTMPL');
SaveMyDsk(n,'Ref5_n');
SaveMyDsk(cI,'Ref5_cI');
SaveMyDsk(m,'Ref5_m');
SaveMyDsk(ref5Prog,'Ref5_ref5Prog');
SaveMyDsk(inTxtFile,'Ref5_inTxtFile');
SaveMyDsk(outTxtFile,'Ref5_outTxtFile');
SaveMyDsk(batch,'Ref5_batch')
SaveMyDsk(commit,'Ref5_commit')
SaveMyDsk(refGoModulParams,'Ref5_refGoModulParams');
end;
cmSelectAll: begin
PushPos(#mTbl);
ClearMarker(MarkerNT); SetLimit(m,0); SetLimit(m,127);
_loop mTbl { InsertMarker(MarkerNT,mTbl.nT); m[mTbl.nT]:=mTbl.nT; };
PopPos(#mTbl);
refGoArgParams:=PictMarker;
ReReadRecord(#mTbl);
end;
cmUnSelectAll: begin
ClearMarker(MarkerNT); SetLimit(m,0); SetLimit(m,127);
refGoArgParams:='('+nT+' 1)';
ReReadRecord(#mTbl);
end;
cmMarkUnMark: begin
if(SearchMarker(MarkerNT,mTbl.nT,IndexNT)) {
DeleteMarker(MarkerNT,mTbl.nT);
m[mTbl.nT]:=0;
}else{
InsertMarker(MarkerNT,mTbl.nT);
m[mTbl.nT]:=mTbl.nT;
};
refGoArgParams:=PictMarker;
ReDrawPanel(0);
end;
cmInvertAll: begin
PushPos(#mTbl);
_loop mTbl {
InvertMarker(MarkerNT,mTbl.nT);
m[mTbl.nT]:=if(m[mTbl.nT]=0,mTbl.nT,0);
};
PopPos(#mTbl);
refGoArgParams:=PictMarker;
ReReadRecord(#mTbl);
end;
cmShowAll: begin
PushPos(#mTbl);
_loop mTbl {
if((ni[nT]=0) or (not SearchMarker(MarkerNT,nT,IndexNT))) continue;
ClearMarker(selectMarker(nT));
ReSetBounds(nI[nT]);
loop_InsertMarker(nT);
SetBounds(nI[nT]);
};
PopPos(#mTbl);
ReReadRecord(#mTbl);
end;
cmHideAll: begin
PushPos(#mTbl);
_loop mTbl {
if((ni[nT]=0) or (not SearchMarker(MarkerNT,nT,IndexNT))) continue;
ClearMarker(selectMarker(nT));
};
PopPos(#mTbl);
ReReadRecord(#mTbl);
end;
cmCompressLevel: begin
PushPos(#mTbl);
_loop mTbl {
if((ni[nT]=0) or (not SearchMarker(MarkerNT,nT,IndexNT))) continue;
ReSetBounds(nI[nT]);
loop_InvertMarker(nT);
SetBounds(nI[nT]);
};
PopPos(#mTbl);
ReReadRecord(#mTbl);
end;
cmInsert: begin stop; exit; end;
cmDelete: begin stop; exit; end;
cmDefault: begin if(CurTable=#mTbl) if(nI[nT]=0) PutCommand(cmSF_ViewTable) else RunWindow(nI[nT]-1); end;
cmSF_ViewTable: begin
var c:comp;
c:=SF_ViewTable(nTbl,0);
if((c=0) or (nI[nT]=0)) exit;
n[nT]:=c;
ReReadRecord(nI[nT]);
end;
cmProcessText: begin
ProcessText(ref5Prog+'.ref',0,'');
end;
cmRefC: begin
var aErr:integer;
ExecProgram('refc.exe',ref5Prog,'',0,aErr);
end;
cmRefGo: begin
var aErr:integer;
var i,j,mSize:longint;
var b:byte;
if(initExec(i,j,b))
do {
if(batch<>0) {
if(not IsMemoText(nI[b])) continue;
if(not bcase(b=0:false
,b=1:Memo.OpenMemo(ALGCALC.DESCRIPT)
,b=2:Memo.OpenMemo(ALGCALCTMPL.DESCRIPT)
)) continue;
mSize:=Memo.GetSize;
Memo.Close;
if(mSize=0) continue;
expFileToMemo(b);
};
ExecProgram('refgo.exe',ref5Prog+'+'+refGoModulParams+' '+chr(34)+outTxtFile+chr(34)+' '+chr(34)+inTxtFile+chr(34)+' '+chr(34)+refGoArgParams+chr(34)+' '+refGoArgParams2,'',0,aErr);
if(batch=0) exit;
impFileToMemo(b);
if(commit<>0) if(updateCurrentTable(b)) {};
} while exitExec(i,j,b);
end;
cmRefTr: begin
var aErr:integer;
ExecProgram('reftr.exe',ref5Prog+'+'+refGoModulParams+' '+chr(34)+outTxtFile+chr(34)+' '+chr(34)+inTxtFile+chr(34)+' '+chr(34)+refGoArgParams+chr(34)+' '+refGoArgParams2,'',0,aErr);
end;
cmImportFileToMemo: begin
if(nI[nT]=0) exit;
impFileToMemo(nT);
if(commit<>0) if(updateCurrentTable(nT)) {};
ReDrawPanel(nI[nT]);
end;
cmExportMemoToFile: begin
if(nI[nT]=0) exit;
expFileToMemo(nT);
end;
end;
end.
!----------------------------------------------------------------------------
т.е. в коде:
добавить другие таблицы из (106) доступных.
Образцом будут различные встречающиеся комбинации из N[Номер по алфиту] T[Название таблицы] F[Название Memo поля] I[Название Nrec индекса], а входом строки интерфейса при построчном однопроходном просмотре.
По построению интерфейса создаётся словарь строк вида N T F I для (106) таблиц в файле dict.txt.
Используем его и перед обработкой считаем его и перед закапыванием в виде (N1 T1 F1 I1)(...) используем в качестве фильтра список добавляемых по [Insert] в интерфейсе таблиц в виде : (Начальный_номер_таблицы1 Количество_последовательных_таблиц1)(Начальный_номер_таблицы2 Количество_последовательных_таблиц2)(...).
При распознавании очередной строки интерфейса подставляем в цикле все варианты из выкопанного словаря, в противном случае просто выводим строку как есть. Всё:).
Пример использования - выбираем наш vip файл в текстовом поле по кнопке [Import]:
отметим, что при этом в базу реально уходит обновление (пользовать на свой страх и риск)
при этом поле аргумента автоматически изменяется в виде списка ()()()...
Теперь обратная задача - убрать некоторые таблицы. Ref файл для удаления - rmn.ref:
тут отличие только в том, что нужно знать номер по алфавиту последней добавленной ранее таблицы, смотрим её номер и вводим его в поле дополнительного аргумента, в нашем случае [25]:
Остаётся сохранить новый Ref5.vip и скомпилить его как обычно.