Уважаемые, столкнулся с такой непростой задачкой, как работа с текстовым файлом сложной структуры. Нужно считать с него коды станций, номера платежей, суммы и коды статей. И дату. Желательно в табличку запихнуть для удобства работы. Единственный вариант, который приходит в голову, это построчное считывание и анализ. Подскажите какими методами такое можно провернуть?
Прикрепленные файлы
razsb.txt ( 3.45 килобайт )
Кол-во скачиваний: 287
а что если текстовый файл заменить на екселевкий?
сорри не досмотрел приложение, походу файл прога делает
тут все должно быть строго
Да файл мне прога выкидывает, но не моя и менять я в ней не могу ничего. В файле много лишнего. Мне нужна только сумма по станции и код станции с датой. все остальное игнорировать. Данные мне нужны для БД. Есть примерный вариант как анализировать подобное, а то не так долго работаю с делфи, опыт а еще пока нету.
ширина стобцов меняться может? если нет то все упрощается берешь строку от сих до сих и вот те ячейка....
шапка тож наверно статична можно сразу отбросить
строки придется проверять, что именно в строке
берешь ищешь твою "по станции", как нашел значит все строки до следующей "по станции" твои...
(ну кроме разделителей)
еще может можно ориентироваться по
:----
|
для удобства грузи в Тмемо строки сразу и видеть будешь что загрузил
а разносить конечно в массив или по усмотрению может сразу в твою БД как удобней
Да все поля статичны. Ну вот как? Мне только коды станций и общая сумма нужны.
С регулярными там чет все не по-русски :-( как заставить захватывать с строку?
Безо всяких регэкспов:
procedure TForm1.ParseClick(Sender: TObject);На твоем файле из первого поста выдает в Memo1 вот такой результат:
var
Lst, Parsed: TStringList;
i: integer;
s: string;
begin
Lst := TStringList.Create;
try
Lst.LoadFromFile('razsb.txt');
for i := 0 to Pred(Lst.Count) do
begin
if Pos('ПО СТАНЦИИ', Lst.Strings[i]) > 0 then
begin
Parsed := TStringList.Create;
ExtractStrings(
['|', ' '], [],
PChar(
StringReplace(
StringReplace(Lst.Strings[i], 'ПО СТАНЦИИ', '', []),
' ', ' ', [rfReplaceAll])
),
Parsed
);
Memo1.Lines.Add(Format('Код: %s, Сумма: %s',
[Parsed.Strings[0], Parsed.Strings[1]]));
Parsed.Free;
end;
end;
finally
Lst.Free;
end;
end;
надо и так попробовать, спасибо. Дату я забрал, правда, может и не самым красивым способом. Подозреваю, что косяки еще могут меня встретить.
//чтение из файла
while not EOF(f) do
begin
readln(f,buf); // прочитать строку из файла
Memo1.Lines.Add(buf); // добавить строку в поле Memo1
if buf[27]='З' then
Form4.Edit2.Text:=copy(buf,30,42);
end;
CloseFile(f); // закрыть файл
begin
Form4.ComboBox1.Text:=mounth;
Form4.Edit3.Text:=god;
data1:=mounth + ' ' + god;
Form4.Edit3.text:=data2;
end;
end;
Клевый код, очень быстро работает. Вот с датой проще, наверное до 6 строки пролистать. а чтобы символы "Г."отбросить просто отминусовать их от конца или есть проще варианты? Еще проблема возникла в том, что версия проги выбрасывающая отчет сменилась, и изменился отчетный файлик. В нем три вида отчетов, мне нужны станции с кодами платежей и цифрами по ним по ФО-7л и ФО-7н, Фо-7М не нужно. Возникла идея разбить на два текстовика с нужным содержим по Фо-7л и Н, а как можно определять начало и концовки их?
Прикрепленные файлы
razsb.txt ( 47.17 килобайт )
Кол-во скачиваний: 263
Решил просто перебирать тупо строки и писать в StringGrid. По задумке должно было писать все строки начинающиеся с символа "|", но чет не очень вышло, пишет только три первых столбца и заполняет чушью.
procedure TForm4.Button5Click(Sender: TObject);
var
F:TextFile; //файл
fName: String[100]; // имя файла
buf: String[80]; //буфер для чтения строк
i:integer; //шагалка
stroka:string; //строка
year,mounth:string; //месяц и год введение пользователем
data1,data2:string; //дата считываемая и отображаемая
begin
fName:=Form4.Edit1.Text; //забираем путь
AssignFile(f,fName); //
try
Reset(F); // открыть для чтения
except
on EInOutError do
begin
ShowMessage('Ошибка доступа к файлу'+fName);
exit;
end
end;
while not EOF(f) do
begin
for i := 0 to StringGrid1.RowCount - 1 do
begin
Form4.StringGrid1.Cells[0,i]:=copy(buf,9,16); (имя)
Form4.StringGrid1.Cells[1,i]:=copy(buf,21,27);(код)
Form4.StringGrid1.Cells[2,i]:=copy(buf,27,106);(код)
Form4.StringGrid1.Cells[3,i]:=copy(buf,107,120);(сумма)
Form4.StringGrid1.Cells[4,i]:=copy(buf,122,127);(статья)
//чтение из файла
begin
readln(f,buf); // прочитать строку из файла
if buf[1]='|' then
end;
end;
if buf[27]='З' then
begin
Form4.Edit2.Text:=copy(buf,30,42); //забрал дату
end;
end;
CloseFile(f); // закрыть файл
begin
Form4.ComboBox1.Text:=mounth;
Form4.Edit3.Text:=year;
data1:=mounth + ' ' + year;
Form4.Edit3.text:=data2;
end;
end;
Вроде разобрался с заполнение, только из пяти столбцов заполняются только первые три. В чем причина не пойму. Как можно удалить строки из грида, если там пустые ячейки или не нужные мне значения? И кучнеи сбить, а то пробелов с пустыми строками полно.
Разобрался!
//загрузка данных в табличку
procedure TForm4.Button5Click(Sender: TObject);
var
F:TextFile; //файл
fName: String[100]; // имя файла
buf: String[127]; //буфер для чтения строк
i:integer; //шагалка
stroka:string; //строка
year,mounth:string; //месяц и год введение пользователем
data1,data2:string; //дата считываемая и отображаемая
name_stat:string;
{ begin
if Form4.Edit3.Text=null then
ShowMessage('Не указан год загрузки!!!');
exit;
if Form4.ComboBox1.Text=null then
ShowMessage('Не выбран месяц загрузки');
exit; }
begin
fName:=Form4.Edit1.Text; //забираем путь
AssignFile(f,fName);
try
Reset(F); // открыть для чтения
except
on EInOutError do
begin
ShowMessage('Ошибка доступа к файлу'+fName);
exit;
end
end;
i:=1;
while not EOF(f) do
begin
readln(f,buf); // прочитать строку из файла
// длина строки в образце фиксированная.
if buf[27]='З' then
Form4.Edit2.Text:=copy(buf,30,20);
if POS(':',buf[1])>0 then
continue
else
begin
if POS('(',buf[1])>0 then
continue
else
begin
if POS(' ',buf[1])>0 then
continue;
if buf[1]='|' then
begin
if POS('ЕЛЕНИЕ',buf)>0 then
continue
else
begin
if POS('СТАНЦИИ',buf)>0 then
continue
else
begin
if POS('ГО ПО ОТДЕ',buf)>0 then
continue
else
begin
if POS('ГО ПО ДОРО',buf)>0 then
continue
else
begin
Form4.StringGrid1.Cells[0,i]:=copy(buf,7,10);
Form4.StringGrid1.Cells[1,i]:=copy(buf,20,3);
Form4.StringGrid1.Cells[2,i]:=copy(buf,26,79);
Form4.StringGrid1.Cells[3,i]:=copy(buf,106,13);
Form4.StringGrid1.Cells[4,i]:=copy(buf,121,4);
if Form4.StringGrid1.Cells[0,i]<>' ' then
name_stat:=Form4.StringGrid1.Cells[0,i];
if Form4.StringGrid1.Cells[0,i]=' ' then
Form4.StringGrid1.Cells[0,i]:=name_stat;
inc(i);
end;
end;
end;
end;
end;
end;
end;
end;
CloseFile(f); // закрыть файл
begin
mounth:=Form4.ComboBox1.Text; //месяц клиента
year:=Form4.Edit3.Text; // год клиента
data1:=mounth + ' ' + year + ' Г.';// дата клиента
data2:=Form4.Edit2.Text; // дата из файла
Form4.Edit4.Text:=data1;
if data1<>data2 then
begin
ShowMessage('Дата загрузки не соответствует указанной дате');
Form4.Button6.Enabled:=False;
end;
if data1=data2 then
begin
ShowMessage('Дата ввода корректна');
Form4.Button6.Enabled:=True;
Form4.ComboBox1.Enabled:=False;
Form4.Edit3.Enabled:=False;
end;
for i := 1 to StringGrid1.RowCount - 1 do
begin
if Form4.StringGrid1.Cells[1,i]<>'147' then
if Form4.StringGrid1.Cells[1,i]<>'163' then
if Form4.StringGrid1.Cells[1,i]<>'143' then
if Form4.StringGrid1.Cells[1,i]<>'150' then
if Form4.StringGrid1.Cells[1,i]<>'166' then
if Form4.StringGrid1.Cells[1,i]<>'149' then
if Form4.StringGrid1.Cells[1,i]<>'154' then
if Form4.StringGrid1.Cells[1,i]<>'144' then
if Form4.StringGrid1.Cells[1,i]<>'145' then
if Form4.StringGrid1.Cells[1,i]<>'169' then
if Form4.StringGrid1.Cells[1,i]<>'158' then
if Form4.StringGrid1.Cells[1,i]<>'161' then
if Form4.StringGrid1.Cells[1,i]<>'151' then
if Form4.StringGrid1.Cells[1,i]<>'162' then
if Form4.StringGrid1.Cells[1,i]<>'171' then
if Form4.StringGrid1.Cells[1,i]<>'124' then
if Form4.StringGrid1.Cells[1,i]<>'160' then
begin
Form4.StringGrid2.Cells[0,i]:=Form4.StringGrid1.Cells[0,i];
Form4.StringGrid2.Cells[1,i]:=Form4.StringGrid1.Cells[1,i];
Form4.StringGrid2.Cells[2,i]:=Form4.StringGrid1.Cells[2,i];
Form4.StringGrid2.Cells[3,i]:=Form4.StringGrid1.Cells[3,i];
Form4.StringGrid2.Cells[4,i]:=Form4.StringGrid1.Cells[4,i];
begin
if Form4.StringGrid2.Cells[0,i]<>' ' then
name_stat:=Form4.StringGrid2.Cells[0,i];
if Form4.StringGrid2.Cells[0,i]=' ' then
Form4.StringGrid2.Cells[0,i]:=name_stat;
{
if Form4.StringGrid1.Cells[0,i]<>' ' then
name_stat:=Form4.StringGrid1.Cells[0,i];
if Form4.StringGrid1.Cells[0,i]=' ' then
Form4.StringGrid1.Cells[0,i]:=name_stat; }
end;
end;
end;
end;
end;
Еще один маленький вопросик. Надо в табличку положить коды станций, но чет они у меня не хотят вставать как нужно и "размножаться". И еще как заставить стринггрид заполняться строка в соответствии с записями, а то я руками вбухал 200, что не есть хорошо. Во второй грид гружу по выборке.
procedure TForm4.Button5Click(Sender: TObject);
var
F:TextFile; //файл
fName: String[100]; // имя файла
buf: String[127]; //буфер для чтения строк
i:integer; //шагалка
stroka:string; //строка
year,mounth:string; //месяц и год введение пользователем
data1,data2:string; //дата считываемая и отображаемая
name_stat:string;
kod_stat:string;
j:integer;
kod_plateg:string; // код платежа
Kod_state:string;
{ begin
if Form4.Edit3.Text=null then
ShowMessage('Не указан год загрузки!!!');
exit;
if Form4.ComboBox1.Text=null then
ShowMessage('Не выбран месяц загрузки');
exit; }
begin
fName:=Form4.Edit1.Text; //забираем путь
AssignFile(f,fName);
try
Reset(F); // открыть для чтения
except
on EInOutError do
begin
ShowMessage('Ошибка доступа к файлу'+fName);
exit;
end
end;
i:=1; j:=1;
while not EOF(f) do
begin
readln(f,buf); // прочитать строку из файла
// длина строки в образце фиксированная.
if buf[27]='З' then
Form4.Edit2.Text:=copy(buf,30,20);
if POS(':',buf[1])>0 then
continue
else
begin
if POS('(',buf[1])>0 then
continue
else
begin
if POS(' ',buf[1])>0 then
continue;
if buf[1]='|' then
begin
if POS('ЕЛЕНИЕ',buf)>0 then
continue
else
begin
if POS('ПО СТАНЦИИ',buf)>0 then
Form4.StringGrid1.Cells[5,j]:=copy(buf,17,7);
if POS('СТАНЦИИ',buf)>0 then
continue
else
begin
if POS('ГО ПО ОТДЕ',buf)>0 then
continue
else
begin
if POS('ГО ПО ДОРО',buf)>0 then
continue
else
begin
Form4.StringGrid1.Cells[0,i]:=copy(buf,7,10);
Form4.StringGrid1.Cells[1,i]:=copy(buf,20,3);
Form4.StringGrid1.Cells[2,i]:=copy(buf,26,79);
Form4.StringGrid1.Cells[3,i]:=copy(buf,106,13);
Form4.StringGrid1.Cells[4,i]:=copy(buf,121,4);
if Form4.StringGrid1.Cells[0,i]<>' ' then
name_stat:=Form4.StringGrid1.Cells[0,i];
if Form4.StringGrid1.Cells[0,i]=' ' then
Form4.StringGrid1.Cells[0,i]:=name_stat;
if Form4.StringGrid1.Cells[5,i]<>'123' then
Kod_stat:= Form4.StringGrid1.Cells[5,i];
// это я тут пытался присвоить имена
if Form4.StringGrid1.Cells[5,i]='' then
Form4.StringGrid1.Cells[5,i]:=Kod_stat;
inc(j);
inc(i);
end;
end;
end;
end;
end;
end;
end;
end;
CloseFile(f); // закрыть файл
begin
mounth:=Form4.ComboBox1.Text; //месяц клиента
year:=Form4.Edit3.Text; // год клиента
data1:=mounth + ' ' + year + ' Г.';// дата клиента
data2:=Form4.Edit2.Text; // дата из файла
Form4.Edit4.Text:=data1;
if data1<>data2 then
begin
ShowMessage('Дата загрузки не соответствует указанной дате');
Form4.Button6.Enabled:=False;
end;
if data1=data2 then
begin
ShowMessage('Дата ввода корректна');
Form4.Button6.Enabled:=True;
Form4.ComboBox1.Enabled:=False;
Form4.Edit3.Enabled:=False;
end;
Form4.SocketConnection1.Connected:=false;
Form4.SocketConnection1.Connected:=true;
Form4.SocketConnection1.AppServer.openbase('ORA8','fs_master','fs');
kod_plateg:='select KOD_PLATEG_FO7 from SPR_PLATEG_FO7';
kod_state:='select KODEXP7 from SPR_MSTO where KODEXP <> 0 ';
Form4.ClientDataSet1.close;
Form4.ClientDataSet1.DataRequest(kod_plateg);
Form4.ClientDataSet1.open;
// Form4.ClientDataSet1.DataRequest(kod_state);
// Form4.ClientDataSet1.open;
while not Form4.ClientDataSet1.eof do
begin
for i := 1 to StringGrid1.RowCount - 1 do
begin
kod_plateg:=Form4.ClientDataSet1.fieldbyname('KOD_PLATEG_FO7').asstring;
// kod_state:=Form4.ClientDataSet1.fieldbyname('KODEXP7').asstring;
if Form4.StringGrid1.Cells[1,i]= kod_plateg then //выборка нужных платежей
begin
Form4.StringGrid2.Cells[0,i]:=Form4.StringGrid1.Cells[0,i];
Form4.StringGrid2.Cells[1,i]:=Form4.StringGrid1.Cells[1,i];
Form4.StringGrid2.Cells[2,i]:=Form4.StringGrid1.Cells[2,i];
Form4.StringGrid2.Cells[3,i]:=Form4.StringGrid1.Cells[3,i];
Form4.StringGrid2.Cells[4,i]:=Form4.StringGrid1.Cells[4,i];
Form4.StringGrid2.Cells[5,i]:=Form4.StringGrid1.Cells[5,i];
end;
end;
Form4.ClientDataSet1.next;
end;
Form4.ClientDataSet1.close;
end;
Form4.Edit5.Text := Format('%.2d', [Form4.ComboBox1.ItemIndex + 1])+ '.' +Form4.Edit3.text;
end;
напиши сначала
StringGrid1.RowCount:=2;
а при добавлении записи
StringGrid1.RowCount:=StringGrid1.RowCount+1;{555}
а что значит "размножаться"?
о, щас попробую. Размножаться - это если имя станции одинаковое, то код станции тож должен быть там