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


Автор: Martin_8 22.12.2008, 01:59
Здравствуйте.
Помогите, пожалуйста, разобраться с TStringList. Статью о TStringList я прочитал, но всё равно не могу понять, почему происходит так, как описанное ниже.

У меня есть txt файл, который мне необходимо обработать. Скажем, записать результат его парсинга в memo.
Файл состоит из двух секций [IN_PARAM] и [OUT_PARAM]. 
В секции [OUT_PARAM] содержится информация в формате “^имя” = “значение^”. Причём блоки параметров “^имя” = “значение^” периодически (через 12 строк) повторяются (начало 12-и строчного блока это ^DocDate, а конец это ^Num ). Первые 12 строк описывают одну организацию, следующие 12 строк описывают вторую организацию и т.д.
На выходе, я хочу получить только “значения”.

txt файл прикреплён.

Разбор я выполняю так.
Код

procedure TForm1.Button2Click(Sender: TObject);
var
  s : TStringList;
  i,k,b,l,h,j,f : integer;
  a,ss:string;
begin
  s := TStringList.Create;
  try
   if dlgOpen1.Execute then Memo1.Lines.LoadFromFile(dlgOpen1.FileName);
   Memo1.Lines.LoadFromFile(dlgOpen1.FileName);
   s.LoadFromFile(dlgOpen1.FileName);

   k:=s.IndexOf('[OUT_PARAM]');  // определяем номер строки, где находится [OUT_PARAM]

   f:=0;
   l:=k+1;
   // В этом while ищем номер строки, где находится ^DocDate именно с ^DocDate начинаются те самые 12 строк
   while f=0 do
    begin
     If (Pos('^DocDate',s.Names[l])<>0) then
      begin
        ShowMessage(IntToStr(l));
        h:=l; // номер строки, где находится ^DocDate
        f:=1;
      end;
     l:=l+1;
    end;

    // Выводим в мемо по 12 строк
    while h<s.Count-1 do
     begin
       for j:= h to h+12 do
        begin
          b:= Pos('^',s.Values[s.Names[j]]); // определяю позицию нахождения в строке символа ^
          ss:=s.Values[s.Names[j]];          // переписываем строку
          Delete(ss,b,1);                    // удаляем символ ^
          Memo2.Lines.Add(ss);               // выводим результат в memo
          h:=h+1;
        end;
     end
  finally
    s.Free;
  end;

end;

Вся проблема во втором while: 
Первый 12 итераций в for выполняются нормально, и я получаю данные об первой организации. Но следующие 12 итераций for опять выводят информацию о первой организации, а не о следующей. С третей та же проблема и т.д. Хотя я вижу, что переменная j меняется. 
Возникает такое ощущение, что “указатель  строки” не перемещается дальше, а остаётся на первом блоке из 12-записей.
Покажите, где здесь ошибка и как её исправить?

P.S. 
Потом, если удастся побороть описанную проблему, нужно будет вносить “значения” в БД, Insert запросом по 12 за раз. 
Посоветуйте, как и куда лучше сохранять мои “значения”, для последующей вставки в БД через Insert ?


Автор: Данкинг 22.12.2008, 03:07
Цитата(Martin_8 @  22.12.2008,  01:59 Найти цитируемый пост)
Код

if dlgOpen1.Execute then Memo1.Lines.LoadFromFile(dlgOpen1.FileName);
   Memo1.Lines.LoadFromFile(dlgOpen1.FileName);
   s.LoadFromFile(dlgOpen1.FileName)
;

А зачем дважды грузить в Memo1, но в результате всё равно работать с S ? smile Кстати, я даже боюсь представить, что будет, если пользователь всё же не выберет файла через OpenDialog!  smile Впрочем, ошибка через try...finally всё равно отловится, согласен.

Честно говоря, ничего из кода не понял, но могу посоветовать использовать не StringList, а TextFile, т.е. читать строки напрямую из текста. smile Да и "значения" я бы брал, просто отсекая всё слева, что идёт за "равно", а потом удаляя ^.

Автор: Martin_8 22.12.2008, 10:02
Данкинг, Спаибо за ответ, особоеено в такое время.
Я в принципе, делаю всё так, как Вы написали.

Цитата(Данкинг @  22.12.2008,  03:07 Найти цитируемый пост)
Да и "значения" я бы брал, просто отсекая всё слева

Я так и делаю, вот здесь, как раз и нахдится "значение"
Код

Values[s.Names[j]]

Цитата(Данкинг @  22.12.2008,  03:07 Найти цитируемый пост)
то идёт за "равно", а потом удаляя ^

Вот это делается здесь:

Код

b:= Pos('^',s.Values[s.Names[j]]); // определяю позицию нахождения в строке символа ^
ss:=s.Values[s.Names[j]];          // переписываем строку
Delete(ss,b,1);                    // удаляем символ ^
// Теперь в ss чистая строка со "значением" без ^ 


Но я хочу понять, почему в моём случаи, не перемещается "указатель" строк в TStringList. 
Я просто зашёл в тупик.  smile 

Автор: NewDima 22.12.2008, 10:27
не совсем вкуриваю, о каком указателе речь...

Автор: NewDima 22.12.2008, 11:10
 smile 

Автор: TRS743 22.12.2008, 11:44
for j:= h to h+12 do
        begin
          b:= Pos('^',s.Values[s.Names[j]]); // определяю позицию нахождения в строке символа ^
          ss:=s.Values[s.Names[j]];          // переписываем строку
          Delete(ss,b,1);                    // удаляем символ ^
          Memo2.Lines.Add(ss);               // выводим результат в memo
          h:=h+1;
        end;
Не совсем понял смысл проги, но выделенное красным цветом вызывает подозрения

Автор: Martin_8 22.12.2008, 12:02
NewDima, Спасибо! 
А я как-то не заметил свойство ValueFromIndex у TStringList. С ним всё работает. Честно говоря, я не понял, почему не работает мой код, ну да ладно.

Посоветуйте, пожалуйста, ещё по поводу этого:
Цитата(Martin_8 @  22.12.2008,  01:59 Найти цитируемый пост)
P.S. 
Потом, если удастся побороть описанную проблему, нужно будет вносить “значения” в БД, Insert запросом по 12 за раз. 
Посоветуйте, как и куда лучше сохранять мои “значения”, для последующей вставки в БД через Insert ?


Автор: Данкинг 22.12.2008, 12:05
Цитата(Martin_8 @  22.12.2008,  12:02 Найти цитируемый пост)
Потом

Когда "потом" - сразу и вноси.

Автор: NewDima 22.12.2008, 15:50
Цитата(Martin_8 @ 22.12.2008,  19:02)
Посоветуйте, пожалуйста, ещё по поводу этого:
Цитата(Martin_8 @  22.12.2008,  01:59 Найти цитируемый пост)
P.S. 
Потом, если удастся побороть описанную проблему, нужно будет вносить “значения” в БД, Insert запросом по 12 за раз. 
Посоветуйте, как и куда лучше сохранять мои “значения”, для последующей вставки в БД через Insert ?

это уже следующая тема и другой раздел
http://forum.vingrad.ru/forum/delphi-db-database-reporting.html

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