![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Вопрос по потокам [XP]
petvv © (2009-03-17 07:52:00)Вот есть код:
constructor TMonDirThread.Create(aPath: String);
begin
inherited Create(True);
FreeOnTerminate := True;
FPath := aPath;
Self.Priority := tpHighest;
Resume;
end;
procedure TMonDirThread.UpdateLog;
var
s: string;
f: TextFile;
i: Integer;
begin
Result:=1;
KolStr:=0;
Full:= WideCharToString(Path)+'\'+WideCharToString(FileName);
CreateDBF();
AssignFile(f, Full);
Reset(f);
while not EOF(f) do
begin
ReadLn(f, s);
if Result=2 then
begin
// Сдесь получаем № и дату накладной
GetNom(s,12,20);
GetDat(s,21,31);
end;
Inc(Result,1);
end;
CloseFile(f);
//*************************************
// Получаем количество строк в файле
//*************************************
AssignFile(f, Full);
Reset(f);
while not EOF(f) do
begin
ReadLn(f, s);
Inc(KolStr,1);
end;
KolStr:=KolStr-4;
CloseFile(f);
//*******************
Result:=1;
AssignFile(f, Full);
Reset(f);
while not EOF(f) do
begin
ReadLn(f, s);
if Result>=5 then
begin
Form1.Table1.Append;
Form1.Table1.FieldByName('DATEN').AsDateTime:=StrToDateTime(ResultDat);
Form1.Table1.FieldByName('NOMN').AsString:=ResultNom;
//Отсюда начинается сама накладная
//Получим количество полей
GetFields(s, Length(s));
end;
Inc(Result,1);
end;
CloseFile(f);
DeleteFile(Full);
Form1.Table1.Active:=False;
end;
procedure TMonDirThread.Execute;
Type PFileNotifyInformation=^TFileNotifyInformation;
TFileNotifyInformation=packed record
NextEntryOffset:dword;
Action:dword;
FileNameLength:dword;
FileName:WideChar;
end;
var hDir,cbReturn:dword;
lpBuf:pointer;
Ptr:PFileNotifyInformation;
begin
//Path:='D:\Накладные';
hDir:=CreateFile(Path,GENERIC_READ,FILE_SHARE_READ or FILE_SHARE_WRITE
or FILE_SHARE_DELETE,nil,OPEN_EXISTING,FILE_FLAG_BACKUP_SEMANTICS,0);
if hDir=INVALID_HANDLE_VALUE then begin ShowMessage(SysErrorMessage(GetLastError));exit;end;
GetMem(lpBuf,BUF_SIZE);
//repeat
while not Terminated do
begin
ZeroMemory(lpBuf,BUF_SIZE);
if(not ReadDirectoryChangesW(hDir,lpBuf,BUF_SIZE,true,FILE_NOTIFY_CHANGE_FILE_NAME
or FILE_NOTIFY_CHANGE_LAST_WRITE,@cbReturn,nil,nil))or(cbReturn=0)then Break;
// пользователь не сможет прервать ожидание, если захочет. Это нужно либо вынести в отдельный
// поток, либо использовать синхронный ввод/вывод
Ptr:=lpBuf;OldName:='';
// repeat
while not Terminated do
begin
GetMem(FileName,Ptr^.FileNameLength+2);
ZeroMemory(FileName,Ptr^.FileNameLength+2);
lstrcpynW(FileName,addr(Ptr^.FileName),Ptr.FileNameLength div 2+1);
case Ptr.Action of
FILE_ACTION_ADDED:Synchronize(UpdateLog);
end;
FreeMem(FileName);
if Ptr^.NextEntryOffset=0 then break;
Inc(integer(Ptr),Ptr^.NextEntryOffset);
// until false;
//until false;
end;
end;
FreeMem(lpBuf); // этот код ни разу не вызывается - программа останется в цикле до первой ошибки
CloseHandle(hDir);
end;
После выполнения FILE_ACTION_ADDED:Synchronize(UpdateLog);
не возвращается в цикл. Почему однако ???
Slym (2009-03-18 11:52:00) [1]petvv (18.03.09 11:38) [25]
hThread:=CreateThread(nil,0,@WorkThread, LV,0,ThID);
Думаешь проблема только с дельфевыми потоками? сирано графика у тебя съедет в один прекрасный момент...
если хочешь логов то Post/SendMessage пользуй но не напрямую VCL
Slym (2009-03-18 11:48:00) [2]petvv (18.03.09 11:38) [25]
Path, Full, ResultNom, ResultDat, Path1,fName, nName, Pole: String;
Fields: Variant;
nFileName:PWideChar;
OldName:widestring;
Result, KolStr, KolFields:Integer;
procedure TxtToDbf1;
Это на самом деле проблема!
У тебя глаз висит? печень наруже или мозг вскрыт? Пациент умрет
petvv (2009-03-18 11:38:00) [3]Slym'у огромный респект, буду разбираться с твоим кодом. А решил всё так:
unit TxtToDbf;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, DB, DBTables, ComCtrls, StdCtrls;
const
BUF_SIZE=1024;
type
TForm1 = class(TForm)
Table1: TTable;
LV: TListBox;
procedure FormCreate(Sender: TObject);
procedure CreateDBF();
procedure GetFields(InpString: string; fieldpos: Integer);
function GetDat(InpString: string; nashpos: Integer; fieldpos: Integer): string;
function GetNom(InpString: string; nashpos: Integer; fieldpos: Integer): string;
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
Path, Full, ResultNom, ResultDat, Path1,fName, nName, Pole: String;
Fields: Variant;
nFileName:PWideChar;
OldName:widestring;
Result, KolStr, KolFields:Integer;
procedure TxtToDbf1;
implementation
{$R *.dfm}
procedure WorkThread(LV : TListView);stdcall;
Type PFileNotifyInformation=^TFileNotifyInformation;
TFileNotifyInformation=packed record
NextEntryOffset:dword;
Action:dword;
FileNameLength:dword;
FileName:PWideChar;
end;
var
hDir : THandle;
lpBuf : Pointer;
cbReturn : Cardinal;
FileName : PWideChar;
Ptr:PFileNotifyInformation;
begin
hDir := CreateFile ('d:\Накладные',GENERIC_READ,FILE_SHARE_READ or FILE_SHARE_WRITE
or FILE_SHARE_DELETE,nil,OPEN_EXISTING,FILE_FLAG_BACKUP_SEMANTICS,0);
if hDir = INVALID_HANDLE_VALUE
then begin ShowMessage(SysErrorMessage(GetLastError)); exit; end;
GetMem(lpBuf,BUF_SIZE);
repeat
// очищаем память перед записью в нее (на всякий случай)
ZeroMemory(lpBuf,BUF_SIZE);
if not ReadDirectoryChangesW(hDir,lpBuf,BUF_SIZE,true,
FILE_NOTIFY_CHANGE_FILE_NAME or FILE_NOTIFY_CHANGE_LAST_WRITE,
@cbReturn,nil,nil) then Break;
Ptr:=lpBuf;
repeat
GetMem(FileName,Ptr^.FileNameLength+2);
ZeroMemory(FileName,Ptr^.FileNameLength+2);
lstrcpynW(FileName,addr(Ptr^.FileName),Ptr.FileNameLength div 2+1);
Full:= Path+'\'+FileName;
FreeMem(FileName);
case PFileNotifyInformation(Ptr).Action of
FILE_ACTION_ADDED : if ExtractFileExt(Full)<>'.dbf' Then TxtToDbf1();
end;
if PFileNotifyInformation(Ptr).NextEntryOffset=0
then Break
else begin
Inc(Cardinal(Ptr),PFileNotifyInformation(Ptr).NextEntryOffset);
end;
until false;
until false;
FreeMem(lpBuf);
end;
procedure TForm1.FormCreate(Sender: TObject);
var
ThID, hThread : Cardinal;
begin
Path:='d:\Накладные';
hThread:=CreateThread(nil,0,@WorkThread,LV,0,ThID);
// В случае неудачи выводим сообщение
if hThread=0 then ShowMessage(SysErrorMessage(GetLastError));
end;
.....
end.
Slym (2009-03-18 08:35:00) [4]
while not Terminated do
begin
ZeroMemory(lpBuf,BUF_SIZE);
if(not ReadDirectoryChangesW(hDir,lpBuf,BUF_SIZE,true,FILE_NOTIFY_CHANGE_FILE_NAME
or FILE_NOTIFY_CHANGE_LAST_WRITE,@cbReturn,nil,nil))or(cbReturn=0) then Break;
Ptr:=lpBuf;
repeat
FileName:=WideCharLenToString(@(Ptr^.FileName),Ptr.FileNameLength div 2);
case Ptr.Action of
FILE_ACTION_ADDED: DataProcessor.ProcessFile(FPath+FileName);
end;
if Ptr^.NextEntryOffset=0 then break;
Inc(integer(Ptr),Ptr^.NextEntryOffset);
until false;
end;
finally
FreeMem(lpBuf);
end;
finally
CloseHandle(hDir);
end;
except
if Assigned(ApplicationHandleException) then
ApplicationHandleException(Self);
end;
end;
end.
TMonDirThread.Create('c:\');
Slym (2009-03-18 08:35:00) [5]это ты тупиЩъ...
вот так должно выглядеть и никаких Undiclared identificator не будет
unit uDataProcessor;
interface
uses
Windows, SysUtils, Classes, DB, DBTables;
type
TDataProcessor=class
private
Table:TTable;
protected
procedure InitTable(const FileName:string);
procedure ProcessLine(const Line:string);
public
constructor Create;
destructor Destroy;override;
procedure ProcessFile(const FileName:string);
end;
implementation
function GetDat(InpString: string; nashpos: Integer; fieldpos: Integer): string;
var
curpos, i: Integer;
c: Char;
begin
curpos:= nashpos;
result:= '';
for i := nashpos to fieldpos do
begin
if curpos > fieldpos then Break;
repeat
c := InpString[curpos];
Inc(curpos, 1);
if (c='о') or (c='т')then
c := ' ';
if c <> ',' then
result:= result + c;
until (c = ',') or (curpos > fieldpos)
end;
result := Trim(result);
end;
function GetNom(InpString: string; nashpos: Integer; fieldpos: Integer): string;
var
c: Char;
curpos, i: Integer;
begin
curpos := nashpos;
result := '';
for i := nashpos to fieldpos do
begin
if curpos > fieldpos then
Break;
repeat
c := InpString[curpos];
Inc(curpos, 1);
if (c='о') or (c='т') or (c = #13) or (c = #10) then
c := ' ';
if c <> ',' then
result := result + c;
until (c = ',') or (curpos > fieldpos)
end;
if (curpos > Length(InpString)) and (i < fieldpos) then
result := '';
result := Trim(result);
end;
{ TDataProcessor }
constructor TDataProcessor.Create;
begin
inherited Create;
Table:=TTable.Create(nil);
end;
destructor TDataProcessor.Destroy;
begin
Table.Free;
inherited;
end;
procedure TDataProcessor.InitTable(const FileName: string);
begin
with Table do
begin
Active:=False;
TableType:=ttDBase;
DataBaseName:=ExtractFileDir(FileName);
TableName:=ExtractFileName(FileName);
with FieldDefs do
begin
Clear;
Add('DATEN',ftDate);
Add('NOMN',ftString,12,False);
Add('KOD',ftFloat,0,False);
Add('NAME',ftString,200,False);
Add('KOL',ftFloat,0,False);
Add('PROIZV',ftString,50,False);
Add('COUNTRY',ftString,15,False);
Add('GTD',ftString,30,False);
Add('CENA_OTP',ftFloat,0,False);
Add('CENA',ftFloat,0,False);
Add('NDS',ftFloat,0,False);
Add('SUM_NDS',ftFloat,0,False);
Add('CENA_SNDS',ftFloat,0,False);
Add('SUM_BNDS',ftFloat,0,False);
Add('CENA_REES',ftFloat,0,False);
Add('CENA_PR',ftFloat,0,False);
Add('TORG_NADB',ftFloat,0,False);
Add('SERIA',ftString,20,False);
Add('GODN',ftDate);
Add('NOM_SERT',ftString,30,False);
Add('SROK_DEIST',ftString,10,False);
Add('ORGAN',ftString,50,False);
Add('NOM_GLK',ftString,30,False);
Add('DATA_VID',ftString,10,False);
end;
CreateTable;
Exclusive:=true;
Active:=True;
end;
end;
procedure TDataProcessor.ProcessLine(const Line: string);
const FieldNames:array[1..22] of string=('KOD','NAME','KOL','PROIZV','COUNTRY','GTD',
'CENA_OTP','CENA','NDS','SUM_NDS','CENA_SNDS','SUM_BNDS','CENA_REES','CENA_PR',
'TORG_NADB','SERIA','GODN','NOM_SERT','SROK_DEIST','ORGAN','NOM_GLK','DATA_VID') ;
var
LineData:TStringList;
i:Integer;
Field:TField;
FieldValue:string;
begin
LineData:=TStringList.Create;
try
LineData.Delimiter:=';';
LineData.DelimitedText:=Line;
for i:= Low(FieldNames) to High(FieldNames) do
begin
Field:=Table.FindField(FieldNames[i]);
if not assigned(Field) then continue;
FieldValue:=LineData[i];
FieldValue:=StringReplace(FieldValue,'%',' ',[rfReplaceAll]);
if Field.DataType<>ftDate then
FieldValue:=StringReplace(FieldValue,'.',',',[rfReplaceAll]);
Field.Value:=FieldValue;
end;
finally
LineData.Free;
end;
end;
procedure TDataProcessor.ProcessFile(const FileName: string);
var
FileData:TStringList;
Dat:TDateTime;
Nom:string;
i:integer;
begin
InitTable(ChangeFileExt(FileName,'.dbf'));
try
FileData:=TStringList.Create;
try
FileData.LoadFromFile(FileName);
Dat:=StrToDateTime(GetNom(FileData[1],12,20));
Nom:=GetDat(FileData[1],21,31);
for i:=4 to FileData.Count-1 do
begin
Table.Append;
ProcessLine(FileData[i]);
Table.FieldByName('DATEN').AsDateTime:=Dat;
Table.FieldByName('NOMN').AsString:=Nom;
Table.Post;
end;
finally
FileData.Free;
end;
finally
Table.Close;
end;
end;
end.
unit uMonThread;
interface
uses
Windows, Messages, SysUtils, Classes,uDataProcessor;
type
TMonDirThread = class(TThread)
private
FPath: String;
DataProcessor:TDataProcessor;
protected
procedure Execute; override;
public
constructor Create(const Path: String);
destructor Destroy;override;
end;
implementation
type
PFileNotifyInformation=^TFileNotifyInformation;
TFileNotifyInformation=packed record
NextEntryOffset:dword;
Action:dword;
FileNameLength:dword;
FileName:WideChar;
end;
const
BUF_SIZE=4096;
constructor TMonDirThread.Create(const Path: String);
begin
inherited Create(True);
DataProcessor:=TDataProcessor.Create;
FreeOnTerminate:=True;
FPath:=IncludeTrailingPathDelimiter(Path);
Priority:=tpHighest;
Resume;
end;
destructor TMonDirThread.Destroy;
begin
DataProcessor.Free;
inherited;
end;
procedure TMonDirThread.Execute;
var
hDir,cbReturn:dword;
lpBuf:pointer;
Ptr:PFileNotifyInformation;
FileName:string;
begin
try
hDir:=CreateFile(PChar(FPath),GENERIC_READ,FILE_SHARE_READ or FILE_SHARE_WRITE or FILE_SHARE_DELETE,
nil,OPEN_EXISTING,FILE_FLAG_BACKUP_SEMANTICS,0);
if hDir=INVALID_HANDLE_VALUE then RaiseLastOSError;
try
GetMem(lpBuf,BUF_SIZE);
try
petvv (2009-03-18 07:53:00) [6]ё мля люди походу енто у меня дельфя чегойто глючит.
Пишу:
Type PFileNotifyInformation=^TFileNotifyInformation;
TFileNotifyInformation=packed record
NextEntryOffset:dword;
Action:dword;
FileNameLength:dword;
FileName:WideChar;
end;
var hDir,cbReturn:dword;
lpBuf:pointer;
Ptr:PFileNotifyInformation;
begin
//Path:='D:\Накладные';
hDir:=CreateFile(Path,GENERIC_READ,FILE_SHARE_READ or FILE_SHARE_WRITE
or FILE_SHARE_DELETE,nil,OPEN_EXISTING,FILE_FLAG_BACKUP_SEMANTICS,0);
if hDir=INVALID_HANDLE_VALUE then begin ShowMessage(SysErrorMessage(GetLastError));exit;end;
GetMem(lpBuf,BUF_SIZE);
repeat
//while not Terminated do
//begin
ZeroMemory(lpBuf,BUF_SIZE);
if(not ReadDirectoryChangesW(hDir,lpBuf,BUF_SIZE,true,FILE_NOTIFY_CHANGE_FILE_NAME
or FILE_NOTIFY_CHANGE_LAST_WRITE,@cbReturn,nil,nil))or(cbReturn=0)then Terminate;
// пользователь не сможет прервать ожидание, если захочет. Это нужно либо вынести в отдельный
// поток, либо использовать синхронный ввод/вывод
Ptr:=lpBuf;OldName:='';
repeat
//while not Terminated do
//begin
GetMem( FileName,Ptr^.FileNameLength+2);
ZeroMemory( FileName,Ptr^.FileNameLength+2);
lstrcpynW( FileName,addr(Ptr^.FileName),Ptr.FileNameLength div 2+1);
case Ptr.Action of
FILE_ACTION_ADDED:Form1.TxtToDbf(Form1);
на выделенное жирным говорит Undiclared identificator ...
Опупеть. И ещё заметил, что при добавлении на форму любого компонента в секции Uses не появляются нужные ссылки. А появляются они только после того как начнёш чегой то в ентой секции менять. Во пипец.
Slym (2009-03-18 06:34:00) [7]Какой формат файла? Намудрено сильно...
Slym (2009-03-18 05:57:00) [8]я не вижу привязки Table1 к гриду или другой визуализации...
1. Тогда зачем его держать на форме?
2. Нет обращения к форме, нет нужды в синхронизе...
3. Код на троечку с - (куча глобальных переменных)... на рефакторинг...
Сергей М. (2009-03-17 13:35:00) [9]А что, напрямую никак нелься вызвать TxtToDbf() ? Обязательно в обработчике ее вызывать ?
TxtToDbf;
Form1.Memo1.SetSelText('Изменено')
Чем этот вариант плох ?
petvv (2009-03-17 13:29:00) [10]Form1.Memo1.SetSelText('Изменено'); <-- вот здесть ты встал по брейкпойнту, сделал шаг по F7
Memo1 в OnChange стоит TxtToDbf();
Сергей М. (2009-03-17 13:22:00) [11]
> Нажимаеш F7 попадаем в TxtToDbf
Что ты несешь, какой еще TxtToDbf ?
Процедура Updatelog у тебя состоит из одной-единственной исполняемой строчки :
procedure TMonDirThread.UpdateLog;<-- сюда попал ? толкнул F9 дальше ?
begin
//Synchronize(TxtToDbf); // <-- эта закомментарена
Form1.Memo1.SetSelText('Изменено');<-- вот здесть ты встал по брейкпойнту, сделал шаг по F7
end;
petvv (2009-03-17 13:01:00) [12]Да. Нажимаеш F7 попадаем в TxtToDbf она выполняется, попадаем в
procedure TMonDirThread.UpdateLog;
begin
//Synchronize(TxtToDbf);
Form1.Memo1.SetSelText('Изменено');
end; // вот сюда
Дальше хоть обнажимайся F7, F8, F9 никуда не возвращается
Сергей М. (2009-03-17 12:47:00) [13]
> выполнение останавливается
Шаг (F7) после останова выполняется успешно?
petvv (2009-03-17 12:01:00) [14]Ставил. Когда кидаеш 1-й файл в директорию отрабатыват нормально (создаёт dbf) и после Form1.Memo1.SetSelText('Изменено');
выполнение останавливается (не возвращается в основной цикл опроса). Т.е. кидаеш следующий файл в директорию, а реакции 0.
Сергей М. (2009-03-17 11:57:00) [15]
> выполнение останавливается (не возвращается в основной цикл
> опроса)
Как ты это узнал ?
Ставил брейкпойнт на вызове SetSelText и делал шаг (F7) ?
petvv (2009-03-17 11:45:00) [16]Если не понятно то ещё раз:
while not Terminated do
begin
GetMem(FileName,Ptr^.FileNameLength+2);
ZeroMemory(FileName,Ptr^.FileNameLength+2);
lstrcpynW(FileName,addr(Ptr^.FileName),Ptr.FileNameLength div 2+1);
case Ptr.Action of
FILE_ACTION_ADDED:Synchronize(UpdateLog); //Уходит на синхронизацию
end;
FreeMem(FileName);
if Ptr^.NextEntryOffset=0 then break;
Inc(integer(Ptr),Ptr^.NextEntryOffset);
// until false;
//until false;
end;
procedure TMonDirThread.UpdateLog;
begin
//Synchronize(TxtToDbf);
Form1.Memo1.SetSelText('Изменено');
end;
В Мемо1 OnChange = Form1.TxtToDbf - выполняется обработка файла
и после Form1.Memo1.SetSelText('Изменено');
выполнение останавливается (не возвращается в основной цикл опроса)
petvv (2009-03-17 11:39:00) [17]непосредственно по проблеме был выше, и вопрос конкретный
Юрий Зотов (2009-03-17 11:36:00) [18]> petvv (17.03.09 11:17) [9]
Как Вы считаете, если бы Вы выделили и привели только тоткод, который относится к проблеме непосредственно, то Ваши шансы получить конкретный толковый ответ увеличились бы, или уменьшились?
petvv (2009-03-17 11:17:00) [19]Вот код потока:
unit uMonThread;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, StdCtrls, DB, DBTables, Menus;
const
BUF_SIZE=256;
type
TMonDirThread = class(TThread)
private
FPath: String;
protected
procedure Execute; override;
procedure UpdateLog;
public
constructor Create(aPath: String);
end;
implementation
uses
Unit1;
constructor TMonDirThread.Create(aPath: String);
begin
inherited Create(True);
FreeOnTerminate := True;
FPath := aPath;
Self.Priority := tpHighest;
Resume;
end;
procedure TMonDirThread.UpdateLog;
begin
//Synchronize(TxtToDbf);
Form1.Memo1.SetSelText('Изменено');
end;
procedure TMonDirThread.Execute;
Type PFileNotifyInformation=^TFileNotifyInformation;
TFileNotifyInformation=packed record
NextEntryOffset:dword;
Action:dword;
FileNameLength:dword;
FileName:WideChar;
end;
var hDir,cbReturn:dword;
lpBuf:pointer;
Ptr:PFileNotifyInformation;
begin
//Path:='D:\Накладные';
hDir:=CreateFile(Path,GENERIC_READ,FILE_SHARE_READ or FILE_SHARE_WRITE
or FILE_SHARE_DELETE,nil,OPEN_EXISTING,FILE_FLAG_BACKUP_SEMANTICS,0);
if hDir=INVALID_HANDLE_VALUE then begin ShowMessage(SysErrorMessage(GetLastError));exit;end;
GetMem(lpBuf,BUF_SIZE);
//repeat
while not Terminated do
begin
ZeroMemory(lpBuf,BUF_SIZE);
if(not ReadDirectoryChangesW(hDir,lpBuf,BUF_SIZE,true,FILE_NOTIFY_CHANGE_FILE_NAME
or FILE_NOTIFY_CHANGE_LAST_WRITE,@cbReturn,nil,nil))or(cbReturn=0)then Break;
// пользователь не сможет прервать ожидание, если захочет. Это нужно либо вынести в отдельный
// поток, либо использовать синхронный ввод/вывод
Ptr:=lpBuf;OldName:='';
// repeat
while not Terminated do
begin
GetMem(FileName,Ptr^.FileNameLength+2);
ZeroMemory(FileName,Ptr^.FileNameLength+2);
lstrcpynW(FileName,addr(Ptr^.FileName),Ptr.FileNameLength div 2+1);
case Ptr.Action of
FILE_ACTION_ADDED:Synchronize(UpdateLog);
end;
FreeMem(FileName);
if Ptr^.NextEntryOffset=0 then break;
Inc(integer(Ptr),Ptr^.NextEntryOffset);
// until false;
//until false;
end;
end;
FreeMem(lpBuf); // этот код ни разу не вызывается - программа останется в цикле до первой ошибки
CloseHandle(hDir);
end;
end.
petvv (2009-03-17 10:25:00) [20]Вот код основной формы:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, StdCtrls, DB, DBTables, Menus, uMonThread;
const
BUF_SIZE=256;
type
TForm1 = class(TForm)
TrayIcon1: TTrayIcon;
Table1: TTable;
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
Table1: TTable;
Path:PWideChar;
Full, ResultNom, ResultDat, Path1,fName, nName, Pole: String;
Fields: Variant;
FileName:PWideChar;
OldName:widestring;
Result, KolStr, KolFields:Integer;
procedure TxtToDbf;
procedure GetFields(InpString: string; fieldpos: Integer);
procedure CreateDBF();
function GetDat(InpString: string; nashpos: Integer; fieldpos: Integer): string;
function GetNom(InpString: string; nashpos: Integer; fieldpos: Integer): string;
implementation
uses ShellApi, shlobj, registry;
//**************************************
procedure CreateDBF();
begin
//**************************************
path1:=ExtractFileDir(Full);
fName:=ExtractFileName(Full);
nName:=ChangeFileExt(fName, '.dbf');
//*****
Form1.Table1.Active:=False;
Form1.Table1.TableType:=ttDBase;
Form1.Table1.DataBaseName:=Path1;
Form1.Table1.TableName:=nName;
Form1.Table1.FieldDefs.Clear;
Form1.Table1.FieldDefs.Add('DATEN',ftDate);
Form1.Table1.FieldDefs.Add('NOMN',ftString,12,False);
Form1.Table1.FieldDefs.Add('KOD',ftFloat,0,False);
Form1.Table1.FieldDefs.Add('NAME',ftString,200,False);
Form1.Table1.FieldDefs.Add('KOL',ftFloat,0,False);
Form1.Table1.FieldDefs.Add('PROIZV',ftString,50,False);
Form1.Table1.FieldDefs.Add('COUNTRY',ftString,15,False);
Form1.Table1.FieldDefs.Add('GTD',ftString,30,False);
Form1.Table1.FieldDefs.Add('CENA_OTP',ftFloat,0,False);
Form1.Table1.FieldDefs.Add('CENA',ftFloat,0,False);
Form1.Table1.FieldDefs.Add('NDS',ftFloat,0,False);
Form1.Table1.FieldDefs.Add('SUM_NDS',ftFloat,0,False);
Form1.Table1.FieldDefs.Add('CENA_SNDS',ftFloat,0,False);
Form1.Table1.FieldDefs.Add('SUM_BNDS',ftFloat,0,False);
Form1.Table1.FieldDefs.Add('CENA_REES',ftFloat,0,False);
Form1.Table1.FieldDefs.Add('CENA_PR',ftFloat,0,False);
Form1.Table1.FieldDefs.Add('TORG_NADB',ftFloat,0,False);
Form1.Table1.FieldDefs.Add('SERIA',ftString,20,False);
Form1.Table1.FieldDefs.Add('GODN',ftDate);
Form1.Table1.FieldDefs.Add('NOM_SERT',ftString,30,False);
Form1.Table1.FieldDefs.Add('SROK_DEIST',ftString,10,False);
Form1.Table1.FieldDefs.Add('ORGAN',ftString,50,False);
Form1.Table1.FieldDefs.Add('NOM_GLK',ftString,30,False);
Form1.Table1.FieldDefs.Add('DATA_VID',ftString,10,False);
Form1.Table1.CreateTable;
Form1.Table1.Active:=True;
Form1.Table1.Edit;
Form1.Table1.First;
end;
//********************************
procedure GetFields(InpString: string; fieldpos: Integer);
var
c: Char;
curpos, i: Integer;
begin
//**************************************
curpos := 1;
KolFields:=0;
Fields:='';
for i := 1 to fieldpos do
begin
case KolFields of
1: Pole:='KOD';
2: Pole:='NAME';
3: Pole:='KOL';
4: Pole:='PROIZV';
5: Pole:='COUNTRY';
6: Pole:='GTD';
7: Pole:='CENA_OTP';
8: Pole:='CENA';
9: Pole:='NDS';
10: Pole:='SUM_NDS';
11: Pole:='CENA_SNDS';
12: Pole:='SUM_BNDS';
13: Pole:='CENA_REES';
14: Pole:='CENA_PR';
15: Pole:='TORG_NADB';
16: Pole:='SERIA';
17: Pole:='GODN';
18: Pole:='NOM_SERT';
19: Pole:='SROK_DEIST';
20: Pole:='ORGAN';
21: Pole:='NOM_GLK';
22: Pole:='DATA_VID';
end;
case KolFields of
1,3,7,8,9,10,11,12,13,14,15: Form1.Table1.FieldByName(Pole).AsFloat:=StrToFloat(Fields);
2,4,5,6,16,18,19,20,21,22: Form1.Table1.FieldByName(Pole).AsString:=Fields;
end;
Fields:='';
KolFields := KolFields+1;
if curpos > Length(InpString) then
Break;
repeat
c := InpString[curpos];
Inc(curpos, 1);
if (c = #13) or (c = #10) then
c := ' ';
if (KolFields<>19) and (c='.') then
c:=',';
if c='%' then
c:=' ';
if c <> ';' then
Fields := Fields + c;
until (c = ';') or (curpos > Length(InpString))
end;
if (curpos > Length(InpString)) and (i < fieldpos) then
end;
//********************************
function GetDat(InpString: string; nashpos: Integer; fieldpos: Integer): string;
var
c: Char;
curpos, i: Integer;
begin
curpos := nashpos;
resultDat := '';
for i := nashpos to fieldpos do
begin
if curpos > fieldpos then
Break;
repeat
c := InpString[curpos];
Inc(curpos, 1);
if (c='о') or (c='т') or (c = #13) or (c = #10) then
c := ' ';
if c <> ',' then
resultDat := resultDat + c;
until (c = ',') or (curpos > fieldpos)
end;
resultDat := Trim(resultDat);
end;
//********************************
function GetNom(InpString: string; nashpos: Integer; fieldpos: Integer): string;
var
c: Char;
curpos, i: Integer;
begin
curpos := nashpos;
resultNom := '';
for i := nashpos to fieldpos do
begin
if curpos > fieldpos then
Break;
repeat
c := InpString[curpos];
Inc(curpos, 1);
if (c='о') or (c='т') or (c = #13) or (c = #10) then
c := ' ';
if c <> ',' then
resultNom := resultNom + c;
until (c = ',') or (curpos > fieldpos)
end;
if (curpos > Length(InpString)) and (i < fieldpos) then
result := '';
resultNom := Trim(resultNom);
end;
//************************************
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
Path:='D:\Накладные';
Form1.Tag := Integer(TMonDirThread.Create(Path));
end;
procedure TxtToDbf;
var
s: string;
f: TextFile;
// i: Integer;
begin
Result:=1;
KolStr:=0;
Full:= WideCharToString(Path)+'\'+WideCharToString(FileName);
CreateDBF();
AssignFile(f, Full);
Reset(f);
while not EOF(f) do
begin
ReadLn(f, s);
if Result=2 then
begin
// Сдесь получаем № и дату накладной
GetNom(s,12,20);
GetDat(s,21,31);
end;
Inc(Result,1);
end;
CloseFile(f);
//*************************************
// Получаем количество строк в файле
//*************************************
AssignFile(f, Full);
Reset(f);
while not EOF(f) do
begin
ReadLn(f, s);
Inc(KolStr,1);
end;
KolStr:=KolStr-4;
CloseFile(f);
//*******************
Result:=1;
AssignFile(f, Full);
Reset(f);
while not EOF(f) do
begin
ReadLn(f, s);
if Result>=5 then
begin
Form1.Table1.Append;
Form1.Table1.FieldByName('DATEN').AsDateTime:=StrToDateTime(ResultDat);
Form1.Table1.FieldByName('NOMN').AsString:=ResultNom;
//Отсюда начинается сама накладная
//Получим количество полей
GetFields(s, Length(s));
end;
Inc(Result,1);
end;
CloseFile(f);
DeleteFile(Full);
Form1.Table1.Active:=False;
end;
end.