Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 17.03.2012, 22:49   #1
AlexKhol
Пользователь
 
Регистрация: 04.02.2012
Сообщений: 15
По умолчанию Парсинг txt с разделителями табуляцией

Доброго времени суток! Необходимо из xls файла сделать xml.Сам xls представляет собой довольно большую таблицу,расписание занятий.Пробовал обращаться к таблице через Variant,но дело в том,что программа должна быть универсальной для любого количества столбцов и строк,а также любой разметки.Поэтому пришлось сохранять как Текстовый документ(с разделителем табуляцией).Подскажите как мне вытащить данные и записать их в группы,по столбцам.Например

Код HTML:
<group value="1">
 
<tag>Дни</tag>
<tag>Понедельник</tag>
...
</group>
 
 
<group value="2">
 
<tag>Часы</tag>
...
</group>
и тд.
А вот таблица в Txt:1.txt
AlexKhol вне форума Ответить с цитированием
Старый 18.03.2012, 13:01   #2
xrob
Форумчанин
 
Регистрация: 18.10.2010
Сообщений: 419
По умолчанию

я вам дам подсказку: символ табуляции - это #9.
и да прибудет с вами copy и pos!
благословляю тебя, сын мой, на такой вот код:

Код:
td1:= copy(stroka,1, pos(#9,stroka) );
Delete(stroka,1,pos(#9,stroka));

td2:= copy(stroka,1, pos(#9,stroka) );
Delete(stroka,1,pos(#9,stroka));
ну и т.д., пока строка не кончится.
кстати, чтобы избежать гемора с последней ячейкой,
после которой нету таба, и pos его не найдет,
то добавьте этот таб в самом начале, прежде чем парсить:

stroka:=stroka + #9;
xrob вне форума Ответить с цитированием
Старый 18.03.2012, 13:16   #3
_SERGEYX_
Участник клуба
 
Аватар для _SERGEYX_
 
Регистрация: 07.07.2007
Сообщений: 1,518
По умолчанию

В DelphiWorld есть хорошая функция, для разбивки строки с разделителями в stringlist
Код:
function Tokenize(Str: WideString; Delimiter: string): TStringList;
var
  tmpStrList: TStringList;
  tmpString, tmpVal: WideString;
  DelimPos: LongInt;
begin
  tmpStrList := TStringList.Create;
  tmpString := Str;
  DelimPos := 1;
  while DelimPos > 0 do
  begin
    DelimPos := LastDelimiter(Delimiter, tmpString);
    tmpVal := Copy(tmpString, DelimPos + 1, Length(tmpString));
    tmpStrList.Add(UpperCase(tmpVal));
    Delete(tmpString, DelimPos, Length(tmpString));
  end;
  Tokenize := tmpStrList;
end;
Правда, выдаст список в TStringList задом наперед, т.е. нужно будет читать лист
не так
Код:
for i:= 0 to sl.count-1
а так
Код:
for i:= sl.count-1 downto 0
но это не проблема
_SERGEYX_ вне форума Ответить с цитированием
Старый 18.03.2012, 15:51   #4
AlexKhol
Пользователь
 
Регистрация: 04.02.2012
Сообщений: 15
По умолчанию

А Delimiter - это разделитель?
AlexKhol вне форума Ответить с цитированием
Старый 18.03.2012, 16:30   #5
GunSmoker
Старожил
 
Регистрация: 13.08.2009
Сообщений: 2,581
По умолчанию

Цитата:
хорошая функция
По рукам бы за такой дизайн сигнатуры "хорошей функции".

Правильно нужно делать так:
Код:
procedureTokenize(const ASource, ADelimiter: String; const AResult: TStrings);
Ну и код внутри можно и получше сделать.

Например, так (режем строчку, используя TStrings):
Код:
procedure Tokenize(const ASource: String; const ADelimiter: Char; const AResult: TStrings);
var
  SavedDelimiter: Char;
  SavedQuoteChar: Char;
  SavedStrictDel: Boolean;
  DelimitedText: String;
begin
  SavedDelimiter := AResult.Delimiter;
  SavedQuoteChar := AResult.QuoteChar;
  SavedStrictDel := AResult.StrictDelimiter;
  try
    AResult.Delimiter := ADelimiter;
    AResult.QuoteChar := '"';
    AResult.StrictDelimiter := True;

    DelimitedText := AResult.QuoteChar + StringReplace(ASource, ADelimiter, AResult.QuoteChar + ADelimiter + AResult.QuoteChar, [rfReplaceAll]) + AResult.QuoteChar;

    AResult.DelimitedText := DelimitedText;
  finally
    AResult.Delimiter := SavedDelimiter;
    AResult.QuoteChar := SavedQuoteChar;
    AResult.StrictDelimiter := SavedStrictDel;
  end;
end;
Или так (если хочется руками и/или с множественными разделителями):
Код:
procedure Tokenize(const ASource, ADelimiters: String; const AResult: TStrings);
var
  CutPos: Integer;
  Src, Line: String;
begin
  if ASource = '' then
    Exit;

  AResult.BeginUpdate;
  try
    Src := ASource;
    AResult.Clear;
    repeat

      CutPos := LastDelimiter(ADelimiters, Src);
      if CutPos > 0 then
      begin
        Line := Copy(Src, CutPos + 1, MaxInt);
        Src := Copy(Src, 1, CutPos - 1);
      end
      else
      begin
        Line := Src;
        Src := '';
      end;

      AResult.Insert(0, Line);

    until Src = '';
  finally
    AResult.EndUpdate;
  end;
end;
Пример использования:
Код:
Tokenize('Test 1;Test 2;Test 3', ';', Memo1.Lines);
или:
Код:
var
  SL: TStringList;
begin
  SL := TStringList.Create;
  try
    Tokenize('Test 1;Test 2;Test 3', ';', SL);
    // что-то делаем с SL
  finally
    FreeAndNil(SL);
  end;
end;
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
GunSmoker вне форума Ответить с цитированием
Старый 18.03.2012, 17:02   #6
AlexKhol
Пользователь
 
Регистрация: 04.02.2012
Сообщений: 15
По умолчанию

GunSmoker подскажите как можно их по столбцам записать,то есть 1-й столбец в одну группу,второй в другую и тд.Дело в том что таблица кривая,и если в загрузить в Tstringlist, то 0-я строка,отображается нормально,а следующие не полно,а по 2-3 элемента?
AlexKhol вне форума Ответить с цитированием
Старый 18.03.2012, 17:09   #7
GunSmoker
Старожил
 
Регистрация: 13.08.2009
Сообщений: 2,581
По умолчанию

Ну так ты покажи наглядно, как ты хочешь представить данные. Например, открой файл в Excel, перегруппируй, покажи скриншот.

Пока что из твоего 1.txt текст
Цитата:
<group value="1">

<tag>Дни</tag>
<tag>Понедельник</tag>
...
</group>


<group value="2">

<tag>Часы</tag>
...
</group>
не следует ну никак.
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
GunSmoker вне форума Ответить с цитированием
Старый 18.03.2012, 17:17   #8
AlexKhol
Пользователь
 
Регистрация: 04.02.2012
Сообщений: 15
По умолчанию

Вот скрин таблицы.45.jpg
Нужно объединить по столбцам.
AlexKhol вне форума Ответить с цитированием
Старый 18.03.2012, 17:26   #9
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

Почему бы из Excel не выгрузить как xml-таблицу? ИМХО проще из xml-файла сделать другой xml-файл, чем ковыряться в текстовом файле с разделителями
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию
Аватар вне форума Ответить с цитированием
Старый 18.03.2012, 17:35   #10
AlexKhol
Пользователь
 
Регистрация: 04.02.2012
Сообщений: 15
По умолчанию

просто там куча пустых ячеек,которые тоже выводятся,и не узнаешь,где пустой потому что это окно,то есть занятий нет,а где...
AlexKhol вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как разделить textbox1.text (с разделителями ;) по частям? Aqil_f Microsoft Office Excel 13 13.12.2017 18:03
Дерево(строка) из массива строк с разделителями Lorenzo_M Помощь студентам 0 08.12.2011 04:40
Работа с различными разделителями (вставка и удаление) tissot Microsoft Office Excel 4 13.10.2010 06:03
помогите пожалуйста, задача с табуляцией, ошибка деление на 0.. как её убрать? Валюшка Помощь студентам 3 20.01.2009 21:01
PCHAR строка с разделителями #13#10. Как вычленить отдельные "подстроки" EdNovice Общие вопросы Delphi 1 17.04.2007 11:42