Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Для новичков > Считывание текстового файла сложной структуры


Автор: Pellegrino 28.1.2010, 23:06
Уважаемые, столкнулся с такой непростой задачкой, как работа с текстовым файлом сложной структуры. Нужно считать с него коды станций, номера платежей, суммы и коды статей. И дату. Желательно в табличку запихнуть для удобства работы. Единственный вариант, который приходит в голову, это построчное считывание и анализ. Подскажите какими методами такое можно провернуть? 

Автор: Данкинг 28.1.2010, 23:12
Цитата(Pellegrino @  28.1.2010,  23:06 Найти цитируемый пост)
Подскажите какими методами такое можно провернуть? 

Так грузи в Memo, а дальше парси всякими строковыми функцями вроде "copy".

Автор: chip_and_dayl 28.1.2010, 23:26
Pellegrino
Лучше всего структура файла сменить

Цитата(Pellegrino @  28.1.2010,  23:06 Найти цитируемый пост)
Единственный вариант, который приходит в голову, это построчное считывание и анализ

Я даже бы сказал - посимвольный 

Автор: Pellegrino 29.1.2010, 17:59
Файл менять не могу и структуру тоже. Данные нужны для БД. Конкретно привязать не могу именно к copy, так как длина названий везде разная и это только 1\5 файла.  А как сделать чтобы записывал только суммы из строк со словами "по станции"?

Автор: chip_and_dayl 29.1.2010, 20:35
Значить алгоритм, приблизительно такой.
1.  Загружаем/открываем текстовой файл
2. Ищем строку "по станции" (ф-ций поиска хватает)
3. Запоминаем номер строки и запускаем поиск уже по строке, в которой нашли слово "по станции"
4. Заносим сумму в базу
5. Ищем  следующую строку, где находиться слово "по станции"

Добавлено @ 20:40
Тут вопрос может возникнуть только в пункте 3. Как искать!?! Или тупым перебором, то  есть каждую строку анализировать на символ  "|" и когда, мы найдем в строке второй символ "|", то мы знаем, что за вторым символом уже идет желаемая сумма, то  мы откидываем пробелы и заносим сумму в базу.
Второй вариант, найти ф-цию поиска, которая ищет по шаблону

Автор: Pellegrino 29.1.2010, 21:28
Вот у меня была идея искать на подобе какойнить маски.

Автор: Демо 29.1.2010, 22:55
Так вроде нет никаких проблем разобрать файл.

Конечный автомат - стандартный алгоритм.

Автор: kami 30.1.2010, 01:11
Я чего-то возможно не понимаю, но не вижу никакой проблемы разобрать этот файл.
Длина строки - фиксированная.
Длина каждой ячейки - тоже.
Функции copy вместе с trim хватит с головой и даже больше...
Если я правильно понял структуру файла, то:

Код

type
  TPayRecord = record
    Name: string;
    Code: integer;
    Caption: string;
    Summ: Double;
    StNum: integer;
  end;

  TPayRecordArray = array of TPayRecord;

  TStation = record
    StationCode: integer;
    StationSumm: Double;
    Pays: TPayRecordArray;
  end;

  TStations = array of TStation;

  TBufType = (btDivider, btPay, btStation);

function DescribeBufType(const Buf: string): TBufType;
begin
  Result := btDivider;
  // длина строки в образце фиксированная.
  if Length(Buf) <> 126 then
    exit;
  if Buf[1] = ':' then
    Exit;
  if Buf[6] = '|' then
    Result := btPay
  else
    if Pos('ПО СТАНЦИИ', Buf)<>0 then
      Result := btStation; // так как в таблице есть еще строка "ОТДЕЛЕНИЕ -  1",
      // назначение которой не оговаривалось, не помешает дополнительная проверка
      // на принадлежность строки - к итоговой по станции.
end;

procedure ParseStation(Buf: string; var Station: TStation);
begin
  Station.StationCode := StrToInt(Trim(Copy(Buf, 15, 89)));
  Station.StationSumm := StrToFloat(Copy(Buf, 106, 13));
end;

procedure ParsePay(Buf: string; var Pay: TPayRecord);
begin
  Pay.Name := Trim(Copy(Buf, 7, 10));
  Pay.Code := StrToInt(Trim(Copy(buf, 18, 7)));
  Pay.Caption := Trim(Copy(Buf, 26, 79));
  Pay.Summ := StrToFloat(Trim(Copy(Buf, 106, 13)));
  Pay.StNum := StrToInt(Trim(Copy(Buf, 120, 6)));
end;

