Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Lookup в обычном Grid'e


Автор: Serggggg 4.2.2004, 10:10
Доброе время суток.
Трабл такой - есть Grid, где надо использовать выпадающий список (Lookup). Для Grid'a Datasourse представляет собой запрос (TQuery) с опцией LiveRequest=True.
Согласно тому, что написано в книжке, я прописываю в конструкторе поля запроса. Теперь то поле, которое должно выпадать, я объявляю как fkLookup. Естественно, указан LookupDataSource (тоже запрос), прописаны поля (LookupKeyField - указан ID, LookupResultField - указано NAME).
Вроде бы все нормально. Но при компиляции и запуске в нужном поле Grid'a на самом деле ничего не выпадает, поле ведёт себя, как обычное поле.
Подскажите, если не сложно, где я ошибся. withstupid.gif

Автор: Serggggg 4.2.2004, 16:32
Люди, подскажите плизззз! Целый день с этой проблемой воюю. Неужели никто с таким не сталкивался? sad.gif butbut.gif

Автор: Medved 5.2.2004, 08:23
Ты просто сделал Lookup поле в наборе данных.
Если хочешь, чтобы выпадал список в DBGrid, то необходимо заполнить свойство PickList необходимого столбца DBGrid.

Автор: Serggggg 5.2.2004, 10:42
А этот PickList надо заполнять, присваивая строкам поля запроса?
Типа такого?

Grid1.Columns[j].PickList.Clear;
for i:=0 to Query1.RecordCount do
Grid1.Columns[j].PickList.Items.Add(Query1.Fields[k].Text);

Автор: x77 5.2.2004, 11:02
Serggggg, покажи код конструктора.

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

фишка видимо в том, что поле создаётся динамически, а список значений для лукапа не формируется. можно жёстко прописать заполнение LookupList'а (со включенным кэшированием, разумеется), тогда всё будет хорошо и к тому же производительность возрастает на порядок, т.к. значения берутся не из базы, но скорее всего, это решается и стандартно. прото надо посмотреть на код.

Автор: Medved 5.2.2004, 13:40
Да точно, что-то я запарился....

Автор: Serggggg 5.2.2004, 14:04
Привожу всё, что касается моего случая:
Grid: 6 полей для ввода. Из них 1 поле содержит Foreign Key (ID из другой таблицы) - оно и должно выпадать. Grid связан DataSet'ом с запросом (TQuery - назовём его Query1). Ещё один запрос представляет данные для LookUp'a (тоже TQuery - Query2).

Query1: выбирает данные по условию. Для него SQL.Text присваивается по ходу выполнения программы. Запрос имеет параметр RequestLive=True (для добавления и редактирования данных в Grid'e).

Query2: SQL.Text='SELECT field_ID, field_NAME from TableName1' на протяжении работы приложения (не меняется).

Поля запроса Query1 (жестко прописанные в редакторе полей):
1. поле ID
... (поля ввода обычных числовых данных - 5 полей)
7. поле, содержащее Foreign Key (должно выпадать)

Параметры инспектора объектов для поля#7:
FieldKind: fkLookup
FieldName: NVL_SIZE_ID
KeyFields: NVL_SIZE_ID
LookupDataSet: Query2
LookupKeyField: NVLSIZE_ID
Lookup ResultField: VNAME
Остальные параметры - по умолчанию.

Колонки Grid'a:
... 5 полей с числовой информацией (FieldName1,...,FieldName5),
поле с "выпадающим списком" (ButtonStyle = cbsAuto, Expanded заклинило на False, ReadOnly = True).

Результат - во время работы программы оба запроса активны, Grid заполнен, но поле с Lookup'ом не реагирует на ввод (курсор там мигает, но на нажатие клавиш не реагирует). А просто ведёт себя, как поле ввода, в которое ничего ввести нельзя.

Автор: x77 5.2.2004, 14:12
Цитата
Из них 1 поле содержит Foreign Key (ID из другой таблицы) - оно и должно выпадать.


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

Автор: Serggggg 5.2.2004, 14:39
Хорошо, меняю полю ID в конструкторе запроса значение FieldKind на fkData, добавляю новое поле VNAME:
FieldKind: fkLookup
KeyFields: NVL_SIZE_ID (т.е. в конструкторе полей запроса есть и поле NVL_SIZE_ID, и поле VNAME)
LookupDataSet: Query2
LookupKeyField: NVLSIZE_ID (это поле из запроса Query2)
LookupResultField: VNAME (тоже из Query2)
Из Grid'a убираем NVL_SIZE_ID, на место этой колонки ставим VNAME.

Результат тот же. Или же мне надо запрос для самого Grid'a переделать, чтобы там отображалось VNAME?
Извините, я задолбал, наверное, уже. Но мне очень надо в этом разобраться.

Автор: x77 5.2.2004, 14:47
ты проверил, другие поля редактируются?

допустим, есть два разных таблицы: Query1, Query2.

Query1
ID1 // ключевое
ID2 // foreign key
NAME1 // имя

Query2
ID2 // ключевое
NAME2 // имя

все поля объявляем статически (т.е. делаем Add в Fields Editor'е для обоих запросов). после этого там же, в Fields Editor'e, для Query1 опять делаем Add, выбираем тип строки - fkLookup, тип данных - соответствующий Query2.NAME2, далее:

LookupDataSet = Query2,
KeyFields = Query1.ID2,
LookupKeyField = Query2.ID2
LookupResultField = Query2.NAME2

после этого, если сами запросы допускают редактирование, в DBGrid'е, связанном с Query1 ты сможешь изменить значение ID2, выбирая значения NAME2 из Query2.

Автор: Serggggg 5.2.2004, 15:11
x77, ОГРОМНОЕ СПАСИБО за детальное разъяснение! Всё заработало! thumbs-up.gif

Цитата
если сами запросы допускают редактирование


Фишка была также и в этом - свойство ReadOnly было равно true.
Ещё раз спасибо! baaa.gif

Автор: x77 5.2.2004, 15:17
smile.gif

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