66import logging
77import pandas as pd
88from pytabular .object import PyObject , PyObjects
9+ from Microsoft .AnalysisServices .Tabular import Measure , Table
10+
911
1012logger = logging .getLogger ("PyTabular" )
1113
@@ -27,7 +29,6 @@ def __init__(self, object, table) -> None:
2729 table (table.PyTable): The parent `PyTable`.
2830 """
2931 super ().__init__ (object )
30-
3132 self .Table = table
3233 self ._display .add_row ("Expression" , self ._object .Expression , end_section = True )
3334 self ._display .add_row ("DisplayFolder" , self ._object .DisplayFolder )
@@ -59,6 +60,74 @@ class PyMeasures(PyObjects):
5960 `model.Measures.find('ratio')`.
6061 """
6162
62- def __init__ (self , objects ) -> None :
63+ def __init__ (self , objects , parent ) -> None :
6364 """Extends init from `PyObjects`."""
64- super ().__init__ (objects )
65+ super ().__init__ (objects , parent )
66+
67+ def __call__ (self , * args , ** kwargs ):
68+ """Made `PyMeasures` just sends args through to `add_measure`."""
69+ return self .add_measure (* args , ** kwargs )
70+
71+ def add_measure (self , name : str , expression : str , ** kwargs ) -> PyMeasure :
72+ """Add or replace measures from `PyMeasures` class.
73+
74+ Required is just `name` and `expression`.
75+ But you can pass through any properties you wish to update as a kwarg.
76+ This method is also used when calling the class,
77+ so you can create a new measure that way.
78+ kwargs will be set via the `settr` built in function.
79+ Anything in the .Net Measures properties should be viable.
80+ [Measure Class](https://learn.microsoft.com/en-us/dotnet/api/microsoft.analysisservices.measure?#properties) # noqa: E501
81+
82+ Example:
83+ ```
84+ expr = "SUM('Orders'[Amount])"
85+ model.Measures.add_measure("Orders Total", expr)
86+ ```
87+
88+ ```
89+ expr = "SUM('Orders'[Amount])"
90+ model.Measures.add_measure("Orders Total", expr, Folder = 'Measures')
91+ ```
92+
93+ ```
94+ expr = "SUM('Orders'[Amount])"
95+ model.Tables['Sales'].Measures('Total Sales', expr, Folder = 'Measures')
96+ ```
97+
98+ Args:
99+ name (str): Name of the measure. Brackets ARE NOT required.
100+ expression (str): DAX expression for the measure.
101+ """
102+ if isinstance (self .parent ._object , Table ):
103+ table = self .parent
104+ model = self .parent .Model
105+ else :
106+ table = self .parent .Tables ._first_visible_object ()
107+ model = self .parent
108+
109+ logger .debug (f"Creating measure in { table .Name } " )
110+
111+ new = True
112+
113+ try :
114+ logger .debug (f"Measure { name } exists... Overwriting..." )
115+ new_measure = self .parent .Measures [name ]._object
116+ new = False
117+ except IndexError :
118+ logger .debug (f"Creating new measure { name } " )
119+ new_measure = Measure ()
120+
121+ new_measure .set_Name (name )
122+ new_measure .set_Expression (expression )
123+
124+ for key , value in kwargs .items ():
125+ logger .debug (f"Setting '{ key } '='{ value } ' for { new_measure .Name } " )
126+ setattr (new_measure , key , value )
127+
128+ if new :
129+ measures = table .get_Measures ()
130+ measures .Add (new_measure )
131+
132+ model .save_changes ()
133+ return model .Measures [new_measure .Name ]
0 commit comments