procedure ParseFile(FileName: string; var Stations: TStations);
var
  f: TextFile;
  buf: string;
  iStations, iPays: Integer;
  i: integer;
begin
  DecimalSeparator:='.';

  iStations := 0;
  iPays := 0;
  SetLength(Stations, 1);
  SetLength(Stations[0].Pays, 1);

  AssignFile(f, FileName);
  Reset(f);
  // пропускаем начальные строки - заголовок таблицы и все такое.
  // Дату предлагаю "забрать" самому.
  for i := 1 to 14 do
    Readln(f);

  while not Eof(f) do
    begin
      Readln(f, buf);
      case DescribeBufType(buf) of
        btDivider: ;
        btPay:
          begin
            ParsePay(buf, Stations[iStations].Pays[iPays]);
            if Stations[iStations].Pays[iPays].Name = '' then
              if iPays > 0 then
                Stations[iStations].Pays[iPays].Name := Stations[iStations].Pays[iPays - 1].Name;
            Inc(iPays);
            SetLength(Stations[iStations].Pays, iPays + 1);
          end;
        btStation:
          begin
            ParseStation(buf, Stations[iStations]);
            Inc(iStations);
            SetLength(Stations, iStations + 1);
            SetLength(Stations[iStations].Pays, 1);
            iPays:=0;
          end;
      end;
    end;
end;

procedure ClearStations(var Stations: TStations);
var
  i, j: integer;
begin
  // из-за несовершенства алгоритма
  // в каждом из массивов последний элемент будет
  // пустым. Убираем лишнее.
  for i := 0 to Length(Stations) - 1 do
    begin
      j := Length(Stations[i].Pays);
      if j <> 0 then
        if Stations[i].Pays[j-1].Name = '' then
          SetLength(Stations[i].Pays, j - 1);
    end;
  i:=Length(Stations)-1;
  if Stations[i].StationCode=0 then
    SetLength(Stations, i);
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  Stations:TStations;
begin
  if OpenDialog1.Execute then
    begin
      ParseFile(OpenDialog1.FileName, Stations);
      ClearStations(Stations);
    end;
  // теперь в Stations содержатся коды станций и суммы платежей
  // а в Stations[i].Pays - платежи.
  // можно делать с ними, что угодно...
end;

Автор: Pellegrino 1.2.2010, 14:00
Круто, спасибо. А как добавить еще коды платежей и суммы по ним? Еще вопрос, что за регулярные выражения, они могут тут помочь? А в данные из типа рекорд можно в стингГрид укладывать? smile 

Автор: profesiachuvak 1.2.2010, 17:45
Цитата(Pellegrino @  1.2.2010,  14:00 Найти цитируемый пост)
А в данные из типа рекорд можно в стингГрид укладывать? smile 


Обращаться к fields (полям) записи и выводить их в StringGrid.

Автор: kami 1.2.2010, 18:49
Цитата(Pellegrino @  1.2.2010,  14:00 Найти цитируемый пост)
. А как добавить еще коды платежей и суммы по ним?

Не понял вопроса, или Вы не читали мой ответ.
Stations[i].Pays[j].Code и Summ - это разве не то, что нужно? Строка платежа разбирается полностью по всем колонкам за исключением порядкового номера.

Цитата(Pellegrino @  1.2.2010,  14:00 Найти цитируемый пост)
 Еще вопрос, что за регулярные выражения, они могут тут помочь?

Не ко мне.

Цитата(Pellegrino @  1.2.2010,  14:00 Найти цитируемый пост)
А в данные из типа рекорд можно в стингГрид укладывать?

Более чем можно, и к этому нет никаких препятствий. Только давайте так - решать за Вас Вашу задачу здесь, имхо, не будут. За этим - в "Центр Помощи". С учетом того, что я и так сказал больше, чем нужно было, предлагаю следующее - Вы попробуете сами перенести данные из записей в StringGrid. Если что-то не получится - с конкретным вопросом и своим "работающим не так, как нужно" кодом - пожалуйста сюда.

Автор: Pellegrino 1.2.2010, 21:50
Дату я забрал, правда, может и не самым красивым способом. Подозреваю, что косяки еще могут меня встретить.
Код

//чтение из файла
    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;



Автор: kami 1.2.2010, 23:37
Код с моими комментариями:
Код

