QuantumGrid:How to setup master-detail relationship for TOracleDataSet using the OnDetailFirst event - 02/14/14 04:25 PM
I am posting this to help anyone else who might be using QuantumGrid with Direct Oracle Access.
As stated in the TcxDbDataModeController.OnDetailFirst, normally the controller handles the parameterized elements of the SQL query, but for some DataSets you will need to use this
event. This is the case with TOracleDataSet. The proper steps are as follows;
1) Set the parameters of the
TcxGrid.DataControler.DetailKeyFieldNames, TcxGrid.DataControler.KeyFieldNames and TcxGrid.DataControler.MasterKeyFieldNames
2) Do NOT Set the values of TOracleDataSet.Master,
TOracleDataSet.MasterFields and TOracleDataSet.DetailFields.
3) Write a routine that will place the parameter
values into the parameter variables.
I have written a generic routine that can be used as a
basis for this routine. It can be used for single or multiple parameterized queries. It uses one custom function "GetNextFieldInString" which I use for parsing CSV import files. This function strips the string before the ';', returning the sting that was stripped. It also removes the retuned characters plus the ';' from the string passed. I did this to make the routine more compact and easier to read.
As stated in the TcxDbDataModeController.OnDetailFirst, normally the controller handles the parameterized elements of the SQL query, but for some DataSets you will need to use this
event. This is the case with TOracleDataSet. The proper steps are as follows;
1) Set the parameters of the
TcxGrid.DataControler.DetailKeyFieldNames, TcxGrid.DataControler.KeyFieldNames and TcxGrid.DataControler.MasterKeyFieldNames
2) Do NOT Set the values of TOracleDataSet.Master,
TOracleDataSet.MasterFields and TOracleDataSet.DetailFields.
3) Write a routine that will place the parameter
values into the parameter variables.
I have written a generic routine that can be used as a
basis for this routine. It can be used for single or multiple parameterized queries. It uses one custom function "GetNextFieldInString" which I use for parsing CSV import files. This function strips the string before the ';', returning the sting that was stripped. It also removes the retuned characters plus the ';' from the string passed. I did this to make the routine more compact and easier to read.
Code
procedure TFrmEditOrders.GtvPickupsDataControllerDataModeControllerDetailFirst(Sender: TcxDBDataModeController; ADataSet: TDataSet; const AMasterDetailKeyFieldNames: string; const AMasterDetailKeyValues: Variant; var AReopened: Boolean); Var KeyFieldNames : String; I: Integer; St : String; RefreshDetail : Boolean; VarArrDimCount : Integer; begin if (ADataSet is TOracleDataSet) then begin With (ADataSet as TOracleDataSet) do begin VarArrDimCount:=VarArrayDimCount(AMasterDetailKeyValues); if VarArrDimCount=0 then begin if GetVariable(AMasterDetailKeyFieldNames)<>AMasterDetailKeyValues then begin if Active then CloseAll; SetVariable(AMasterDetailKeyFieldNames,AMasterDetailKeyValues); Open; AReopened:=True; end; end else begin RefreshDetail:=False; KeyFieldNames:=AMasterDetailKeyFieldNames; I:=0; while Not RefreshDetail and (VarArrayHighBound(AMasterDetailKeyValues,1)>=I) do begin // Function GetNextFieldInString(Var St : String; EofStr,EolStr : String) : String; // This function returns the string before the ';' and also removes the returned string plus the ';' from the string that was passed (St) St:=GetNextFieldInString(KeyFieldNames,';',CrLf); if GetVariable(St)<>AMasterDetailKeyValues[I] then RefreshDetail:=True; Inc(I); end; if RefreshDetail then begin if Active then CloseAll; KeyFieldNames:=AMasterDetailKeyFieldNames; for I := VarArrayLowBound(AMasterDetailKeyValues,1) to VarArrayHighBound(AMasterDetailKeyValues,1) do begin St:=GetNextFieldInString(KeyFieldNames,';',CrLf); SetVariable(St,AMasterDetailKeyValues[I]); end; Open; AReopened:=True; end; end; end; end; end;