Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Добавить колонку в ДБ-грид, если там уже есть результат SQL-запро [D7, WinXP]


Rat ©   (2005-06-09 08:40:00) 

Грид связан с датасетом, вызывающим рез-т SQL-запроса(в AdoQuery или AdoStoredProc). После того, как содержимое этого SQL датасета отобразится в гриде, могу ли я в этот грид еще добавлять колонки? Просто когда их начинаю добавлять, то показываются только эти новые,( а старые исчезают) . Или единственный выход- добавлять эту колонку в запрос? Не хотелось бы, т.к. мне она нужна для помечания записей для дальнейшей обработки(т.е. от запроса эта колонка не должна зависеть).


Desdechado   (2005-06-10 11:06:00) [1]

2 AP
зачем так категорично?

2 Rat
Для такой цели вообще в гриде мультиселект придумали - выбирается много записей, а потом цикл по их букмаркам и все.

2 AP
А первичный ключ может быть ведь длинным (или из нескольких полей), причем для разных выборок он разный - зачем огород городить?
Хотя любителям - простор для выращивания багов :)


Anatoly Podgoretsky   (2005-06-10 09:55:00) [2]

Rat   (10.06.05 02:23) [8]
bookmark фтопку
Есть первичные ключи


evvcom   (2005-06-10 09:27:00) [3]


> что-то типа этого не знаю может быть можно сделать как то
> проще..

Можно проще. Для этого делаешь свой компонент:

 TMyStoredProc = class(TAnyStoredProc)
 private
   FOnCreateFields: TDataSetNotifyEvent;
 protected
   procedure CreateFields; override;
 public
   function CreateCalcField(FieldName: string; DataType: TFieldType): TField;
 published
   property OnCreateFields: TDataSetNotifyEvent read FOnCreateFields write FOnCreateFields;
 end;

procedure TMyStoredProc.CreateFields;
begin
 inherited;
 if Assigned(FOnCreateFields) then
   FOnCreateFields(Self);
end;

function TMyStoredProc.CreateCalcField(FieldName: string;
 DataType: TFieldType): TField;
var l_FieldClass: TFieldClass;
begin
 l_FieldClass := GetFieldClass(DataType);
 if Assigned(l_FieldClass) then begin
   Result := l_FieldClass.Create(Self);
   Result.FieldName := FieldName;
   Result.FieldKind := fkCalculated;
   Result.DataSet   := Self;
 end
 else
   Result := nil;
end;

Вешаешь обработчик на OnCreateFields, в нем и вызываешь CreateCalcField. Все поля уже будут созданы, ты добавляешь только те, которые тебе нужны (или удаляешь :))


Rat   (2005-06-10 07:58:00) [4]

Уникальный ID- это поле из запроса или у грида тоже есть какие-то ID?. Просто поначалу мне хотелось, чтобы этот процесс не зависел от запроса(этот ID у разных таблиц может по разному называться). Но придется думаю так и сделать. Никто от меня универсальности пока и не требует. Если что, с дополнительной колонкой поэксперементирую.
Спасибо всем за советы.


ORMADA   (2005-06-10 07:23:00) [5]

//А данные об этом bookmark что-ли никак нельзя сохранить(в //массив какой-нить) для последующего использования.
легко сделай Tlist и храни там указатели на букмарки
но видишь ли букмарки такая вещь непостоянна закрыл/открыл датасет - можешь их выкидывать
а лучше хранить в массиве идентификатор записи (код однозначно идентифицирующий запись) а потом по нему локейтить к примеру
----------------------------------------------------------------
режим кеширования у адо квери к примеру выставляешь LockType=ltBatchOptimistic это означает что данные находятся в режиме кэширования и всякие операции типа delete INSERT и т.д. не идут в бд пока не будут подтверждены (ADOStoredProc.UpdateBatch;) или отменены (ADOStoredProc.CancelBatch)
----------------------------------------------------------------
ну если не хочешь колонку пусть пользователь выбирает у тя записи как нить а ты сохраняй идентификаторы их (к примеру уникальный код однозначно идентифицирующий запись) а потом их можно будет не в цикле удалить все а послал серверу команду типа delete FROM t1 WHERE код IN (идентификаторы записи через ',' к примеру '1,2,3')


