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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 30.01.2018, 13:27   #1
Etsareva
Форумчанин
 
Регистрация: 26.01.2018
Сообщений: 180
По умолчанию сортировка

есть 2 dataseta с одинаковым набором данных (данные отображаются в DBGridEh). данные в одном Dataset сортируются с помощью процедуры procedure TMainForm.SortData. мне нужно таким же образом отсортировать данные в другом dataset. как мне ту же самую процедуру применить к этому dataset?
Etsareva вне форума Ответить с цитированием
Старый 30.01.2018, 13:45   #2
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

Цитата:
Сообщение от Etsareva Посмотреть сообщение
как мне ту же самую процедуру применить к этому dataset?
судя по всему - никак.
нужно изменять код процедуры так, чтобы он сортировал нужный датасет.

для начала покажите код процедуры TMainForm.SortData.

и, кстати, расскажите, почему нельзя сортировать в SQL запросе (см. ORDER BY .. )
Serge_Bliznykov вне форума Ответить с цитированием
Старый 30.01.2018, 13:47   #3
Etsareva
Форумчанин
 
Регистрация: 26.01.2018
Сообщений: 180
По умолчанию

Код:
procedure TMainForm.SortData;
type
     TSortItem = record
      Key: String;
      Values: Array of Variant;
     end;
     TSortItems = Array of TSortItem;

var
     I,J: Integer;
     DataSet: TClientDataSet;
     List: TStringList;
     BookMark: Integer;
     TmpStr,ProductName: String;
     FCount: Integer;
     FItems: TSortItems;
     FMaxParamCount: Integer;
     IndexFields: String;
     IsFloat: Boolean;
     F: Double;
     Prd: integer;
     Sort: string;

     function GetItemPos(Key: String): Integer;
     begin
          DataSet.First;
          For Result:= 0 to DataSet.RecordCount-1 do begin
           If DataSet.FieldByName('Key').AsString=Key
            then Exit;
           DataSet.Next;
          end;
          Inc(Result);
     end;

begin
    try
      //Временная сортировка (почему-то нужно сначала очистить, а потом определить ключ)
     SP.IndexFieldNames:= '';
      SP.IndexFieldNames:= 'ТипДетали;Обозначение;НаимИзделия;Документ';

      //Создать объекты
      DataSet:= TClientDataSet.Create(Application);
      List:= TStringList.Create;
      FItems:= nil;
      FCount:= 0;
      FMaxParamCount:= 0;

        SP.First;
      While not SP.Eof do begin
       // 1.Запомнить положение маркера
       BookMark:= SP.FieldByName('Nomer').AsInteger;

       // 2.По каким параметрам будет отбор для сортировки
      TmpStr:= SP.FieldByName('Документ').AsString;            //ГОСТ,ТУ
       ProductName:= SP.FieldByName('НаимИзделия').AsString;    //резистор,конденсатор

       // 3.Очистить хранилище: индексы,данные,наборы полей
       DataSet.IndexFieldNames:= '';
       If DataSet.Active then begin
        DataSet.EmptyDataSet;
        DataSet.FieldDefs.Clear;
        DataSet.Fields.Clear;
        DataSet.Close;
       end;
       FItems:= nil;
       FCount:= 0;
       FMaxParamCount:= 0;

       // 4.Ищем изделия в пределах одного документа, параметры для сортировки передаем в массив сортировки
       While (SP.FieldByName('Документ').AsString=TmpStr) and (SP.FieldByName('НаимИзделия').AsString=ProductName) and
       (not SP.Eof) do begin
        //увеличить массив
        SetLength(FItems, FCount+1);
        //поле "Наименование" в массив
        FItems[FCount].Key:= SP.FieldByName('Наименование').AsString;
        Sort:=SP.FieldByName('Документ').AsString;
        //разделить поле "ДляСортировки" на составляющие и записать в массив
        List.Text:= SP.FieldByName('ДляСортировки').AsString;
        //определить поле "Prd" для сортировки
        begin
        If List.Count>0 then begin
         //макс.кол-во параметров для сортировки
         If List.Count>FMaxParamCount
          then FMaxParamCount:= List.Count;
         SetLength(FItems[FCount].Values, List.Count);
         For I:= 0 to List.Count-1 do
          FItems[FCount].Values[I]:= List.Strings[I];
        end;
        end;

        //увеличить счетчик массива для сортировки
        Inc(FCount);
        //следующая запись
        SP.Next;
       end;

       // 5.Сортируем однотипные объекты (с одинаковым набором полей, т.е.принадлежащие одному документу)
       //   и возвращает порядок для каждого объекта:
       // 5.1.Подготовить DataSet
        DataSet.FieldDefs.Add('Key', ftString, 100);
       IndexFields:= '';
       IsFloat:= False;
       For I:= 0 to FMaxParamCount-1 do begin
        //проверяем, является ли текущий столбец числовым
        For J:= 0 to FCount-1 do
         If FItems[J].Values<>nil then
          If Length(FItems[J].Values)>=I then begin
           try  {--- это для правильной проверки ---}
            IsFloat:= TryStrToFloat(FItems[J].Values[I], F);
           except
            IsFloat:= False;
           end; {---}
           If not IsFloat
            then Break;
          end;
        //добавляем поле (числовое, или строковое)
        If IsFloat
         then DataSet.FieldDefs.Add('Field'+IntToStr(I), ftFloat)
         else DataSet.FieldDefs.Add('Field'+IntToStr(I), ftString, 20);
        IndexFields:= IndexFields+'Field'+IntToStr(I)+';';
       end;

       // 5.2.Датасет с нужной структурой создан, заносим данные
    DataSet.CreateDataSet;
       DataSet.IndexFieldNames:= '';
       DataSet.Active:= True;
       For I:= 0 to FCount-1 do begin
        DataSet.Append;
        DataSet.FieldByName('Key').AsString:= FItems[I].Key;
        For J:= 0 to FMaxParamCount-1 do
         If J<=Length(FItems[I].Values)-1
          then DataSet.FieldByName('Field'+IntToStr(J)).Value:= FItems[I].Values[J]
          else DataSet.FieldByName('Field'+IntToStr(J)).Value:= MaxDouble;
        DataSet.Post;
       end;

         // 6.Сортировка массива   ?????????????????????????????????? Здесь ошибка
       DataSet.IndexFieldNames:= IndexFields+'Key';

       // 7.Запись результата в исходный массив:
       //возвращаемся к первому объекту текущего документа
       SP.Locate('Nomer',BookMark,[]);
       //ищем и записываем результат
       For I:= 0 to DataSet.RecordCount-1 do begin
        SP.Edit;
        SP.FieldByName('ПорядокПоПараметрам').AsInteger:= GetItemPos(SP.FieldByName('Наименование').AsString);
        SP.Post;
        SP.Next;
       end;
      end;

     finally
      DataSet.Free;
      List.Free;
      FItems:= nil;
     end;
     // 8.Включаем индексацию
     SP.IndexFieldNames:= 'ТипДетали;Обозначение;PozName;НаимИзделия;Документ;ПорядокПоПараметрам';
