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


Автор: Vladimir_K 17.4.2007, 17:15
Подскажите, как, указав папку, реализовать программное открытие находящихся в ней текстовых файлов?
Количество и имена файлов заранее неизвестны.
Порядок такой:
1) указать конкретную папку;
2) нажать кнопку Пуск;
3) содержимое первого по-порядку файла загружается в окно RichEdit;
4) обработка файла;
5) сохранение файла;
6) открытие следующего файла;
7) и т.д.
8) остановка, когда все файлы из папки обработаны.

Автор: Snowy 17.4.2007, 17:22
FindFirst + F1

Автор: ama_kid 17.4.2007, 17:22
FindFirst/FindNext

Автор: Vladimir_K 17.4.2007, 18:25
Что-то я не очень понял...
Как это сделать-то? smile 

Автор: z-END 17.4.2007, 18:30
Цитата(Vladimir_K @  17.4.2007,  19:25 Найти цитируемый пост)
Как это сделать-то?

дык.. руками или деньгамиsmile

вызываем диалог обзора папок (или пишем свой)
выполнем поиск всех текстовых файлов, заносим их в массив
потом крутим цикл по всем элементам полученного массива (окртываем, редактируем,сохраняем)

Автор: Vladimir_K 17.4.2007, 19:17
Как вызвать диалог обзора папок? Чтобы выбрать можно было именно папку а не конкретный файл в ней?

Автор: Vladimir_K 17.4.2007, 19:45
Код

procedure TForm1.Button1Click(Sender: TObject);
var F:TSearchRec;
    ires:integer;
    sdirtxt:string;
begin
 ires:=FindFirst(sdirtxt,faAnyFile,F);
 while ires=0 do
  begin
   RichEdit1.Lines.LoadFromFile(F.Name);//Отобразить содержимое файла
   .
   .
   ires:=FindNext(F);
  end;

end;

Как-то так... 
А как задать каталог в переменную sdirtxt?

Автор: z-END 18.4.2007, 09:23
Цитата(Vladimir_K @  17.4.2007,  20:45 Найти цитируемый пост)
А как задать каталог в переменную sdirtxt?

может вам инструкцию по пользованию поиском распечатать? smile

Автор: Akella 18.4.2007, 10:58
Цитата(z-END @  17.4.2007,  18:30 Найти цитируемый пост)
или деньгамиsmile

наглёш

Добавлено @ 11:01
Код

Procedure TfmUpdateInfo.GetArchivesToUpload(Dir:String);
Var
 SearchRec:TSearchRec;
begin
 try
   if Dir<>'' then Dir:=IncludeTrailingPathDelimiter(Dir);
   if FindFirst(Dir+'*.*', faAnyFile, SearchRec)=0 then
     repeat
       if (SearchRec.name='.') or (SearchRec.name='..') then continue;
       if ((SearchRec.Attr and faDirectory)<>0) then
         GetArchivesToUpload(Dir+SearchRec.name) //we found Directory: "Dir+SearchRec.name"
       else  begin

             if AnsiUpperCase(ExtractFileExt(SearchRec.name)) = '.RTF' then   EditFile(Dir+SearchRec.name);

       end;//else
     until FindNext(SearchRec)<>0;
   FindClose(SearchRec);

 finally
   //
 end;
end;


а в EditFile() уже извращаешься как хочешь, открываешь, редактируешь, закрываешь ну и т.д.

Автор: z-END 18.4.2007, 11:04
Цитата(Akella @  18.4.2007,  11:58 Найти цитируемый пост)
наглёш

оффтоп

все можно сделать или самому или за вознаграждениеsmile

Автор: Akella 18.4.2007, 11:09
На Винграде советы дают и оказывают помощь бесплатно, за иск. той ветки, где явно подразумевается вознаграждения за помошь. smile

Добавлено через 25 секунд
а ты намекаешь ему.... вместо помощи....

Добавлено через 2 минуты и 2 секунды
Цитата(z-END @  18.4.2007,  11:04 Найти цитируемый пост)
все можно сделать или самому или за вознаграждение

или обратиться к нам на форум smile 

Автор: z-END 18.4.2007, 11:16


Цитата(Akella @  18.4.2007,  12:09 Найти цитируемый пост)
или обратиться к нам на форум

к вам на форум и обратились.. так что пиши кодsmile

Автор: Vladimir_K 18.4.2007, 15:04
Спасибо, конечно за помощь, но я думал это будет попроще сделать, типа использования OpenDialog...
Как работать с этой процедурой: procedure TfmUpdateInfo.GetArchivesToUpload(Dir:String); я вообще понятия не имею. Ну нет у меня таких знаний.
Попробую разобраться, что там к чему, а нет, так использую другой путь. 
Но все равно всем спасибо за помощь. Или почти всем...

