В процессе работы с 1С:Предприятие Аптека, возникла потребность выявлять фальсифицированные или бракованные лекарственные препараты. Эти сведения можно получить и сделать сверку данных с базой аптеки. Но тут возникли трудности.
Присылаемая база данных использует файл Vsual FoxPro .dbf, для использование его в программе 1С, это не является препятствием. Но оказалось, что описание причины брака медпрепарата содержится в МЕМО поле с которым 1С:Предприятие работать не может. Нужно было как-то преобразовать этот файл в более доступный для импорта формат. Выбор среды для реализации выпал на Delphi.
После анализа методов работы с файлами dbf, решено было отказаться в использовании ADO и BDE в связи с тем что необходимую установку драйверов и настройку пришлось бы делать на компьютере пользователя. Нужно было приложение работающее незаметно и не требующее сложных настроек. Поиски на эту тему увенчались успехом, был найден компонент tDbf позволяющий работать с dbf форматом напрямую.
Т.к. в 1С:Предприятие уже была обработка загрузки данных из xml, то оставалось привести исходный файл к требуемой структуре. Вот что из этого вышло:
unit converter;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, DB, dbf, StdCtrls;
type TForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end;
var Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject); var f : TextFile; fil: string; MyDbf: TDbf; i,j: integer; // pole: PChar; RCHStr : TStream; spisok: TStringList; begin MyDbf := TDbf.Create(nil); MyDbf.FilePath:='C:\Brak\'; MyDbf.TableName:='brakf.dbf';
MyDbf.Open; fil:=ExtractFilePath(Application.ExeName)+'\defect.xml' ;
AssignFile(f,fil); Rewrite(f);
writeln(f,''); writeln(f,'<INVENTORY>'); for i:=1 to MyDbf.RecordCount do begin MyDbf.RecNo:=i ;
writeln(f,'<defect>'); writeln(f,'<Name>'+Mydbf.fieldByName('NLN').asString+' '+Mydbf.fieldByName('NLF').asString+'</Name>'); writeln(f,'<Seria>'+Mydbf.fieldByName('SERBR').asString+'</Seria>'); writeln(f,'<Produser>'+Mydbf.fieldByName('NPR').asString+'</Produser>'); writeln(f,'<NumLetter>'+Mydbf.fieldByName('NP').asString+'</NumLetter>'); writeln(f,'<DataLetter>'+Mydbf.fieldByName('DT').asString+'</DataLetter>');
//чтение МЕМО поля motiv RCHStr := TsTREAM.Create; // Создаешь поток RCHStr := MyDbf.CreateBlobStream(MyDbf.FieldByName('motiv'),bmRead); // Считываем поток spisok:=TStringList.Create; spisok.LoadFromStream(RCHStr); // А вот тут загружаем его в нужный компонент if spisok.Count<>0 then
for j:=0 to spisok.count-1 do // Считываем строки списка BEGIN if spisok.ValueFromIndex[J]<>null then writeln(f,'<Reasons>'+spisok.Strings[J]+'</Reasons>'); end; spisok.Free; RCHStr.Free; // Освобождаем поток //конец чтения МЕМО поля
writeln(f,'</defect>'); end; writeln(f,'</INVENTORY>'); end;
end.
|