end;
_____
К сожалению, на форуме нет тега [DELPHI], поэтому для форматирования кода программы пользуйтесь тегами [CODE] (читать FAQ)
Модератор

Последний раз редактировалось Serge_Bliznykov; 30.01.2018 в 13:55.
Etsareva вне форума Ответить с цитированием
Старый 30.01.2018, 13:52   #4
Etsareva
Форумчанин
 
Регистрация: 26.01.2018
Сообщений: 180
Сообщение

не могу сказать, почему не работает SQL-запрос, но он не работает. программу не я создавала, сейчас разбираюсь в исходнике. в БД запрос с order by отрабатывает хорошо.
Etsareva вне форума Ответить с цитированием
Старый 30.01.2018, 14:12   #5
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

извините, но я Вам вряд ли смогу помочь - кода много, он специфичен (не универсален), логика работы мне не понятна (при чём здесь ClientDataSet, например, или что такое SP - что за текущий документ? это не первый dataset, о котором идёт речь? он сортируется?)...
Короче, вопросов слишком много...
Извините.
Serge_Bliznykov вне форума Ответить с цитированием
Старый 30.01.2018, 14:16   #6
Etsareva
Форумчанин
 
Регистрация: 26.01.2018
Сообщений: 180
По умолчанию

да, это именно первый dataset, который сортируется.
Etsareva вне форума Ответить с цитированием
Старый 30.01.2018, 14:16   #7
Etsareva
Форумчанин
 
Регистрация: 26.01.2018
Сообщений: 180
По умолчанию

я Вас услышала, спасибо!
Etsareva вне форума Ответить с цитированием
Старый 30.01.2018, 14:31   #8
Serge_Bliznykov
Старожил
 
Регистрация: 09.01.2008
Сообщений: 26,229
По умолчанию

Цитата:
Сообщение от Etsareva Посмотреть сообщение
да, это именно первый dataset, который сортируется.
так попробуйте заменить на нужный датасет, например, попробуйте так:
Код:
procedure TMainForm.SortData(var SP : TDataSet);
это если у Вас оба датасета В ТОЧНОСТИ одинаковые, конечно.
Serge_Bliznykov вне форума Ответить с цитированием
Старый 30.01.2018, 14:36   #9
Etsareva
Форумчанин
 
Регистрация: 26.01.2018
Сообщений: 180
По умолчанию

dataset не идентичные по своему содержанию, я не могу заменить. причем, мне в обоих datasetax нужно сохранить сортировку...
Etsareva вне форума Ответить с цитированием
Старый 30.01.2018, 14:40   #10
Etsareva
Форумчанин
 
Регистрация: 26.01.2018
Сообщений: 180
По умолчанию

StandDS - dataset, который надо отсортировать, SP - отсортирован.
Изображения
Тип файла: png 1.png (37.3 Кб, 49 просмотров)
Etsareva вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Быстрая сортировка(сортировка Хоара). Сортировка фрагмента массива [C++] druger Помощь студентам 0 20.04.2012 15:49
Быстрая сортировка(сортировка хаора) с++ LustHunter Помощь студентам 3 07.10.2011 19:37
Сортировка массива методами предсортировки и слияния, и пирамидальная сортировка. lenny_24 Помощь студентам 2 17.04.2011 18:57
паскаль,одномерный массив,сортировка вставка,сортировка убывания,от максимального до конца немозг Помощь студентам 11 06.02.2010 21:57
Сортировка файлов в Explorer vs сортировка в Delphi mutabor Общие вопросы Delphi 11 04.09.2009 14:32