while not EOF(f) do
  begin
    readln(f,buf);    // это понятно.
    Memo1.Lines.Add(buf); // А это зачем? В изначальном вопросе не сказано, что всё подряд из файла нужно загружать в Memo
    if buf[27]='З' then // не проще ли "пролистать" до шестой строки и забрать оттуда нужное?
      Form4.Edit2.Text:=copy(buf,30,42); // строка с этой датой имеет переменную длину ровно по дате,
                                         // я бы забирал так: copy(buf, 30, Length(buf)), т.е. с 30 символа и до конца.
                                                             
  end;  // почему, найдя нужное, мы все равно продолжаем проходить остаток файла и заносить всё из него в memo?
        // а если файл будет гигантского размера?
CloseFile(f); // закрыть файл
  begin
    Form4.ComboBox1.Text:=mounth; // из кода непонятно, откуда взялись эти переменные - month, god (имхо, лучше year :) )
    Form4.Edit3.Text:=god;
    data1:=mounth + ' ' + god;
    Form4.Edit3.text:=data2;
  end;
end;


Замечание не по теме - для удобства чтения другими вашего кода, неплохо было бы оформлять его, придерживаясь правил, принятых у создателей VCL. Да и обзывать компоненты лучше осмысленными именами, чтобы не пришлось мучительно искать - "а что же отображает Edit94 на Form31".

Автор: Pellegrino 2.2.2010, 22:16
По моей задумке пользователь вводит год в эдите3 и выбирает месяц из комбоБокса, а после я захватываю дату и сравниваю её с введенным, если нет совпадения, то вывожу сообщение об ошибке ввода и блокирую кнопку записи в БД. А как до 6 строки пролистать -  for i:=0 do 5 then таким образом? Еще проблема возникла в том, что версия проги выбрасывающая отчет сменилась, и изменился отчетный файлик. В нем три вида отчетов, мне нужны станции с кодами платежей и цифрами по ним по ФО-7л и ФО-7н, Фо-7М не нужно. Возникла идея разбить на два текстовика с нужным содержим по Фо-7л и Н, а как можно определять начало и концовки их? 

Автор: kami 2.2.2010, 22:31
Цитата(kami @  1.2.2010,  18:49 Найти цитируемый пост)
решать за Вас Вашу задачу здесь, имхо, не будут. За этим - в "Центр Помощи". ... Если что-то не получится - с конкретным вопросом и своим "работающим не так, как нужно" кодом - пожалуйста сюда.


Автор: Pellegrino 3.2.2010, 20:36
Решил просто перебирать тупо строки и писать в 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;


Автор: kami 4.2.2010, 00:21
Цитата(Pellegrino @  3.2.2010,  20:36 Найти цитируемый пост)
пишет только три первых столбца и заполняет чушью. 

Естественно.
Поставьте брейкпоинт на начало обработчика кнопки и пройдитесь в ней по F8. Наводя курсор на переменную buf на каждой строке Вы поймете, где ошибка. Навскидку 
- сперва нужно считывать очередную строку в буфер, а уже потом с ней работать 
- у функции copy второй параметр - с какого символа начать копирование, а третий - количество копируемых символов. Вы же не хотите сказать, что "статья" занимает 127 символов?
Код
copy(buf,122,127);(статья)

И еще раз повторюсь  - 
Цитата(kami @  1.2.2010,  23:37 Найти цитируемый пост)
для удобства чтения другими вашего кода, неплохо было бы оформлять его, придерживаясь правил, принятых у создателей VCL.
, читать Ваш очень неудобно.
Если это не по силам, скачайте и установите http://www.aew.wur.nl/uk/delforexp/. После установки нажав Ctrl+D (в среде Delphi, естественно) и Enter Вы удивитесь, как код преобразится к читабельному виду.

Автор: Pellegrino 4.2.2010, 09:43
Я в нете с телефона, но постараюсь выложить оформленный код. С символами до меня уже доперло. Заполняются только первые три колонки, что странно. ТАблица так же заполняется мусором, есть 4 значения, по которым надо строки удалять. А вот как удалять строки в Гриде по значению ячейки? Можно табличку плотней сбить, а то много пустых позиций. Еще вопрос не везде есть имя станции папротив станции, каким алгоритмом доставить туда соотвествующие имена? Спасибо за подсказку про ф8, сразу нашел в чем косяк. Прошу не судить меня строго, так как я недавно начал...

Автор: kami 4.2.2010, 16:12
Цитата(Pellegrino @  4.2.2010,  09:43 Найти цитируемый пост)
Заполняются только первые три колонки, что странно.

Может быть, в строке меньше 107 символов, поэтому
Цитата(Pellegrino @  3.2.2010,  20:36 Найти цитируемый пост)

copy(buf,107,120);(сумма)
copy(buf,122,127);(статья)

