@ 0,0 say center('Банковские реквизиты контрагентов',80,.T.)
@ 24,0 say ' Enter-выбрать F5-добавить F4-изменить F8-пометить к удалению F2-сортировать '
set color to w/b,n/w
@ 1,0 clear to 23,79
@ 1,0 to 1,79 double
set cursor off
* выводим на просмотр записи о контрагентах для возможности модификации
declare f_list[3], h_list[3]
f_list[1] = 'if(deleted(),"*"," ")'
f_list[2] = 'sub_scet'
f_list[3] = 'left(kontragent,61)'
h_list[1] = ''
h_list[2] = 'Субсчет'
h_list[3] = 'Контрагент'
dbedit( 2, 0, 23, 79, f_list, 'KeyProc', '', h_list )
* записываем в файл RU.TXT строку,
* содержащую расчетный счет, МФО и название банка
memowrit( 'RU.TXT', RS+MFO+alltrim(Bank1)+' '+alltrim(Bank2) )
pack && удаляем помеченные к удалению записи
* функция обработки нажатий клавиш в dbedit()
function KeyProc
parameters mode, field_ptr
if mode < 4
return 1
endif
do case
case lastkey() = 13 && выбрать запись
return 0
case lastkey() = -4 && добавить запись
subscet = sub_scet && копируются код субсчета и
kontrag = kontragent && название субсчета текущей записи
append blank
replace sub_scet with subscet, kontragent with kontrag
do EditRecord && редактирование банковских реквизитов
return 2
case lastkey() = -1 && восстановление индексов
reindex && ох, капризные они у Clipper'а
return 2
case lastkey() = -3 && редактирование банковских реквизитов
do EditRecord
case lastkey() = -7 && пометить/снятьпометку
if deleted() && к удалению записи
recall
else
delete
endif
endcase
return 1
* редактирование полей "Расчетный счет", "МФО" и "Название банка"
procedure EditRecord
save screen
set color to n/bg
@ 24,0 say center('Insert-вставка/заменаУдаление: Del,Bs,Ctrl/T,Ctrl/Y',80,.T.)
set color to w/b,n/w
@ 1,0 clear to 23,79
@ 2,2 say 'Субсчет: ..... '+sub_scet
@ 4,2 say 'Контрагент ... '+left (kontragent,50)
@ 5,17 say right(kontragent,50)
@ 7,0 to 7,79
@ 9,2 say 'Расчетныйсчет ....' get RS
@ 11,2 say 'МФО ...............' get MFO
@ 13,2 say 'Банкполучателя ...' get Bank1
@ 14,2 say ' ' get Bank2
set cursor on
read
set cursor off
restore screen
Для использования программы необходимо штатными средствами обработки dbf-файлов создать файл BANK.DBF, включающий поля:
SUB_SCET - символьного типа, длина 9,
KONTRAG - символьного типа, длина 100,
RS - символьного типа, длина 11,
MFO - символьного типа, длина 10,
BANK1 - символьного типа, длина 50,
BANK2 - символьного типа, длина 50.
BANK.DBF должен быть проиндексирован по полю SUB_SCET. Имя индексного файла - BANK.NTX.
Программа получает от функции [ru ] в качестве параметра строку, заключенную в двойные кавычки (таковы правила СУБД Clipper), которая содержит код субсчета и его наименование, разделенные точкой с запятой.
Суть работы программы состоит в том, что она ищет в списке записей файла BANK.DBF запись, соответствующую субсчету, выбранному при регистрации операции в "Финансах без проблем". Если такой записи нет, то программа предлагает ввести банковские реквизиты контрагента.
Далее, в любом случае пользователю предлагается на выбор список сведений о контрагентах. Он может откорректировать любую запись, пометить запись к удалению или добавить новую. После нажатия на Enter, реквизиты выбранной записи объединяются в одну строку без всяких разделителей и записываются в файл RU.TXT, откуда их и "подбирает" функция [ru ].
Приведенная программа может использоваться во многих формах, требующих отражения банковских реквизитов. Мы приведем пример ее использования в форме печати платежного поручения. Скопируйте файл PLATEZKA.RPT из директории варианта стандартной поставки в директорию PROBA, переименуйте этот файл в PLAT_POR.RPT и внесите следующие изменения:
Теперь, измените листья ветви "Расчетный счет расход" дерева операций следующим образом:
Зарегистрируем операцию:
Выберите "Создать документ". В ответ на запрос файла-формы введите номер документа, например, 145. Стартовал BANK.EXE и не найдя записи, соответствующей субсчету 60-001 "ТОО Вега" предлагает нам ввести банковские реквизиты поставщика:
После ввода недостающей записи переходим к выбору. Здесь можно завести несколько записей, соответствующих одному контрагенту, изменить реквизиты того или иного контрагента, пометить ненужные записи к удалению:
После нажатия на Enter происходит возврат в "Финансы без проблем" и завершение формирования документа:
Использование функции [ru ] может оказаться достаточно полезным. "Финансы без проблем" написать тяжело, а небольшой "прибамбас" к ним на Клиппере или Бэйсике - не составляет особого труда.
Однако, не всегда функция [ru ] дает эффективное решение из-за потери времени на загрузку внешней программы и считывание файла RU.TXT. Особенно это касается случаев ее вызова из файлов-коэффициентов. Для преодоления этого затруднения в языке форм "Финансов без проблем" имеется функция [DLLcall ], позволяющая вызывать программы из DLL-библиотеки. Она имеет следующий формат:
[DLLcall library, index, data]
library - наименование библиотеки DLL,
index - номеp вызываемой пpоцедуpы в библиотеке,
data - стpока данных, пеpедаваемая в пpоцедуpу.
Вызываемая процедура должна поместить результат своей работы в передаваемую строку и DLLcall вернет ее в качестве своего значения.
С точки зрения вызываемой процедуры передаваемый параметр data является указателем на строку, завершающуюся нулевым байтом. Процедура должна вернуть результат в ту же строку, рассматривая ее как буфер из 128 байт. Возвращаемый результат также должен завершаться нулевым байтом. При этом значение строки data не изменяется, поскольку вызываемой процедуре передается адрес промежуточного буфера с копией значения строки data.
Рассмотрим пример, демонстрирующий возможности использования функции DLLcall для адаптации "Финансов без проблем" к национальным языкам.
Ниже приводятся исходные тексты PASCAL-программ библиотеки MOLDOVA, содержащей две экспортируемые процедуры. Первая осуществляет перевод числа в словесное представление, а вторая выдает название месяца по его номеру на молдавском языке:
{$A+,B-,D+,E+,F-,G-,I-,L+,N-,O-,P-,Q-,R-,S+,T-,V+,X+}
{$M 16384,0,0}
library MOLDOVA;
uses strings;
type Sex = (male,female);
Var Number : longint;
ER : integer;
Frase : string;
F : text;
Level : integer;
function StrNumS(R :longint; f :Sex) :string;
var N,L :longint; s :string;
const D0 :array [0..19] of string[20]
= ('','unu','doi','trei','patru','cinci','sase','sapte','opt',
'noua','zece','unsprezece','doisprezece','treisprezece',
'paisprezece','cincisprezece','sasesprezece','saptesprezece',
'optsprezece','nouasprezece');
D1 :array [1..9] of string[20]
= ('zece','douazeci','treizeci','patruzeci','cincizeci','saizeci',
'saptezeci','optzeci','nouazeci');
D2 :array [1..9] of string[20]
= ('o suta','doua sute','trei sute','patru sute','cinci sute',
'sase sute','sapte sute','opt sute','noua sute');
begin
inc(Level,1);
if R < 0 then StrNumS:='Minus '+ StrNumS(-R,f)
else if R = 0 then StrNumS:=''
else if R = 1 then
if Level=1 then
StrNumS:='un '
else
StrNumS:='unu '
else if R <= 19 then begin
StrNumS:=D0[R]+' ';
if f=female
then if R = 1 then StrNumS:='о'
else if R = 2 then StrNumS:='doua ';
end
else if R <= 99 then begin
if (R mod 10)<>0 then
StrNumS:=D1[R div 10] + ' si ' + StrNumS(R mod 10,f)
else
StrNumS:=D1[R div 10] + ' ' + StrNumS(R mod 10,f)
end
else if R <= 999 then StrNumS:=D2[R div 100] + ' ' + StrNumS(R mod 100,f)
else if R <= 1999 then begin
StrNumS:='o mie ' + StrNumS(R mod 1000,f);
end
else if R <= 2999 then begin
StrNumS:='doua mii ' + StrNumS(R mod 1000,f);
end
else if R <= 99999 then begin
L:=R div 1000;
N:=L mod 10;
s:='mii ';
if N = 1 then s:='mie ';
StrNumS:=StrNumS(L,female) + s +
StrNumS(R mod 1000,f);
end
else if R <= 999999 then begin
L:=R div 1000;
N:=L mod 10;
s:='de mii ';
StrNumS:=StrNumS(L,female) + s +
StrNumS(R mod 1000,f);
end
else if R <= 1999999
then begin
StrNumS:= 'un milion ' +
StrNumS(R mod 1000000,f);
end
else if R <= 2999999
then begin
StrNumS:= 'doua milioane ' +
StrNumS(R mod 1000000,f);
end
else if R <= 999999999
then begin
L:=R div 1000000;
N:=L mod 10;
s:='milioane ';
StrNumS:=StrNumS(L,male) + s +
StrNumS(R mod 1000000,f);
end
else if R <= 1999999999
then StrNumS:='un miliard ' +
StrNumS(R mod 1000000000,f)
else StrNumS:='****** N > 1,999,999,999 ******';
end;
procedure P(s :pChar); export;
var i,n :longint; c :integer;
q,t :string;
begin
q:=StrPas(s);
t:='';
for i:=1 to length(q)
do if q[i] <> ','
then t:=t+q[i];
Val(t,n,c);
if c <> 0
then q:='ERROR'
else q:=StrNumS(n, male);
q[1]:=upcase(q[1]);
StrPcopy(s, q);
end;
const M :array [1..12] of string[20] =
('ianuarie ','februarie ','martie ','aprelie ','mai ','iunie ','iulie ',
'august ','septembrie ','oktombrie ','noembrie ','decembrie ');
procedure Q(s :pChar); export;
var q :string; n,c :integer;
begin
q:=StrPas(s);
Val(q,n,c);
if c <> 0
then q:='ERROR 1'
else if (n < 0) or (n > 12)
then q:='ERROR 2'
else q:=M[n];
StrPcopy(s,q);
end;
exports P index 1;
exports Q index 2;
begin
end.
После компоновки библиотеки moldova.dll и размещения его в директории файлов данных бухгалтерии, можно вызывать содержащиеся в нем процедуры из файлов-форм. Приводимые процедуры можно использовать при подготовке первичных документов на молдавском языке вместо встроенных в "Финансы без проблем" "русскоязычных" функций [wn ] и [dt ]. Мы, однако, делать этого не будем и проверим работоспособность функции [DLLcall ], вызвав ее прямо из калькулятора:
Так по молдавски пишется 2458051. А вот так пишется слово 'сентябрь':