А поиск по запросу "диалог обзора папок" ничего не дал.

Автор: z-END 18.4.2007, 15:16
Цитата(Vladimir_K @  18.4.2007,  16:04 Найти цитируемый пост)
А поиск по запросу "диалог обзора папок" ничего не дал.

а синонимы проверить сил конечно же нет...
обзор папок/выбор папки/обзор директории/ выбрать директорию/выбрать каталог/ 
самому не догадаться?

Цитата(Vladimir_K @  18.4.2007,  16:04 Найти цитируемый пост)
Как работать с этой процедурой: procedure TfmUpdateInfo.GetArchivesToUpload(Dir:String); я вообще понятия не имею. Ну нет у меня таких знаний.

может сначала мат.часть почитать? smile
тебе дали готовый кусок кода. который нужно вставить тебе в форму и вызывать по нажатию на твой "ПУСК" 

Автор: Akella 19.4.2007, 08:34
Код

Procedure ScanFilder(Dir:String);
Var
 SearchRec:TSearchRec;
begin
 try
   if Dir<>'' then Dir:=IncludeTrailingPathDelimiter(Dir);
   if FindFirst(Dir+'*.*', faAnyFile, SearchRec)=0 then//если что-то нашли
     repeat
       if (SearchRec.name='.') or (SearchRec.name='..') then continue;//если это не каталоги и не файлы, то пропускаем
       if ((SearchRec.Attr and faDirectory)<>0) then//
         ScanFilder(Dir+SearchRec.name) //нашли папку и вызываем опять саму себя - рукурсия называется
       else  begin//если попалась не папка, а файл, то вот он родной, нужно узнать расширение
             
           if AnsiUpperCase(ExtractFileExt(SearchRec.name)) = '.RTF' then   EditFile(Dir+SearchRec.name);//если расширение "наше", то вызываем функцию EditFile(), а вот уже эту функцию пиши сам, никто не знает точно что ты в ней будешь делать!!!
       end;//else
     until FindNext(SearchRec)<>0;
   FindClose(SearchRec);//заканчиваем поиск
 finally
   //
 end;
end;

Автор: Vladimir_K 19.4.2007, 17:50
Я использовал вот какой код:

Код

uses ShellAPI, ShlObj; 

procedure TForm1.Button1Click(Sender: TObject); 
var 
 TitleName : string;   
 lpItemID : PItemIDList;   
 BrowseInfo : TBrowseInfo;   
 DisplayName : array[0..MAX_PATH] of char;   
 TempPath : array[0..MAX_PATH] of char;  
  
