Процедура сортировки для двух разных таблиц

У меня возник такой неординарный вопрос, наверно, даже странный! на форме у меня есть 2 таблицы, данные в них отображаются из БД одни и те же. для одной таблицы у меня есть процедура сортировки, а для другой - нет, но для нее в принципе должна быть такая же сортировка, как и для первой. как-то можно объединить процедуру сортировки для обеих таблиц или нужно новую процедуру писать?
14 ответов

что такое "процедура сортировки"?так как вы в ветке по БД и пишите про таблицы, то таблицы сортируются SQL запросом конструкцией "order by ***" никаких процедур не нужно


том-то и дело, что сортировка происходит не sql запросом, а именно процедурой сортировки. Значит, мне в другую ветку надо


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


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: ******;
     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:= Max******;
        DataSet.Post;
       end;
 
       DataSet.IndexFieldNames:= IndexFields+'Key';
       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;
процедура сортировки для DATASET SP, мне нужно повторить ту же самую процедуру для DATASET StandDS? или можно объединить эту процедуру для двух DATASET ?


а откуда данные загружаете в DataSet?


из БД


а почему не query и SQL?


Sorry, вопроса не поняла, из
query
конечно.хотела бы узнать, можно ли адаптировать эту процедуру под 2 dataseta? и если да, то как?


почему вы не используете квери и SQL запросы? в запросе сортировка это 1 строказачем оббегать циклами датасеты?


программу не я писала, поэтому исходник сейчас изучаю и дорабатываю его. разработчик программы оставил коммент типа: "Простая сортировка не справится, пришлось обходится такой процедурой". но возникла необходимость отсортировать данные по такому же принципу и в другом dataset.


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


"Простая сортировка не справится, пришлось обходится такой процедурой"
Простите, это как так? SQL прекрасно справляется с сортировками выбранных данных самостоятельно по одному или нескольким полям. Так что разработчик что-то видать перед этим покурил серьезное... Используйте SQl- запрос и Order by, как писал qwertehok в ответе №2 и никаких больше процедур не нужно изобретать.


мне нужно повторить ту же самую процедуру для DATASET StandDS?
надо смотреть код, у вас там много чего - нужно проверять


drvolodko,
SELECT Stand.*,
       Gost.Gost_ID AS GostID, Gost.Name AS GostName,
       Okp.Okp_ID AS OkpID,Okp.Klass,Okp.Naim 
FROM standart.dbo.Stand,
     standart.dbo.Gost,
     standart.dbo.Okp
WHERE Stand.Gost_Id=Gost.Gost_Id AND Stand.Okp_Id=Okp.Okp_Id
ORDER BY Mark ASC
. такой запрос не сортирует в программе, но в бд сортирует