Модераторы: Poseidon, Snowy, bems, MetalFan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Автоматическая сортировка StringGrid, Интересный финт!!! 
:(
    Опции темы
Slawanix
  Дата 2.8.2004, 02:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 177
Регистрация: 29.7.2004
Где: г. Великие Луки

Репутация: нет
Всего: 1



Ну очень интересный вопрос:
Я загружаю в StringGrid одинаковые имена файлов, которые находятся в разных каталогах,
отображается только одно имя, хоть код и добавляет второе аналогичное имя файла из другого каталога.
Если у кого-то возникнет вопрос: может быть я не подготовил строку в таблице, отвечаю - подготовил, но строка появляется пустой.
Еще заметил одну особенность: при загрузке имен файлов они автоматом поалфавиту сортируются, может быть здесь собака зарыта, но тогда как енто вырубить?
Загрузка имен следующим образом:
Код
StringGrid.Cells[0,i]:=SearchRec.Name;
в цикле withstupid.gif

Это сообщение отредактировал(а) Slawanix - 2.8.2004, 02:17
--------------------
моск кипит    
PM MAIL WWW   Вверх
Dynamic
Дата 2.8.2004, 06:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 372
Регистрация: 5.7.2004
Где: Салехард

Репутация: 12
Всего: 15



Slawanix
Цитата
при загрузке имен файлов они автоматом поалфавиту сортируются,

StringGrid ничего сам не сортирует, файлы добавляются в том порядке, в каком их находят FindFirst/FindNext (при тестировании получалось, что по дате создания).
Цитата
отображается только одно имя

Не смог воспроизвести:
Код
procedure TForm1.Button1Click(Sender: TObject);
var SR: TSearchRec;
begin
    StringGrid1.RowCount := 0;
    if FindFirst(GetCurrentDir + '\*.*', faAnyFile, SR) = 0 then
    try
    repeat
      if SR.Name[1] = '.' then Continue;
      StringGrid1.RowCount := StringGrid1.RowCount + 1;
      StringGrid1.Cells[0, StringGrid1.RowCount-2] := SR.Name;
      // добавляем одинаковые имена файлов
      StringGrid1.RowCount := StringGrid1.RowCount + 1;
      StringGrid1.Cells[0, StringGrid1.RowCount-2] := SR.Name;
    until FindNext(SR) <> 0;
    finally
      FindClose(SR);
    end;
end;

Давай свой код.


--------------------
Было бы о чем молчать, а уж что сказать – всегда найдется...
PM MAIL WWW   Вверх
Slawanix
Дата 2.8.2004, 22:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 177
Регистрация: 29.7.2004
Где: г. Великие Луки

Репутация: нет
Всего: 1



Все, я разобрался: дело действительно было не в таблице а в коде, просто функция поиска файлов была рекурсивной и та самая i обнулялась в начале функции, поэтому при рекурсивном обращении она снова обнулялась и запись в таблицу не добавлялась а начиналась с начала, так как StrigGrid[0,i]=StringGrid[0,0]

Спасибо!

Говорила мне мама - не прыгай с девятого этажа! biggrin.gif biggrin.gif biggrin.gif
--------------------
моск кипит    
PM MAIL WWW   Вверх
Slawanix
Дата 3.8.2004, 00:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 177
Регистрация: 29.7.2004
Где: г. Великие Луки

Репутация: нет
Всего: 1



Цитата(Dynamic @ 2.8.2004, 06:51)
Давай свой код.

полностью рабочая процедура, но так как это для синхронизатора файлов,
то предполагается две таблицы.Переменая i инициализируется вне функции(т.е. i:=0).
В ее составлении мне помогли FAQ Vit'a и Guest(та часть, где идет рекурсивный поиск файлов)

Код

//функция сканирования и отбора файлов
Procedure ScanDir(Dir,Dir2:String;Grid:TStringGrid);
var DateDos:Integer;{в переменную записывается дата последнего изменения файла}
begin{Начало процедуры}{1}
{Если имя каталога существует и не равно '' или'\', тогда
добавляем к имени каталога '\', чтобы войти в его корень}
if Dir<>'' then if Dir[length(Dir)]<>'\' then Dir:=Dir+'\';
if Dir2<>'' then if Dir2[length(Dir2)]<>'\' then Dir2:=Dir2+'\';
{если в корне этого каталога есть к-либо файл, тогда...}
if FindFirst(Dir+'*.*', faAnyFile, SearchRec)=0 then
BEGIN{...}
 repeat{выполняем следующую операцию}{2}
 {если имя любого найденного файла содержит только'.' или '..' -то
 проходим дальше, ничего не совершая, к следующим файлам, если такие есть}
 if (SearchRec.name='.') or (SearchRec.name='..') then continue;
 {если атрибуты этих файлов "Директория" тогда...}
 if (SearchRec.Attr and faDirectory)<>0 then
  begin{3}
    ScanDir(Dir+SearchRec.Name,Dir2+SearchRec.Name,Grid); {мы нашли директорию:
     "Dir+SearchRec.name", которую будем сканировать рекурсивным вызовом функции ScanDir}
  end {3}{if (SearchRec.Attr and faDirectory)<>0 then}
 else {Если атрибуты этих файлов не "Директория, тогда...}
 Showmessage('Мы нашли файл '+Dir+SearchRec.name); //мы нашли файл: "Dir+SearchRec.name"
 i:=i+1;
 {Если такой же файл существует в противоположной папке, тогда...}
 ShowMessage('проверяю наличие файла в папке '+ Dir2+SearchRec.Name);
 if FileExists(Dir2+SearchRec.Name)=True then
  BEGIN{4}
    ShowMessage('Файл '+ Dir+SearchRec.name+'  
в папке '+Dir2+SearchRec.Name+' есть');
    {Находим и записываем данные этого файла в промежуточную файловую переменную NF}
    FindFirst(Dir2+SearchRec.Name,faAnyFile, NF);
    {и определяем время последнего изменения этого файла в формате DOS}
    DateDos:=NF.Time;
    FindClose(NF);
    {Производим сравнение двух дат: файла с именем SearchRec.Name с найденным выше файлом}
    //Если дата файла с именем SearchRec.Name БОЛЬШЕ даты найденнго файла, значит он НОВЕЙ
    // и его добавляем в таблицу
    if SearchRec.Time>DateDos then
     BEGIN{5}
     ShowMessage('Добавляю Файл '+ Dir+SearchRec.name+'  в папку '+Dir2+SearchRec.Name);
      //количество строк в таблице прибавляем с каждым добавляемым файлом
      Grid.RowCount:=Grid.RowCount+1;
      {Записываем в таблицу атрибуты файла}
      Grid.Cells[0,i]:=SearchRec.Name;
      Grid.Cells[1,i]:=(DateToStr(FileDateToDateTime(SearchRec.Time))+
      '  '+TimeToStr(FileDateToDateTime(SearchRec.Time)));
      Grid.Cells[2,i]:=IntToStr(SearchRec.Size);
      Grid.Cells[3,i]:=ExtractFileDir(Dir+SearchRec.Name);
      Grid.Cells[4,i]:=Dir2;
     END;{5}
   END{4}
   {Если совпадений файлов нет, то их тоже добавляем в таблицу}
    else
     begin{6}
     ShowMessage('Файла '+ Dir+SearchRec.name+'  в папке '+Dir2+SearchRec.Name+' нет');
     ShowMessage('Добавляю Файл '+ Dir+SearchRec.name+'  в папку '+Dir2+SearchRec.Name);
     //количество строк в таблице прибавляем с каждым добавляемым файлом
      Grid.RowCount:=Grid.RowCount+1;
      Grid.Cells[0,i]:=SearchRec.Name;
      Grid.Cells[1,i]:=(DateToStr(FileDateToDateTime(SearchRec.Time))+
      '  '+TimeToStr(FileDateToDateTime(SearchRec.Time)));
      Grid.Cells[2,i]:=IntToStr(SearchRec.Size);
      //путь каталога-источника
      Grid.Cells[3,i]:=ExtractFilePath(Dir+SearchRec.Name);
      //путь каталога-назначения
      Grid.Cells[4,i]:=Dir2;
     end;{6}
 until FindNext(SearchRec)<>0;
END{...};
 FindClose(SearchRec);
 Grid.RowCount:=Grid.RowCount-1;
end;{1}


Это сообщение отредактировал(а) Slawanix - 3.8.2004, 00:16
--------------------
моск кипит    
PM MAIL WWW   Вверх
p0s0l
Дата 3.8.2004, 18:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Г-н Посол
****


Профиль
Группа: Экс. модератор
Сообщений: 3668
Регистрация: 13.7.2003
Где: 58°38' с.ш. 4 9°41' в.д.

Репутация: 58
Всего: 112



Комментариев больше, чем кода... smile.gif Ты всегда так пишешь ?



--------------------
С уважением, г-н Посол.
PM   Вверх
Slawanix
Дата 3.8.2004, 23:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 177
Регистрация: 29.7.2004
Где: г. Великие Луки

Репутация: нет
Всего: 1



Цитата
Комментариев больше, чем кода... Ты всегда так пишешь ?

Уважаемый г-н Посол,вы совершенно правы: пояснений действительно больше чем достаточно, но отчасти, это из-за того что это отладочная функция, где эти к-ии(которые я не нашел времени удалить) и сообщения больше для моего теста, но не для юзеров; а ,отчасти, чтобы избежать, быть может, лишних распросов. Но в out-версиях присутствует только самое необходимое(код и минимум коментов).
smile.gif С уважением, Slawanix.

P.S. Хотелось бы узнать Ваше мнение и замечания по поводу этой процедуры.

Говорила мне мама - не прыгай с девятого этажа hehe.gif hehe.gif hehe.gif
--------------------
моск кипит    
PM MAIL WWW   Вверх
p0s0l
Дата 4.8.2004, 01:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Г-н Посол
****


Профиль
Группа: Экс. модератор
Сообщений: 3668
Регистрация: 13.7.2003
Где: 58°38' с.ш. 4 9°41' в.д.

Репутация: 58
Всего: 112



Посмотрел я функцию, потестил - сравнил папку текущего проекта и папку backup'а, сделанного несколько месяцев назад, выдало всего пару файлов...
Вообще, странно, что в теле функции не объявлены переменные SearchRec и NF... Я так понял - они глобальные ? Хотя SearchRec обязательно должна быть локальной... Т.е. начало процедуры должно быть таким:
Код
Procedure ScanDir(Dir,Dir2:String; Grid:TStringGrid);
var
 DateDos:Integer;
 SearchRec, NF : TSearchRec;
Иначе при рекурсивном вызове SearchRec испортится... Теперь у меня выдало намного больше файлов...

Далее...
С переменной i тоже не очень ясно: она увеличивается независимо от увеличения Grid.RowCount, и если FileExists = True, но Time<=DateDos, то i увеличится зазря, я так понимаю... Ну короче, у меня на экране не все ряды в StringGrid'е были заполнены, были пропуски... Я бы на твоём месте сделал вместо Grid[x, i] := ... так: Grid[x, Grid.RowCount-1] := ...

Далее...
Код
(DateToStr(FileDateToDateTime(SearchRec.Time))+ '  '+TimeToStr(FileDateToDateTime(SearchRec.Time)))
можно легче:
Код
DateTimeToStr(FileDateToDateTime(SearchRec.Time))

Тоже упростить можно это:
Код
ExtractFileDir(Dir+SearchRec.Name);
так smile.gif:
Код
Dir

И это тоже можно упростить:
Код
   FindFirst(Dir2+SearchRec.Name,faAnyFile, NF);
   {и определяем время последнего изменения этого файла в формате DOS}
   DateDos:=NF.Time;
   FindClose(NF);
Так:
Код
DateDos := FileAge(Dir2 + SearchRec.Name)

Что еще ?... В процедуре есть 2 одинаковые части добавления инфы в Grid - так и напрашивается вынести это отдельно. Например так:
Код

if (not FileExists(Dir2+SearchRec.Name)) or
  (SearchRec.Time > FileAge(Dir2 + SearchRec.Name)) then .. добавляем файл в Grid


В итоге получается типа такого:
Код
Procedure ScanDir(Dir, Dir2:String; Grid:TStringGrid);
var SearchRec : TSearchRec;
begin
 if Dir<>'' then if Dir[length(Dir)]<>'\' then Dir:=Dir+'\';
 if Dir2<>'' then if Dir2[length(Dir2)]<>'\' then Dir2:=Dir2+'\';
 if FindFirst(Dir+'*.*', faAnyFile, SearchRec)=0 then
 repeat
   if (SearchRec.name='.') or (SearchRec.name='..') then Continue;
   if (SearchRec.Attr and faDirectory)<>0 then
     ScanDir(Dir+SearchRec.Name, Dir2+SearchRec.Name, Grid)
   else
     if (not FileExists(Dir2+SearchRec.Name)) or
        (SearchRec.Time > FileAge(Dir2 + SearchRec.Name)) then
     begin
       Grid.Cells[0,Grid.RowCount-1] := SearchRec.Name;
       Grid.Cells[1,Grid.RowCount-1] := DateTimeToStr(FileDateToDateTime(SearchRec.Time));
       Grid.Cells[2,Grid.RowCount-1] := IntToStr(SearchRec.Size);
       Grid.Cells[3,Grid.RowCount-1] := Dir;
       Grid.Cells[4,Grid.RowCount-1] := Dir2;
       Grid.RowCount:=Grid.RowCount+1;
     end;
 until FindNext(SearchRec)<>0;
 FindClose(SearchRec);
end;






--------------------
С уважением, г-н Посол.
PM   Вверх
Dynamic
Дата 4.8.2004, 06:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 372
Регистрация: 5.7.2004
Где: Салехард

Репутация: 12
Всего: 15



Еще вместо:
Код
if Dir<>'' then if Dir[length(Dir)]<>'\' then Dir:=Dir+'\';
if Dir2<>'' then if Dir2[length(Dir2)]<>'\' then Dir2:=Dir2+'\';

можно использовать функции из SysUtils:
Код

Dir := IncludeTrailingBackslash(Dir);
Dir2 := IncludeTrailingBackslash(Dir2);
// или
Dir := IncludeTrailingPathDelimiter(Dir);
Dir2 := IncludeTrailingPathDelimiter(Dir2);

имхо, второй вариант производительнее, т.к. на один вызов процедуры меньше (при использовании в рекурсивном алгоритме это может дать определенный выигрыш).


--------------------
Было бы о чем молчать, а уж что сказать – всегда найдется...
PM MAIL WWW   Вверх
p0s0l
Дата 4.8.2004, 14:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Г-н Посол
****


Профиль
Группа: Экс. модератор
Сообщений: 3668
Регистрация: 13.7.2003
Где: 58°38' с.ш. 4 9°41' в.д.

Репутация: 58
Всего: 112



А вместо:
Код
if (not FileExists(Dir2+SearchRec.Name)) or
       (SearchRec.Time > FileAge(Dir2 + SearchRec.Name)) then
Можно вообще так:
Код
if (SearchRec.Time > FileAge(Dir2 + SearchRec.Name)) then
т.к. FileAge возвратит -1, если файла нет...



--------------------
С уважением, г-н Посол.
PM   Вверх
Dynamic
Дата 4.8.2004, 14:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 372
Регистрация: 5.7.2004
Где: Салехард

Репутация: 12
Всего: 15



tounge.gif Ну и тогда уж вместо
Код
    if (not FileExists(Dir2+SearchRec.Name)) or
       (SearchRec.Time > FileAge(Dir2 + SearchRec.Name)) then
    begin
      Grid.Cells[0,Grid.RowCount-1] := SearchRec.Name;
      Grid.Cells[1,Grid.RowCount-1] := DateTimeToStr(FileDateToDateTime(SearchRec.Time));
      Grid.Cells[2,Grid.RowCount-1] := IntToStr(SearchRec.Size);
      Grid.Cells[3,Grid.RowCount-1] := Dir;
      Grid.Cells[4,Grid.RowCount-1] := Dir2;
      Grid.RowCount:=Grid.RowCount+1;
    end;

пишем
Код
    if (SearchRec.Time > FileAge(Dir2 + SearchRec.Name)) then
    with Grid do
    begin
      Cells[0,RowCount-1] := SearchRec.Name;
      Cells[1,RowCount-1] := DateTimeToStr(FileDateToDateTime(SearchRec.Time));
      Cells[2,RowCount-1] := IntToStr(SearchRec.Size);
      Cells[3,RowCount-1] := Dir;
      Cells[4,RowCount-1] := Dir2;
      RowCount:=RowCount+1;
    end;

В умной книжке прочитал, что обращение к полям класса при помощи with...do происходит чуть быстрее, чем через точку, ну и текста поменьше. biggrin.gif


--------------------
Было бы о чем молчать, а уж что сказать – всегда найдется...
PM MAIL WWW   Вверх
Slawanix
Дата 4.8.2004, 18:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 177
Регистрация: 29.7.2004
Где: г. Великие Луки

Репутация: нет
Всего: 1



Цитата
С переменной i тоже не очень ясно: она увеличивается независимо от увеличения Grid.RowCount, и если FileExists = True, но Time<=DateDos, то i увеличится зазря

Да, с этим казусом я при тесте тоже столкнулся и исправил так:
Код

Grid.RowCount:=Grid.RowCount+1;
i:=i+1;

то есть есть i меняется вместе со строками.
Остальное пошел переваривать, чего и говорить, сыроватый код выдал, спасибо огромное за соображения, есть над чем подумать и исправить.

Говорила мне мама - не прыгай с девятого этажа!
hehe.gif
--------------------
моск кипит    
PM MAIL WWW   Вверх
Петрович
Дата 13.8.2004, 15:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1000
Регистрация: 2.12.2003
Где: Москва

Репутация: 25
Всего: 55



Цитата(Dynamic @ 4.8.2004, 14:56)
В умной книжке прочитал, что обращение к полям класса при помощи with...do происходит чуть быстрее, чем через точку, ну и текста поменьше.

Умная книжка сильно устарела. Это было правдой для давних реализациях компиляторов Pascal. У Delphi, мозгов хватает самой так оптимизировать. Так-что теперь, with нужен лишь для получения более читабельного, компактного и красивого текста.
Добавлено @ 15:07
Цитата(Slawanix @ 3.8.2004, 23:47)
Но в out-версиях присутствует только самое необходимое(код и минимум коментов).

По моему, это зря. Они (комментарии) что, хлеба просят в out-версиях? smile.gif. Зато, через пару лет, даже сам заглянув в текст, быстро сможеш разобраться.
Лично я, никогда не удаляю уже написанных коментариев. Если они конечно написаны по делу.

Цитата(Slawanix @ 3.8.2004, 00:13)
но так как это для синхронизатора файлов

А синхронизатор похоже не отслеживает случаем когда в Dir2 имеются файлы, которые отсутствуют в Dir? Если в терминах Backup, то в Backup-копии (Dir2), файлы, удаленные с оригинала (Dir) останутся жить вечно smile.gif.


--------------------
Все знать невозможно, но хочется
PM ICQ   Вверх
Slawanix
Дата 14.8.2004, 16:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 177
Регистрация: 29.7.2004
Где: г. Великие Луки

Репутация: нет
Всего: 1



Цитата
А синхронизатор похоже не отслеживает случаем когда в Dir2 имеются файлы, которые отсутствуют в Dir? Если в терминах Backup, то в Backup-копии (Dir2), файлы, удаленные с оригинала (Dir) останутся жить вечно


Петрович , Нет, на самом деле процедура проверки директорий выполняется поочередно для каждой из папок, поэтому без внимания никто не остается. Последнее время я был в этом уверен.
Спасибо за сообщение я еще разок потестю, проверю.
rolleyes.gif
--------------------
моск кипит    
PM MAIL WWW   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1722 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.