begin 
 FillChar(BrowseInfo, sizeof(TBrowseInfo), #0);   
 BrowseInfo.hwndOwner := Form1.Handle;   
 BrowseInfo.pszDisplayName := @DisplayName;   
 TitleName := 'Please specify a directory';   
 BrowseInfo.lpszTitle := PChar(TitleName);   
 BrowseInfo.ulFlags := BIF_RETURNONLYFSDIRS;   
 lpItemID := SHBrowseForFolder(BrowseInfo);   
 if lpItemId <> nil then begin    
 SHGetPathFromIDList(lpItemID, TempPath);   
 ShowMessage(TempPath);   
 GlobalFreePtr(lpItemID);    
 end;    
end;


В теме, в которой я его нашел, сказано следующее:

Цитата

Код работает , но мне нужно чтобы запоминался путь к последней выбранной папке и при повторном выборе папки предлагался бы выбор с ранее выбранной папки.
А в даном коде выбор папки всегда начинается с "Мой компьютер".
Как выбрать папку , с возможностью запоминания ранее выбраной папки?(Чтобы вводить несколько папок с одного места на диске последовательно)

После этого:
Цитата

Извените , что поспешил задать вопрос ,нашел решение сам:
В JEDI есть компонента JvSelectDirectory,она решила мою проблему. 

И больше никаких подробностей. Но мне этого мало.

Подскажите, как использовать эту компоненту: JvSelectDirectory?

Автор: Vladimir_K 19.4.2007, 21:42
И почему-то для правильной работы моей программы, она должна находиться в той же папке, где и текстовые файлы... Иначе - не работает. Поэтому, наверное, и со вложенными папками ничего не получается?
В принципе, мне запоминание последней открытой папки не нужно, если программа сможет открывать файлы из папки, которую я укажу и из вложенных в нее папок!

Автор: Vladimir_K 22.4.2007, 13:30
Akella, спасибо за выложенные коды, я пытался разобраться в них, но так как я очень слаб в Delphi, я не смог применить Ваш код (исправить "ошибки", которые вывалила моя Delphi7 на Ваш код), сколько я с ним не бился  smile 
Вот мой код:
Код

//------------------------------------------------------------------------------
// Указать папку
//------------------------------------------------------------------------------
procedure TForm1.BOpenDirClick(Sender: TObject);
var 
 TitleName : string;   
 lpItemID : PItemIDList;   
 BrowseInfo : TBrowseInfo;   
 DisplayName : array[0..MAX_PATH] of char;   
 TempPath : array[0..MAX_PATH] of char;    //Адрес папки
 F:TSearchRec;
 ires:integer;
 i,ns:integer;
 z:string;

begin 
 FillChar(BrowseInfo, sizeof(TBrowseInfo), #0);   
 BrowseInfo.hwndOwner := Form1.Handle;   
 BrowseInfo.pszDisplayName := @DisplayName;
 TitleName := 'Please specify a directory';
 BrowseInfo.lpszTitle := PChar(TitleName);
 BrowseInfo.ulFlags := BIF_RETURNONLYFSDIRS;
 lpItemID := SHBrowseForFolder(BrowseInfo);
 if lpItemId <> nil
  then begin
   SHGetPathFromIDList(lpItemID, TempPath);
   GlobalFreePtr(lpItemID);
  end;

 ires:=FindFirst(TempPath+'\*.txt',faAnyFile,F); //Найти первый txt файл
 while ires=0 do                                                 //Найти и изменить все файлы из папки (и из вложенных папок - если есть)
  begin
   RichEdit1.Lines.LoadFromFile(F.Name);         //Отобразить содержимое файла

// Здесь идет просмотр файла, изменение его (если нужно), и т.д.
// Код я написал сам, приводить его здесь нет смысла - вряд ли он кого-то заинтересует...

   RichEdit1.Lines.SaveToFile(F.Name);             //Сохранение файла
   RichEdit1.Clear;


   ires:=FindNext(F);                    //Найти следующий txt файл
  end;
 FindClose(F);                         //Завершение поиска
end;

Проблема такая: моя программа может открыть txt файлы только из папки, в которой находится сама программа. Из других папок файлы не открываются.
DRKB3 Full скачал (за 2.5 часа smile ) ищу ответ там, но что-то никак не найду...
Может быть, кто-то из вас, о, Великие и Мудрые снизойдет до решения моей задачи?

Автор: VladBD 22.4.2007, 19:22
Хочешь просто - бери OpenDialog, кидай на форму. При старте программы можешь начальный путь указать или расширение по умолчанию - но это не обязательно. Главное укажи мультиселект - чтобы несколько файлов можно было выделять...
Потом в обработчике Button1 пишешь
Код

  if opendialog1.execute=false then Exit;
  for i:=0 to opendialog.files.count do
  begin
     здесь обрабатывай текущий файл
     opendialog.files[i] - это имя I-того выбранного файла 
  end;

Автор: Vladimir_K 23.4.2007, 08:18
Нет, OpenDialog здесь не поможет. smile 
Мне нужно указывать не отдельные файлы, а папку целиком (в которой находятся вложенные папки, а в них *.txt файлы - и прога должна уметь их все находить, и открывать).

Автор: Akella 23.4.2007, 08:40
Цитата(Vladimir_K @  22.4.2007,  13:30 Найти цитируемый пост)
я не смог применить Ваш код (исправить "ошибки", которые вывалила моя Delphi7 на Ваш код), сколько я с ним не бился 

какие именно ошибки?

наверное тебе так нужно сделать:
в верху юнита, есть раздел private

объяви там процедуру, и обрати внимание на TForm1 - замени на свою форму
Код

  private
    { Private declarations }
     Procedure ScanFilder(Dir:String);
...
...
  public
    { Public declarations }
...

implementation

{$R *.dfm}


Procedure TForm1.ScanFilder(Dir:String);
Var
 SearchRec:TSearchRec;
begin
 try
   if Dir<>'' then Dir:=IncludeTrailingPathDelimiter(Dir);
   if FindFirst(Dir+'*.*', faAnyFile, SearchRec)=0 then//если что-то нашли
     repeat
       if (SearchRec.name='.') or (SearchRec.name='..') then continue;//если это не каталоги и не файлы, то пропускаем
       if ((SearchRec.Attr and faDirectory)<>0) then//
         ScanFilder(Dir+SearchRec.name) //нашли папку и вызываем опять саму себя - рукурсия называется
       else  begin//если попалась не папка, а файл, то вот он родной, нужно узнать расширение
             
           if AnsiUpperCase(ExtractFileExt(SearchRec.name)) = '.RTF' then   EditFile(Dir+SearchRec.name);//если расширение "наше", то вызываем функцию EditFile(), а вот уже эту функцию пиши сам, никто не знает точно что ты в ней будешь делать!!!
       end;//else
     until FindNext(SearchRec)<>0;
   FindClose(SearchRec);//заканчиваем поиск
 finally
   //
 end;
end;

Автор: Vladimir_K 23.4.2007, 10:17
Так, это сделал:
Код

private
    { Private declarations }
     Procedure ScanFilder(Dir:String);

Теперь набросок того, что по-моему должно быть:
Код

//==============================================================================
procedure TForm1.Button1Click(Sender: TObject);//По нажатию этой кнопки открывается папка (со вложенными папками с файлами), файлы обрабатываются, и сохраняются.
begin
 ScanFilder(Dir);
end;

procedure EditFile(Dir+SearchRec.name);
begin
 RichEdit1.Lines.LoadFromFile(F.Name);         //Отобразить содержимое файла

//Здесь мой код обработки файла...

 RichEdit2.Lines.SaveToFile(F.Name);           //Сохранение файла
end;

Procedure ScanFilder(Dir:String);
Var
 SearchRec:TSearchRec;
begin
 try
  if Dir<>'' then Dir:=IncludeTrailingPathDelimiter(Dir);
  if FindFirst(Dir+'*.*', faAnyFile, SearchRec)=0 then//если что-то нашли
   repeat
    if (SearchRec.name='.') or (SearchRec.name='..') then continue;//если это не каталоги и не файлы, то пропускаем
    if ((SearchRec.Attr and faDirectory)<>0) then//
         ScanFilder(Dir+SearchRec.name) //нашли папку и вызываем опять саму себя - рукурсия называется
     else
      begin//если попалась не папка, а файл, то вот он родной, нужно узнать расширение
       if AnsiUpperCase(ExtractFileExt(SearchRec.name)) = '.TXT' then EditFile(Dir+SearchRec.name);//если расширение "наше", то вызываем функцию EditFile(), а вот уже эту функцию пиши сам, никто не знает точно что ты в ней будешь делать!!!
      end;//else
   until FindNext(SearchRec)<>0;
  FindClose(SearchRec);//заканчиваем поиск
 finally
   //
 end;
end;
//==============================================================================

Как правильно написать обработчик Button1Click?
EditFile(Dir+SearchRec.name), наверное надо написать процедурой, а не функцией?

Автор: Akella 24.4.2007, 08:08
Код


private
    { Private declarations }
     Procedure ScanFolder(Dir:String);
     procedure EditFile(FileName:string);
......


implementation

....
procedure TfmMain.EditFile(FileName:string);
begin
 RichEdit1.Lines.LoadFromFile(FileName);         //ЗАГРУЗИТЬ содержимое файла

//Здесь мой код обработки файла...

 RichEdit2.Lines.SaveToFile(FileName);           //Сохранение файла
end

Procedure TfmMain.ScanFolder(Dir:String);
Var
 SearchRec:TSearchRec;
begin
 try
  if Dir<>'' then Dir:=IncludeTrailingPathDelimiter(Dir);
  if FindFirst(Dir+'*.*', faAnyFile, SearchRec)=0 then//если что-то нашли
   repeat
    if (SearchRec.name='.') or (SearchRec.name='..') then continue;//если это не каталоги и не файлы, то пропускаем
    if ((SearchRec.Attr and faDirectory)<>0) then//
         ScanFilder(Dir+SearchRec.name) //нашли папку и вызываем опять саму себя - рукурсия называется
     else
      begin//если попалась не папка, а файл, то вот он родной, нужно узнать расширение

       if AnsiUpperCase(ExtractFileExt(SearchRec.name)) = '.TXT' then EditFile(Dir+SearchRec.name);

      end;//else
   until FindNext(SearchRec)<>0;
  FindClose(SearchRec);//заканчиваем поиск
 finally
   //
 end;
end;



Добавлено через 2 минуты и 26 секунд
Но я бы на твоём месте не делал так в цикле, а в цикле (FindeFolder(....) ) загрузил бы в список все найденные файлы, и показал бы пользователю список. Пусть сам выбирает.

Автор: Vladimir_K 24.4.2007, 18:13
Ура, заработало! smile 
Спасибо, Akella, огромное!
А пользователь у этой программы один будет - я, так что все путём!  smile 

P.S. Совсем забыл спросить: как в DRKB искать фразу целиком? А то я ввожу фразу для поиска, а оно мне винегрет из отдельных слов находит...

Автор: Martisha 25.11.2008, 09:01
e у ня похожаяситуация, только у меня папка уже известна из которой текстовые файлы берутся, это папка каждый час обновляется..что мне поменять нужно в этом коде? т.е. задача загрузить из известной папки текстовые файлы в эдит, ну и обработать их потом.. 

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