не отрабатывают? А точнее - отрабатывают, но в результате выдают пустую строку?
Цитата(Pellegrino @  4.2.2010,  09:43 Найти цитируемый пост)
ТАблица так же заполняется мусором, есть 4 значения, по которым надо строки удалять. 

Может, просто перед занесением в таблицу, смотреть - мусор в буфере или нет, и если мусор - сразу переходить к чтению другой строки?
типа так:
Код

в цикле до конца файла
  begin
    считали строку
    в строке мусор? тогда
      continue // это оператор, который Delphi понимает. Означает переход на следующий виток цикла
    иначе
      разбиваем буфер и раскидываем по ячейкам стринггрида
  end;


Цитата(Pellegrino @  4.2.2010,  09:43 Найти цитируемый пост)
Еще вопрос не везде есть имя станции папротив станции, каким алгоритмом доставить туда соотвествующие имена?

в своем коде по первому варианту файла я делал так:
при разбиении строки определял, что это - конкретный платеж или итог по станции. Если конкретный платеж, то:
если имя станции в текущем буфере <> '', то
  запоминаем имя станции
заносим буфер "куда надо".
Если имя станции из текущего буфера ='', то 
  вставляем вместо него запомненное.
Цитата(Pellegrino @  4.2.2010,  09:43 Найти цитируемый пост)
Прошу не судить меня строго, так как я недавно начал

Да вроде никто и не пытается.  smile 

Автор: Pellegrino 4.2.2010, 22:21
Чет с именем не все понятно с имена станций... 
вот так я наворотил, конечно не айс, но работает... 
Код

//зашрузка данных в табличку

procedure TForm4.Button5Click(Sender: TObject);
var
F:TextFile; //файл
fName: String[100]; // имя файла
buf: String[124]; //буфер для чтения строк
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
           for i := 1 to StringGrid1.RowCount - 1 do
    begin
        readln(f,buf);    // прочитать строку из файла
           if buf[1]='|' then
           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);
                end;

        end;
      CloseFile(f); // закрыть файл
             end;



 procedure TForm4.Button6Click(Sender: TObject); // кнопка чистки
var
i:integer;
 begin
     for i := 1 to StringGrid1.RowCount - 1 do
     begin
       if Form4.StringGrid1.Cells[2,i]<>'                                                                               ' then
       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];
     end;
     
      end;
  end;
end;

Автор: Pellegrino 5.2.2010, 21:52
Разобрался я с имена и пустыми строками. Спасибо за подсказки! Вот мой код, конечно не самый оптимальный, но работает! Если есть предложения по оптимизации буду рад! Вот такой вопрос, а как наложить маску ввода на Едит, точнее мне нужно чтобы было только 4 символа и те только цифры, ну типа год.  И организовать проверку на заполненность его корректным способом? 

Код

//загрузка данных в табличку

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;


Автор: kami 5.2.2010, 22:29
Цитата(Pellegrino @  5.2.2010,  21:52 Найти цитируемый пост)
 как наложить маску ввода на Едит

SpinEdit с MinValue=1900 и MaxValue=9999
или MaskEdit с маской !0000;1;0

Автор: Pellegrino 8.2.2010, 18:27
Еще один маленький вопросик. Надо в табличку положить коды станций, но чет они у меня не хотят вставать как нужно и "размножаться".  И еще как заставить стринггрид заполняться строка в соответствии с записями, а то я руками вбухал 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;


Автор: kami 8.2.2010, 20:00
Цитата(kami @  1.2.2010,  23:37 Найти цитируемый пост)
 для удобства чтения другими вашего кода, неплохо было бы оформлять его, придерживаясь правил, принятых у создателей VCL.

Вы выкладываете кучу кода. Не оформленного вообще. И хотите, чтобы в нем кто-то пытался разобраться? Да через 2 недели Вы сами не поймете свой код. Пощадите нервы и время отвечающих, хотя бы акцентируйте внимание на уровне вложенности операторов.

Автор: Pellegrino 8.2.2010, 20:51
с этим, кстати проблемы у самого начались... А как пользоваться вот  DelForExp? 
Код

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
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]<>'' 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); // закрыть файл
end;
end.

Автор: Pellegrino 10.2.2010, 08:22
У меня коды станций запаздывают на одну станцию. Кокой алгоритм должен бы на замещение текущего элемента следующим? При этом первый сместить в начало таблицы? 

Автор: Rennigth 10.2.2010, 09:02
Pellegrino, 
kami правильно говорит, просто нехочеться даже рассматривать Ваш код. Пожалуйста, почитайте хоть эту статью 
http://www.delphikingdom.com/asp/viewitem.asp?catalogid=802 
Поверьте, Вам с большем желанием будут помогать.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)