Rat   (2005-06-10 02:23:00) [6]

А данные об этом bookmark что-ли никак нельзя сохранить(в массив какой-нить) для последующего использования.
У меня тут был уже топик в другом разделе, но его закрыли.
Суть проблемы вообще была такая- Надо чтобы в рамках текущего сеанса работы с dbgrid'ом юзер мог помечать записи на удаление- то есть выбрал, нажал на кнопку, они пометились(напр желтым цветом). Потом, напр. выбрал другие записи и добавил в список удаления(или убрал какие-то записи из списка). А потом, по нажатию на кнопку эти помеченные записи должны удаляться.
(Сейчас программа работает просто- выделил записи, нажал на кнопку, =>цикл по bookmark, они удаляются)
Вот и вопрос- кроме как вводить доп. колонку булевского типа, другого выхода нет?
P/S действительно, что значит открывать в режиме кэширования?


Desdechado   (2005-06-09 11:34:00) [7]

указатели - это TBookMark, он коректен только в текущей выборке
можно использовать, в принципе, но нужно ли - решает каждый сам


Mikle   (2005-06-09 11:17:00) [8]

ORMADA скажи пожалуйста что это значит
открывай таблицы в режиме кэширования


ORMADA   (2005-06-09 10:04:00) [9]

указатель на строки - гон какой то :)
и чё они тебе дадут ?
как с их помощью ты даш юзеру возможность юзеру выбрать записи ?

можно хранить канешна идентификаторы поля из таблицы (уникальное какое нить нить поле однозначно определяющее запись) и потом по нему позиционироваться а большего от них ты не получишь ...


Rat   (2005-06-09 09:42:00) [10]

спасибо, попробую.
Кто-то мне кстати здесь посоветовал вместо введения дополнительного поля сохранять в какой-нить массив указатели на строки грида. А как получить этот указатель на строку ? И возможно ли это вообще?


ORMADA   (2005-06-09 09:29:00) [11]

к датасету в дизайн тайме можно сделать его так выбираешь датасет делаешь правый клик\ New Field\Field Type =Calculated

в рантайме тож легко замутить
делаешь к примеру булевое поле

           with TBooleanField.Create(MainDataSet) do
           begin
             FieldKind := fkData;
             FieldName := MainQuery.Fields.Fields[i].FieldName;
             DataSet := MainDataSet;
             Name := DataSet.Name + 'Fields' + IntToStr(i);
             MainDataSet.FieldDefs.Add(name, ftBoolean);
           end;

и ставишь ему тип calcaluted

