Consider creating a multidimensional data iterator. A special feature of this iterator is its ability to be used for several dimensions and iterations will be executed only by points containing data. The data iterator use enables the user to reduce metamodel calculation time.
Executing the example requires that the repository contains a modeling container with the MS identifier containing a metamodel with the METAMODEL_MULTIDIMITERATOR identifier. A data source for this container is a time series database containing time series attributes with the CITY and INDICATOR identifiers. Those attributes should be of the Link to dictionary type.
Add links to the Cubes, Dal, Dimensions, Metabase, Ms, and Rds system assemblies.
Sub UserProc;
Var
mb: IMetabase;
MsKey: Integer;
pMetaModel: IMsMetaModel;
Ms: IMsModelSpace;
DS: IRubricator;
Attributes: IMetaAttributes;
CDict, IDict: IMetabaseObjectDescriptor;
Chain: IMsCalculationChainEntries;
params: IMsModelParams;
CParam, IParam: IMsModelParam;
iterator: IMsCalculationChainMultiDimIterator;
IteratorOpt: IMsDimIterateByDataOptions;
IterStubs: IMsDimIterateByDataStubs;
dimInstC, dimInstI: IDimInstance;
IterDims: IMsDimIteratorDimensions;
CIterDim, IIterDim: IMsDimIteratorDimension;
Filter: IMsDimIteratorFilter;
dimSelC, dimSelI: IDimSelection;
IterStub: IMsDimIterateByDataStub;
FilterDim: IMsDimIteratorFilteredDimension;
model: IMsModel;
Trans: IMsFormulaTransform;
TransVar: IMsFormulaTransformVariable;
slice: IMsFormulaTransformSlice;
Selector: IMsFormulaTransformSelector;
Formula: IMsFormula;
Determ: IMsDeterministicTransform;
TermInfo: IMsFormulaTermInfo;
Expr: IExpression;
Begin
// Get current repository
mb := MetabaseClass.Active;
// Get modelling container key
MsKey := mb.GetObjectKeyById("MS");
// Get the model
pMetaModel := mb.ItemByIdNamespace("METAMODEL_MULTIDIMITERATOR", MsKey).edit As IMsMetaModel;
// Get modeling container
Ms := mb.Item(MsKey).Bind As IMsModelSpace;
// Get time series database,
// which is a data source for modeling container
DS := Ms.Rubricator.Bind As IRubricator;
// Get indicators attributes
Attributes := DS.Facts.Attributes;
// Get dictionaries used as a base for the CITY and INDICATOR attributes
CDict := Attributes.FindById("CITY").ValuesObject;
IDict := Attributes.FindById("INDICATOR").ValuesObject;
// Get and clear metamodel calculation chain
Chain := pMetaModel.CalculationChain;
Chain.Clear;
// Get and clear metamodel parameters
params := pMetaModel.Params;
params.Clear;
// Add a parameter based on dictionary of the CITY attribute
CParam := params.Add;
CParam.DataType := DbDataType.integer;
CParam.DefaultValue := 1;
CParam.Hidden := True;
CParam.Id := "CITY";
CParam.Name := "City";
CParam.LinkedObject := CDict;
// Add a parameter based on dictionary of the INDICATOR attribute
IParam := params.Add;
IParam.DataType := DbDataType.Integer;
IParam.DefaultValue := 1;
IParam.Hidden := True;
IParam.Id := "INDICATOR";
IParam.Name := "Indicator";
IParam.LinkedObject := IDict;
// Add a multidimensional iterator to metamodel calculation chain
iterator := Chain.AddMultiDimIterator("Multidimensional iterator");
// Get iterator parameters by data
IteratorOpt := Iterator.IterateByData;
// Specify that it is active
IteratorOpt.Active := True;
// Set data source for iterator
IterStubs := IteratorOpt.Stubs;
IterStubs.Add(DS As IVariableStub);
// Get iterated dimensions
IterDims := Iterator.Dimensions;
// Add a dimension based on dictionary of the CITY attribute
dimInstC := CDict.Open(Null) As IDimInstance;
CIterDim := IterDims.Add(dimInstC);
// Specify that dimension is parametric
CIterDim.Parameter := CParam;
// Set data source for iterated dimension
CIterDim.Stubs.Add(DS As IVariableStub);
// Set filter of elements
Filter := CIterDim.Filter;
dimSelC := dimInstC.CreateSelection;
dimSelC.SelectAll;
Filter.Selection := dimSelC;
// Add a dimension based on dictionary of the INDICATOR attribute
dimInstI := IDict.Open(Null) As IDimInstance;
IIterDim := IterDims.Add(dimInstI);
// Specify that dimension is parametric
IIterDim.Parameter := IParam;
// Set data source for iterated dimension
IIterDim.Stubs.Add(DS As IVariableStub);
// Set filter of elements
Filter := IIterDim.Filter;
dimSelI := dimInstI.CreateSelection;
dimSelI.SelectAll;
Filter.Selection := dimSelI;
// Get data source, using which iterations will be executed
IterStub := IterStubs.Item(0);
// Add a filtering by the dimension, on which the CITY attribute is based
FilterDim := IterStub.Dimension(dimInstC.InstanceModel);
Debug.WriteLine(" Filtering dimension: " + FilterDim.Dimension.Name);
FilterDim.Filter.Selection := dimSelC;
// Add a filtering by the dimension, on which the INDICATOR attribute is based
FilterDim := IterStub.Dimension(dimInstI.InstanceModel);
FilterDim.Filter.Selection := dimSelI;
Debug.WriteLine(" Filtering dimension: " + FilterDim.Dimension.Name);
// Create a model inside multidimensional iterator
model := Iterator.Contents.AddExclusiveModel.Model;
// Set up model
Trans := model.Transform;
// Add a modelling variable, which attributes are set by the parameters
TransVar := Trans.Outputs.Add(DS As IVariableStub);
Slice := TransVar.Slices.Add(Null);
Slice.ParametrizedDimensions.Item(0).Parameter := IParam;
Slice.ParametrizedDimensions.Item(1).Parameter := CParam;
Selector := Trans.CreateSelector;
Selector.Slice := Slice;
// Set up model calculation method: determinate equation
Formula := Trans.Transform(Selector);
Formula.Kind := MsFormulaKind.Deterministic;
Determ := Formula.Method As IMsDeterministicTransform;
// Add an input variable, which attributes are set by the parameters
TransVar := Trans.Inputs.Add(DS As IVariableStub);
Slice := TransVar.Slices.Add(Null);
Slice.ParametrizedDimensions.Item(0).Parameter := IParam;
Slice.ParametrizedDimensions.Item(1).Parameter := CParam;
TermInfo := Trans.CreateTermInfo;
TermInfo.Slice := Slice;
// Set expression to calculate a model
Expr := Determ.Expression;
Expr.AsString := TermInfo.TermInnerText + "+1";
If Expr.ErrorInfo <> Null Then
debug.WriteLine(Expr.ErrorInfo.ErrorMessage);
Return;
End If;
// Save changes in the model
model.MetabaseObject.Save;
// Save changes of the metamodel
(pMetaModel As IMetabaseObject).Save;
End Sub UserProc;
See also: