SaveMatrixCallback: ICubeSaveMatrixCallback;
SaveMatrixCallback: Prognoz.Platform.Interop.Cubes.ICubeSaveMatrixCallback;
The SaveMatrixCallback property determines a handler of data matrix saving to cube.
As a property value, specify the object instance that implements methods of the ICubeSaveMatrixCallback interface or is inherited and redetermines the CubeCallback class. The handler enables the user to trace data saving and, if required, change data or fully cancel DBMS transaction.
The handler of errors that can occur on saving data to cube is set in the Callback property. To handle errors and data saving process, one common handler inherited from the CubeCallback class can be used, but handler will work independently.
Executing the example requires a cube with the STD_CUBE identifier. The cube structure includes a dimension with the COUNTRY identifier. The cube stores data by countries.
Add links to the Cubes, Dimensions, MathFin, Matrix, Metabase, ForeSystem (for Fore.NET example) system assemblies.
Sub UserProc;
Var
MB: IMetabase;
CubInst: ICubeInstance;
Des: ICubeInstanceDestination;
Sels: IDimSelectionSet;
Sel: IDimSelection;
Matr: IMatrix;
Coord: IMatrixCoord;
Sto: ICubeInstanceStorage;
i: Integer;
Begin
MB := MetabaseClass.Active;
CubInst := MB.ItemById("STD_CUBE").Open(Null) As ICubeInstance;
Des := CubInst.Destinations.DefaultDestination;
//Cube selection
Sels := Des.CreateDimSelectionSet;
For Each Sel In Sels Do
If Sel.Dimension.Ident = "COUNTRY" Then
Sel.SelectAll;
Else
Sel.SelectElement(0, False);
End If;
End For;
//Get values matrix by specified selection
Matr := Des.Execute(Sels);
Matr.ValueFlag := 1;
Coord := Matr.CreateCoord;
For i := 0 To Matr.DimensionCount - 1 Do
Coord.Item(i) := 0;
End For;
//Change value by coordinate
Matr.Item(Coord) := (Matr.Item(Coord) As Double) + Math.RandBetween(50, 150);
//Object for saving data to cube
Sto := Des.CreateStorage(CubeInstanceStorageOptions.None);
//Data saving handler
Sto.SaveMatrixCallback := New TCubeSaveCallback.Create;
//Save values
Sto.SaveMatrix(Matr, Matr.ValueFlag);
End Sub UserProc;
Class TCubeSaveCallback: CubeCallback
Public Sub OnBeforeSave(Argument: ICubeCallbackBeforeSaveArgument);
Var
Matr: IMatrix;
Iter: IMatrixIterator;
needSkipSave: Boolean = False;
Begin
//Matrix with saved data
Matr := Argument.OriginalMatrix;
Iter := Matr.CreateIterator;
Iter.Move(IteratorDirection.First);
While Iter.Valid Do
//If changed value is greater than 100, cancel saving
If Iter.ValueFlag = 1 Then
If (Iter.Value As Double) > 100 Then
needSkipSave := True;
End If;
End If;
Iter.Move(IteratorDirection.Next);
End While;
Argument.ResultMatrix := Matr;
Argument.SkipDefaultSave := needSkipSave;
End Sub OnBeforeSave;
Public Sub OnAfterSave(Argument: ICubeCallbackSaveArgument);
Var
Connection: ISecurityConnection;
Matr: IMatrix;
Iter: IMatrixIterator;
Begin
Debug.WriteLine("---Data is saved---");
Connection := (Argument.SecurityConnections[0] As ISecurityConnection);
Debug.WriteLine("Platform user: " + Connection.UserNameLo);
Debug.WriteLine("DBMS user: " + Connection.UserNameDb);
Debug.WriteLine("Cube display version: " + Argument.Destination.Id);
Debug.WriteLine("Record key in access protocol: " + Argument.LogKey.ToString);
Debug.WriteLine("Values obtained from cube:");
Matr := Argument.ValueMatrix;
Iter := Matr.CreateIterator;
Iter.Move(IteratorDirection.First);
While Iter.Valid Do
Debug.Write(iter.Value + " ");
Iter.Move(IteratorDirection.Next);
End While;
Debug.WriteLine("");
Debug.WriteLine("Changed values:");
Matr := Argument.FilteredMatrix;
Iter := Matr.CreateIterator;
Iter.Move(IteratorDirection.First);
While Iter.Valid Do
Debug.Write(iter.Value + " ");
Iter.Move(IteratorDirection.Next);
End While;
Debug.WriteLine("");
End Sub OnAfterSave;
End Class TCubeSaveCallback;
Imports Prognoz.Platform.Interop.Cubes;
Imports Prognoz.Platform.Interop.Dimensions;
Imports Prognoz.Platform.Interop.ForeSystem;
Imports Prognoz.Platform.Interop.MathFin;
Imports Prognoz.Platform.Interop.Matrix;
Imports Prognoz.Platform.Interop.Metabase;
…
Private Shared Sub Main(Params: StartParams);
Var
MB: IMetabase;
CubInst: ICubeInstance;
Des: ICubeInstanceDestination;
Sels: IDimSelectionSet;
Sel: IDimSelection;
Matr: IMatrix;
Coord: IMatrixCoord;
Sto: ICubeInstanceStorage;
CMath: MathClass = New MathClass();
i: Integer;
Begin
MB := Params.Metabase;
CubInst := MB.ItemById["STD_CUBE"].Open(Null) As ICubeInstance;
Des := CubInst.Destinations.DefaultDestination;
//Cube selection
Sels := Des.CreateDimSelectionSet();
For Each Sel In Sels Do
If Sel.Dimension.Ident = "COUNTRY" Then
Sel.SelectAll();
Else
Sel.SelectElement(0, False);
End If;
End For;
//Get values matrix by specified selection
Matr := Des.Execute(Sels, uinteger.MaxValue);
Matr.ValueFlag := 1;
Coord := Matr.CreateCoord();
For i := 0 To Matr.DimensionCount - 1 Do
Coord.Item[i] := 0;
End For;
//Change value by coordinate
Matr.Item[Coord] := (Matr.Item[Coord] As Double) + CMath.RandBetween(50, 150);
//Object for saving data to cube
Sto := Des.CreateStorage(CubeInstanceStorageOptions.cisoNone);
//Data saving handler
Sto.SaveMatrixCallback := New TCubeSaveCallback();
//Save values
Sto.SaveMatrix(Matr, Matr.ValueFlag);
End Sub;
Class TCubeSaveCallback: ICubeSaveMatrixCallback
Public Sub OnBeforeSave(Argument: ICubeCallbackBeforeSaveArgument);
Var
Matr: IMatrix;
Iter: IMatrixIterator;
needSkipSave: Boolean = False;
Begin
//Matrix with saved data
Matr := Argument.OriginalMatrix;
Iter := Matr.CreateIterator();
Iter.Move(IteratorDirection.itdFirst);
While Iter.Valid Do
//If changed value is greater than 100, cancel saving
If Iter.ValueFlag = 1 Then
If (Iter.Value As Double) > 100 Then
needSkipSave := True;
End If;
End If;
Iter.Move(IteratorDirection.itdNext);
End While;
Argument.ResultMatrix := Matr;
Argument.SkipDefaultSave := needSkipSave;
End Sub;
Public Sub OnAfterSave(Argument: ICubeCallbackSaveArgument);
Var
Connection: ISecurityConnection;
Matr: IMatrix;
Iter: IMatrixIterator;
Begin
System.Diagnostics.Debug.WriteLine("---Data is saved---");
Connection := ((Argument.SecurityConnections As Array)[0] As ISecurityConnection);
System.Diagnostics.Debug.WriteLine("Platform user: " + Connection.UserNameLo);
System.Diagnostics.Debug.WriteLine("DBMS user: " + Connection.UserNameDb);
System.Diagnostics.Debug.WriteLine("Cube display version: " + Argument.Destination.Id);
System.Diagnostics.Debug.WriteLine("Record key in access protocol: " + Argument.LogKey.ToString());
System.Diagnostics.Debug.WriteLine("Values obtained from cube:");
Matr := Argument.ValueMatrix;
Iter := Matr.CreateIterator();
Iter.Move(IteratorDirection.itdFirst);
While Iter.Valid Do
System.Diagnostics.Debug.Write(iter.Value + " ");
Iter.Move(IteratorDirection.itdNext);
End While;
System.Diagnostics.Debug.WriteLine("");
System.Diagnostics.Debug.WriteLine("Changed values:");
Matr := Argument.FilteredMatrix;
Iter := Matr.CreateIterator();
Iter.Move(IteratorDirection.itdFirst);
While Iter.Valid Do
System.Diagnostics.Debug.Write(iter.Value + " ");
Iter.Move(IteratorDirection.itdNext);
End While;
System.Diagnostics.Debug.WriteLine("");
End Sub;
End Class;
After executing the example a matrix with cube data is obtained. The value is changed by some coordinate, following which the updated matrix is saved back to the cube. Data saving is handled in the TCubeSaveCallback custom class. If changed values is greater than 100, data saving is can canceled.
See also: