p align="left">Рассмотрим следующий пример. В вариант стандартной поставки "Финансов без проблем" входит файл-формы PLATEZKA.RPT, обеспечивающий формирование первичного документа "Платежное поручение". С помощью псевдопроводки "создать документ" он может быть "пристыкован" к операциям. Однако, каждый раз при формировании документа он заставляет нас вводить банковские реквизиты контрагента. Кроме того, организованный в нем последовательный ввод значений не очень-то удобен. Было бы намного приятнее выбирать необходимые значения из справочника, устанавливающего соответствие кода субсчета, передаваемого в форму, банковским реквизитам контрагента - расчетному счету, МФО и названию банка. Для решения этой задачи можно использовать следующую простую программу BANK.EXE, написанную на языке СУБД Clipper Summer'87. При ее "сборке" должны использоваться библиотеки clipper.lib, extend.lib и ct1.lib: parameters FBP_par * если нет параметров - не работаем * список параметров должен быть заключен в двойные кавычки if pcount() = 0 clear ? 'Программа может работать только вместе с "Финансами без проблем"' ? 'Параметры не указаны. Нажмите любую клавишу' inkey(0) quit endif set scoreboard off * файл BANK.DBF должен иметь следующие поля * SUB_SCET - символьного типа, длина 9 * KONTRAG - символьного типа, длина 100 * RS - символьного типа, длина 11 * MFO - символьного типа, длина 10 * BANK1 - символьного типа, длина 50 * BANK2 - символьного типа, длина 50 * длина полей может быть и иной, но тогда надо изменить настройки * вызова программы функцией [ru ] * для приведенного в книге примера критична длина полей RS и MFO * при изменении их в файле BANK.DBF должны быть изменены параметры * функции [cp ] * BANK.DBF должен быть предварительно проиндексирован по полю SUB_SCET use bank index bank * функция [ru ] должна должна передать программе * код субсчета, выбранный при регистрации операции и * название субсчета, разделенные точкой с запятой subscet = token( FBP_par, ';', 1 ) kontrag = token( FBP_par, ';', 2 ) * ищем запись, относящуюся к данному контрагенту seek rtrim(subscet) * если такой записи нет, то добавляем запись с данным кодом и * наименованием субсчета if .not. found() append blank replace sub_scet with subscet, kontragent with kontrag do EditRecord endif * оформляем экран - функция [ru ] должна использоваться * с параметром восстановления экрана set color to n/bg @ 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
Страницы: 1, 2, 3, 4, 5, 6, 7
|