Форум: "Базы";
Текущий архив: 2002.11.18;
Скачать: [xml.tar.bz2];
ВнизКак настрить МастерДетайл виды в QuantumGrid v.4 через TADOQuery Найти похожие ветки
← →
mvg_first (2002-10-28 21:46) [0]Вышел значит недвано новая версия Quantum Grid от DevExpress. И вней есть такая очень красивая возможность по реализации несколькоих Мастер-Дейил отношений в одном гриде. У кого нибудь получилось уже настроить нормальную работу используюя TADOQuery и параметризированные запросы.
Во всех моих попытках получался глюк выражающийся в отражении одинаковых изменений во всех детаилах при редактировании данных в одном из них. Никто не сталкивался с такой проблемой? Как с этим бороться?
← →
vuk (2002-10-28 21:58) [1]Master-detail построить получилось. Насчет измененяемых датасетов пока проверить не успел. Сегодня попинаю еще - отпишу.
← →
Ученик (2002-10-28 22:19) [2]Дополнительный вопрос:
Master-Detail работает только для GridMode = False или что-то все-таки можно настроить ?
← →
vuk (2002-10-28 22:24) [3]Я, честно говоря, не вижу причин по которым не должен работать Master-Detail не в GridMode. Это же не группировки, где необходимо вытягивание всего набора данных. Хотя... Это я тоже до кучи проверю.
Если честно, давно не приходилось запускать QuantumGrid не в режиме LoadAllRecords (GridMode в QG4). :o)
← →
Ученик (2002-10-28 22:28) [4]>vuk © (28.10.02 22:24)
А как решается проблема быстродействия на больших данных, загрузка это же время
← →
vuk (2002-10-28 22:36) [5]>А как решается проблема быстродействия на больших данных
Большие объемы данных (на которых все это будет действительно тормозить) запрашивать не имеет смысла, поскольку пользователь не сможет в них ориентироваться. Ну сами посудите, кому охота ковыряться в паре тысяч записей выискивая одну (хотя даже пара тысяч записей втягивается в момент)? Поэтому если пользователю реально необходимо работать с большими объемами, то представление данных нужно оптимизировать так, чтобы информация была каким-либо образом структурирована(тот же master-detail). В этом случае никаких проблем больших объемов просто не возникает. А если же нужен некий отчет, то здесь в любом случае нужно ждать полной обработки набора данных.
← →
Ученик (2002-10-28 22:41) [6]>vuk © (28.10.02 22:36)
Как раз и хотелось основную таблицу в GridMode=True, подчиненные в любом виде (карточка, таблица), но почему-то подчиненные оказываются пустыми :(
← →
vuk (2002-10-28 22:45) [7]У меня с этим проблем не было (Master-detail делался исключительно средствами QG4 с использовыанием ADOStoredProc).
Как Вы организуете Master-Detail? Поподробнее, если можно.
← →
Ученик (2002-10-28 23:56) [8]>vuk © (28.10.02 22:45)
GridMode был в каком режиме ? тут ведь вот было: GridMode=False для Master, все показывается нормально, GridMode=True, подчиненные таблицы пустые :(
← →
Tornado (2002-10-29 07:57) [9]А где можно взять новую версю Квантума? Я слышал что эти компоненты стоят немалых денег.
← →
Ученик (2002-10-29 08:42) [10]>Tornado © (29.10.02 07:57)
На www.torry.net продают
← →
mvg_first (2002-10-29 10:21) [11]Ну так что? Кто нибудь уже решил вопрос?
Кстати со всеми почитал я тут ответы и запутался с определениями :) Давайте расставим точки над и.
GridMode - это режим когда загружается только часть данных, он призван ускорить загрузку "непомерно" больших объемов данных.
LoadAllRecords - это когда GridMode = False, в этом режиме доступны и сортировка и группировка и все прочие фенечки :). Хотя в хелпе написано что в GridMode = True сортировку и группировку необходимо организовывать с помощью соответствующих событий.
Есть еще свойство DataInSQLMode - которое определяет что работа происходит с параметризированным запросом. В моем понимании это нечто вроде этого
SELECT * FROM Customers WHERE CUSTID = :ID
Т.е. при работе моей программы достаточно только менять значение параметра и все должно отражаться правильно. По крайней мере есил механизм Мастер_детаил организовывать через Свойство DataSource в TADOQuery то все именно так и работает.
Что подразумевали разработчики QG4 я не знаю.
В примерах QG4 отражается банальная работа с помощью таблиц. И без параметризированых запросов.А как работать именно с запросами?? Я не знаю.
← →
mvg_first (2002-10-29 10:32) [12]Более подробно опишу пример на котором у меня не работает Мастер-Детаил.
Есть две таблицы одна - "Таблица товаров" вторая таблица документов по которым этот товар приходил. Обе достаточно большие больше 10000 записей. Вернее в первой таблице их около 2000 во второй соответственно что то около 20 000. Т.е. открытие этих таблиц полностью занятие достаточно геморойное, как вы понимаете.
По этому написал пример в котором Использую параметрический запрос, все сделал как описано в Хелпе. Даже обработал событие OnDetailFirst, что бы обрабатывать установку параметра для фильрования записей.
Запрос ко второй таблице выглядит так
SELECT * FROM TabDoc WHERE IdTov = :ID_TOV
В обработчике указанного события выполняю переоткрытие таблицы
with (ADataSet as TADOQuery) do
begin
DisableControls;
try
Active := False;
Parameters.ParamByName("ID_TOV").Value := AMasterDetailKeyValues;
Active := True;
finally
EnableControls;
end;
AReopened := True;
end;
В результате вполне красиво по "плюсику" открываются детаилы для каждой строки товара. но при установке курсора ячейку с автоматическим включением редактирование в редактируемом поле отображается значение из другого детаила, который был открыт ранее. И когда начинаю редактировать поле, данные изменяются во всех открытых детаилах в той строке на который был в каждом из них последний раз.
← →
vuk (2002-10-29 11:13) [13]to Ученик:
>тут ведь вот было: GridMode=False для Master, все показывается
>нормально, GridMode=True, подчиненные таблицы пустые :(
Похоже все-таки да, не работает это все в GridMode. Что это, особенность работы или баг, пока не знаю, надо будет DevExpress трясти на эту тему...
to mvg_first:
>Давайте расставим точки над и.
Вы поняли все совершенно верно.
Там же есть нужно написать обработчик OnDetailIsCurrentQuery, который определяет, является ди текущий набор данных в подчиненном наборе данных именно тем набором, который нужно отобразить. Проверяется это по значениям пареметров (в принципе, можног и не проверять, а просто вернуть false). Возможно это решит проблему.
← →
mvg_first (2002-10-29 11:46) [14]Нмчего не помогает, я даже больше скажу. Только что внимательнее присмотрелся к поведению Детаил-грида. У меня стоят параметры по умолчанию, т.е. ДатаСет в авторедактировании, у грида стоит опция "сразу показывать редактор". Так вот, открываю первый детаил грид в нем допустим 5 строк, на первой записи в колонке цена указано 0,91 на второй вижу 0,86 при перемещении фокуса на вторую строку в ней значение меняется на 0,91. Т.е. значение берется из первой записи, и так при хождении по всем строкам :(
Это 100% глюк. Если это не так, скажите как сделать правильно.
Второй глюк который я заметил - это если не ставить галку в свойстве DetailInSQLMode и организовывать мастердетаил используюя TAdoQuery то в детаилах отображается только первая запись хотя их конкретно больше.
Вот такой глюк.
← →
mvg_first (2002-10-29 11:47) [15]
> который определяет, является ди текущий набор данных в подчиненном
> наборе данных именно тем набором, который нужно отобразить.
> Проверяется это по значениям пареметров (в принципе, можног
> и не проверять, а просто вернуть false).
А вы это сами проверяли? У меня вот не сработало почему то :(
← →
vuk (2002-10-29 12:04) [16]to mvg_first:
>Нмчего не помогает, я даже больше скажу.
У меня такого не было. Все работает как часы (если не в GridMode).
>А вы это сами проверяли? У меня вот не сработало почему то :(
А то как же? Вот только что еще раз проверил. Все работает как и должно.
А у Вас свойства KeyFieldNames/ MasterKeyFieldNames/ DetailKeyFieldNames правильно установлены?
← →
mvg_first (2002-10-29 12:17) [17]Все стоит правильно.
Первая таблица - Все по умолчанию, только установил DataSource на TAdoQuery с запросом SELECT * FROM TovTab (т.е. полная выборка) это таблица мастер. У нее же установил DetailInSQLMode=true.
Добавил подуровень и в в нем в установил DataSource на TAdoQuery с запросом SELECT * FROM DocTab WHERE IdTov = :ID_TOV (т.е. параметризированный запрос).
Свойство DetailKeyFieldNames Установил на поле IdTov - в моей таблице указывает на идентификатор товара
Свойство MasterKeyFieldNames установил на поле ID - поле из первой таблицы указывает на уникальный идентификатор товара
Свойство KeyFieldNames установил на поле ROW_ID - поле второй таблицы указывает на уникальный идентификторо строки во втрой таблице
← →
vuk (2002-10-29 12:22) [18]У Вас BD какая? Если MSSQL, то могу попробовать набросать пример на демонстрационной базе MS и сюда выложить...
← →
mvg_first (2002-10-29 12:34) [19]БД у меня MSSQL 7.0 Насчет примера возражать не буду. Так что б уж совесем все понятно стало.
Может у меня версия QG4 не корректная :) Надо бы сверить :) У меня версия 1.0.0.0
← →
mvg_first (2002-10-29 13:57) [20]Алло vuk так где же пример? Или очень сложно?
← →
vuk (2002-10-29 14:58) [21]Оно не сложно, в принципе, я его уже сделал, просто я сейчас занят на работе... Там только одна тонкость вылезла, которой сразу не заметил (возможно это небольшой баг). Дело в том, что уже загруженный подчиненный набор данных переоткрывается не при активизации соответствующего GridView, а только после навигации по записям в нем.
Пример будет чуть позжее...
← →
vuk (2002-10-29 18:22) [22]Собственно пример. D6 + ADO. Сначала модуль, потом файл формы.
Необходимо поправить ConnectionString.
unit1.pas
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, cxStyles, cxCustomData, cxGraphics, cxFilter, cxData, cxEdit,
DB, cxDBData, cxGridLevel, cxClasses, cxControls, cxGridCustomView,
cxGridCustomTableView, cxGridTableView, cxGridDBTableView, cxGrid, ADODB,
Grids, DBGrids;
type
TForm1 = class(TForm)
ADOConnection1: TADOConnection;
qryCategories: TADOQuery;
qryProducts: TADOQuery;
dsCategories: TDataSource;
dsProducts: TDataSource;
tvCategories: TcxGridDBTableView;
lvCategories: TcxGridLevel;
cxGrid1: TcxGrid;
qryCategoriesCategoryID: TAutoIncField;
qryCategoriesCategoryName: TWideStringField;
qryCategoriesDescription: TMemoField;
qryCategoriesPicture: TBlobField;
qryProductsProductID: TAutoIncField;
qryProductsProductName: TWideStringField;
qryProductsSupplierID: TIntegerField;
qryProductsCategoryID: TIntegerField;
qryProductsQuantityPerUnit: TWideStringField;
qryProductsUnitPrice: TBCDField;
qryProductsUnitsInStock: TSmallintField;
qryProductsUnitsOnOrder: TSmallintField;
qryProductsReorderLevel: TSmallintField;
qryProductsDiscontinued: TBooleanField;
lvProducts: TcxGridLevel;
tvProducts: TcxGridDBTableView;
tvCategoriesCategoryID: TcxGridDBColumn;
tvCategoriesCategoryName: TcxGridDBColumn;
tvCategoriesDescription: TcxGridDBColumn;
tvCategoriesPicture: TcxGridDBColumn;
tvProductsProductID: TcxGridDBColumn;
tvProductsProductName: TcxGridDBColumn;
tvProductsSupplierID: TcxGridDBColumn;
tvProductsCategoryID: TcxGridDBColumn;
tvProductsQuantityPerUnit: TcxGridDBColumn;
tvProductsUnitPrice: TcxGridDBColumn;
tvProductsUnitsInStock: TcxGridDBColumn;
tvProductsUnitsOnOrder: TcxGridDBColumn;
tvProductsReorderLevel: TcxGridDBColumn;
tvProductsDiscontinued: TcxGridDBColumn;
DBGrid1: TDBGrid;
DBGrid2: TDBGrid;
procedure ReopenProducts(
Sender: TcxDBDataModeController; ADataSet: TDataSet;
const AMasterDetailKeyFieldNames: String;
const AMasterDetailKeyValues: Variant; var AReopened: Boolean);
function CheckProductsDS(
Sender: TcxDBDataModeController; ADataSet: TDataSet;
const AMasterDetailKeyFieldNames: String;
const AMasterDetailKeyValues: Variant): Boolean;
procedure FormCreate(Sender: TObject);
private
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.ReopenProducts(
Sender: TcxDBDataModeController; ADataSet: TDataSet;
const AMasterDetailKeyFieldNames: String;
const AMasterDetailKeyValues: Variant; var AReopened: Boolean);
begin
with (ADataSet as TADOQuery) do
begin
if Parameters.ParamValues["Category"] = AMasterDetailKeyValues then
begin
First;
Exit;
end;
DisableControls;
try
Active := False;
Parameters.ParamValues["Category"] := AMasterDetailKeyValues;
Active := True;
finally
EnableControls;
end;
AReopened := True;
end;
end;
function TForm1.CheckProductsDS(
Sender: TcxDBDataModeController; ADataSet: TDataSet;
const AMasterDetailKeyFieldNames: String;
const AMasterDetailKeyValues: Variant): Boolean;
begin
Result := false;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
qryCategories.Open;
qryProducts.Open;
end;
end.
← →
vuk (2002-10-29 18:24) [23]unit1.dfm
object Form1: TForm1
Left = 347
Top = 151
Width = 605
Height = 460
Caption = "Form1"
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = "MS Sans Serif"
Font.Style = []
OldCreateOrder = False
OnCreate = FormCreate
PixelsPerInch = 96
TextHeight = 13
object cxGrid1: TcxGrid
Left = 0
Top = 0
Width = 597
Height = 193
Align = alClient
TabOrder = 0
object tvCategories: TcxGridDBTableView
DataController.DataSource = dsCategories
DataController.DetailKeyFieldNames = "CategoryID"
DataController.Filter.Criteria = {00000000}
DataController.KeyFieldNames = "CategoryID"
DataController.Summary.DefaultGroupSummaryItems = <>
DataController.Summary.FooterSummaryItems = <>
DataController.Summary.SummaryGroups = <>
OptionsBehavior.ImmediateEditor = False
object tvCategoriesCategoryID: TcxGridDBColumn
DataBinding.FieldName = "CategoryID"
end
object tvCategoriesCategoryName: TcxGridDBColumn
DataBinding.FieldName = "CategoryName"
end
object tvCategoriesDescription: TcxGridDBColumn
DataBinding.FieldName = "Description"
end
object tvCategoriesPicture: TcxGridDBColumn
DataBinding.FieldName = "Picture"
end
end
object tvProducts: TcxGridDBTableView
DataController.DataModeController.DetailInSQLMode = True
DataController.DataModeController.OnDetailFirst = ReopenProducts
DataController.DataModeController.OnDetailIsCurrentQuery = CheckProductsDS
DataController.DataSource = dsProducts
DataController.DetailKeyFieldNames = "CategoryID"
DataController.Filter.Criteria = {00000000}
DataController.KeyFieldNames = "ProductID"
DataController.MasterKeyFieldNames = "CategoryID"
DataController.Summary.DefaultGroupSummaryItems = <>
DataController.Summary.FooterSummaryItems = <>
DataController.Summary.SummaryGroups = <>
OptionsBehavior.ImmediateEditor = False
object tvProductsProductID: TcxGridDBColumn
DataBinding.FieldName = "ProductID"
end
object tvProductsProductName: TcxGridDBColumn
DataBinding.FieldName = "ProductName"
end
object tvProductsSupplierID: TcxGridDBColumn
DataBinding.FieldName = "SupplierID"
end
object tvProductsCategoryID: TcxGridDBColumn
DataBinding.FieldName = "CategoryID"
end
object tvProductsQuantityPerUnit: TcxGridDBColumn
DataBinding.FieldName = "QuantityPerUnit"
end
object tvProductsUnitPrice: TcxGridDBColumn
DataBinding.FieldName = "UnitPrice"
end
object tvProductsUnitsInStock: TcxGridDBColumn
DataBinding.FieldName = "UnitsInStock"
end
object tvProductsUnitsOnOrder: TcxGridDBColumn
DataBinding.FieldName = "UnitsOnOrder"
end
object tvProductsReorderLevel: TcxGridDBColumn
DataBinding.FieldName = "ReorderLevel"
end
object tvProductsDiscontinued: TcxGridDBColumn
DataBinding.FieldName = "Discontinued"
end
end
object lvCategories: TcxGridLevel
GridView = tvCategories
object lvProducts: TcxGridLevel
GridView = tvProducts
end
end
end
object DBGrid1: TDBGrid
Left = 0
Top = 313
Width = 597
Height = 120
Align = alBottom
DataSource = dsProducts
TabOrder = 1
TitleFont.Charset = DEFAULT_CHARSET
TitleFont.Color = clWindowText
TitleFont.Height = -11
TitleFont.Name = "MS Sans Serif"
TitleFont.Style = []
end
object DBGrid2: TDBGrid
Left = 0
Top = 193
Width = 597
Height = 120
Align = alBottom
DataSource = dsCategories
TabOrder = 2
TitleFont.Charset = DEFAULT_CHARSET
TitleFont.Color = clWindowText
TitleFont.Height = -11
TitleFont.Name = "MS Sans Serif"
TitleFont.Style = []
end
← →
vuk (2002-10-29 18:25) [24]продолжение unit1.dfm
object ADOConnection1: TADOConnection
Connected = True
ConnectionString =
"Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security In" +
"fo=False;Initial Catalog=Northwind;Data Source=FCS---S05"
LoginPrompt = False
Provider = "SQLOLEDB.1"
Left = 32
Top = 70
end
object qryCategories: TADOQuery
Connection = ADOConnection1
CursorType = ctStatic
Parameters = <>
SQL.Strings = (
"SELECT CategoryID, CategoryName, Description, Picture"
"FROM Categories")
Left = 32
Top = 98
object qryCategoriesCategoryID: TAutoIncField
FieldName = "CategoryID"
ReadOnly = True
end
object qryCategoriesCategoryName: TWideStringField
FieldName = "CategoryName"
Size = 15
end
object qryCategoriesDescription: TMemoField
FieldName = "Description"
BlobType = ftMemo
end
object qryCategoriesPicture: TBlobField
FieldName = "Picture"
end
end
object qryProducts: TADOQuery
Connection = ADOConnection1
CursorType = ctStatic
Parameters = <
item
Name = "Category"
DataType = ftString
Size = 4
Value = Null
end>
SQL.Strings = (
"SELECT ProductID, ProductName, SupplierID, "
" CategoryID, QuantityPerUnit, UnitPrice,"
" UnitsInStock, UnitsOnOrder, ReorderLevel, Discontinued"
"FROM Products"
"WHERE CategoryID = :Category")
Left = 32
Top = 126
object qryProductsProductID: TAutoIncField
FieldName = "ProductID"
ReadOnly = True
end
object qryProductsProductName: TWideStringField
FieldName = "ProductName"
Size = 40
end
object qryProductsSupplierID: TIntegerField
FieldName = "SupplierID"
end
object qryProductsCategoryID: TIntegerField
FieldName = "CategoryID"
end
object qryProductsQuantityPerUnit: TWideStringField
FieldName = "QuantityPerUnit"
end
object qryProductsUnitPrice: TBCDField
FieldName = "UnitPrice"
Precision = 19
end
object qryProductsUnitsInStock: TSmallintField
FieldName = "UnitsInStock"
end
object qryProductsUnitsOnOrder: TSmallintField
FieldName = "UnitsOnOrder"
end
object qryProductsReorderLevel: TSmallintField
FieldName = "ReorderLevel"
end
object qryProductsDiscontinued: TBooleanField
FieldName = "Discontinued"
end
end
object dsCategories: TDataSource
DataSet = qryCategories
Left = 60
Top = 98
end
object dsProducts: TDataSource
DataSet = qryProducts
Left = 60
Top = 126
end
end
← →
mvg_first (2002-10-29 20:08) [25]Ок, пример себе скопировал, но посмотрю уже завтра. И вопросы понятное дело завтра продолжаться :)
← →
vuk (2002-10-29 20:13) [26]Когда будете смотреть, обратите внимания на два обычных (TDBGrid) грида внизу формы. Они там для того, чтобы было видно, что происходит с наборами данных при навигации по QG.
← →
mvg_first (2002-10-30 12:11) [27]Вообщем как я и предполагал, глюк остался :)
Как повторить чтоб было понятнее.
Пример скомпилил без изменений (только подправил имя сервера)
Запустил, все заработало, гриды открываются, как положено.
Нажал, на "плюсик" в строке с CategoryId = 4
и так же нажал на "плюсик" в строке с CategoryId = 5
Передо мной картина из двух вложенных таблиц содержащих совершенно разные данные. Как и должно быть. Т.е. пока все нормально.
После чего изменяю знчение в колонке UnitPrice второго детаила в первой строке. После изменения нажимаю Enter и вижу ту же значение в первой строке первого детаила. В результате - явная бочина. Может это так и должно быть??? Но я никогда не докажу этого пользователям моей программы :)
← →
mvg_first (2002-10-30 12:18) [28]Уточню данные, изменения отражаются не обязательно в первой строке, если допустим в первом детаиле переместится на 3-ю запись а потом перейти на второй детаил и сделать изменения в первой (или во второй или в любой) записи то изменения отразятся в первом детаиле в той строке в которой мы находились перед тем как перешли во втрой детаил.
Причем строка первого детаила (который как бы не активный) выглядит совершенно точно по всем полям так же как и строка второго детаила которую мы только что изменили.
Если перейти обратно в первый детаил все становится на свои места :) Значения возвращаются в норму :).
← →
vuk (2002-10-30 14:47) [29]Да, действительно, баг присутствует, я просто даже сначала на него внимания не обратил. Надо будет багрепорт отправить...
← →
mvg_first (2002-10-30 14:59) [30]Все таки я добился своего !!! Хоть кто то баг подтвердил.
А можно ли считать багом то что в GridMode = True не работает мастер детаил???
И если можно, результат общения мне на мыло mvgfirst@nm.ru если не затруднит.
Заранее спасибо :)
← →
vuk (2002-10-30 15:05) [31]>А можно ли считать багом то что в GridMode = True не работает
>мастер детаил???
Не знаю, пока с этим вопрос не ясен, в ньюсгруппе у DevExpress уже есть сообщения по этому поводу...
Результат (если он будет) можно будет смотреть там же. Пока же нужно еще на это время найти.
Страницы: 1 вся ветка
Форум: "Базы";
Текущий архив: 2002.11.18;
Скачать: [xml.tar.bz2];
Память: 0.56 MB
Время: 0.01 c