из за того что все поля прибиваются если они не были заданы явно приходится ручками переносить эти поля из какого нить временного дасасета, а потом уж добавлять calculated
что-то типа этого не знаю может быть можно сделать как то проще..

   //--- Переносим все поля из MainQuery в MainDataSet ---begin----------------
   for i := 0 to MainQuery.FieldCount - 1 do
     case MainQuery.Fields.Fields[i].DataType of

       ftAutoInc:
         begin
           with TAutoIncField.Create(MainDataSet) do
           begin
             FieldKind := fkData;
             ReadOnly := True;
             FieldName := MainQuery.Fields.Fields[i].FieldName;
             DataSet := MainDataSet;
             Name := DataSet.Name + 'Fields' + IntToStr(i);
             MainQuery.FieldDefs.Add(name, ftAutoInc);
           end;
         end;

       ftWord: //--- он же tinyint ---
         begin
           with TWordField.Create(MainDataSet) do
           begin
             FieldKind := fkData;
             FieldName := MainQuery.Fields.Fields[i].FieldName;
             DataSet := MainDataSet;
             Name := DataSet.Name + 'Fields' + IntToStr(i);
             MainQuery.FieldDefs.Add(name, ftWord);
           end;
         end;

       ftInteger:
         begin
           with TIntegerField.Create(MainDataSet) do
           begin
             FieldKind := fkData;
             FieldName := MainQuery.Fields.Fields[i].FieldName;
             DataSet := MainDataSet;
             Name := DataSet.Name + 'Fields' + IntToStr(i);
             MainQuery.FieldDefs.Add(name, ftInteger);
           end;
         end;

       ftSmallint:
         begin
           with TSmallintField.Create(MainDataSet) do
           begin
             FieldKind := fkData;
             FieldName := MainQuery.Fields.Fields[i].FieldName;
             DataSet := MainDataSet;
             Name := DataSet.Name + 'Fields' + IntToStr(i);
             MainQuery.FieldDefs.Add(name, ftSmallint);
           end;
         end;

       ftBCD:
         begin
           with TBCDField.Create(MainDataSet) do
           begin
             FieldKind := fkData;
             FieldName := MainQuery.Fields.Fields[i].FieldName;
             DataSet := MainDataSet;
             Name := DataSet.Name + 'Fields' + IntToStr(i);
             MainQuery.FieldDefs.Add(name, ftBCD);
           end;
         end;

       ftString:
         begin
           with TStringField.Create(MainDataSet) do
           begin
             FieldKind := fkData;
             FieldName := MainQuery.Fields.Fields[i].FieldName;
             DataSet := MainDataSet;
             Name := DataSet.Name + 'Fields' + IntToStr(i);
             Size := MainQuery.Fields.Fields[i].Size;
             DisplayWidth := MainQuery.Fields.Fields[i].Size;
             MainDataSet.FieldDefs.Add(name, ftString);
           end;
         end;

       ftDateTime:
         begin
           with TDateField.Create(MainDataSet) do
           begin
             FieldKind := fkData;
             FieldName := MainQuery.Fields.Fields[i].FieldName;
             DataSet := MainDataSet;
             Name := DataSet.Name + 'Fields' + IntToStr(i);
             MainDataSet.FieldDefs.Add(name, ftDate);
           end;
         end;

       ftFloat:
         begin
           with TFloatField.Create(MainDataSet) do
           begin
             FieldKind := fkData;
             FieldName := MainQuery.Fields.Fields[i].FieldName;
             DataSet := MainDataSet;
             Name := DataSet.Name + 'Fields' + IntToStr(i);
             MainDataSet.FieldDefs.Add(name, ftFloat);
           end;
         end;

       ftBytes:
         begin
           with TBytesField.Create(MainDataSet) do
           begin
             FieldKind := fkData;
             FieldName := MainQuery.Fields.Fields[i].FieldName;
             DataSet := MainDataSet;
             Name := DataSet.Name + 'Fields' + IntToStr(i);
             MainDataSet.FieldDefs.Add(name, ftBytes);
           end;
         end;

       ftBoolean:
         begin
           with TBooleanField.Create(MainDataSet) do
           begin
             FieldKind := fkData;
             FieldName := MainQuery.Fields.Fields[i].FieldName;
             DataSet := MainDataSet;
             Name := DataSet.Name + 'Fields' + IntToStr(i);
             MainDataSet.FieldDefs.Add(name, ftBoolean);
           end;
         end;
     end;
   //--- Переносим все поля из MainQuery в MainDataSet ---end-----------------


Rat   (2005-06-09 09:22:00) [12]

Что за вычисляемое поле- к чему оно относится- к гриду,  к запросу,  или к таблицам, фигурирующим в запросе ?


ORMADA   (2005-06-09 09:06:00) [13]

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


Наверх

Титульная страница Поиск, карта сайта Написать письмо