Grist, contrairement à un tableur, ne permet pas d’avoir des formules différentes dans chaque cellule. Et c’est très bien comme ça !
Il peut arriver cependant d’être confronté à des problèmes faciles à modéliser dans un tableur, mais bien plus compliqué dans Grist. C’est le cas par exemple en gestion budgétaire, avec des modalités de calculs très différentes d’un sujet à l’autre.
N’utilisez pas la solution proposée ici ! C’est une mauvaise pratique ! Si vous pensez en avoir besoin, c’est que vous avez probablement mal modélisé vos données.
Bon, cependant, voici une formule qui permet de calculer des formules simples saisies dans une colonne de texte. La formule peut être composée d’opérateur mathématiques élémentaires + - * / () et de référence à des cellules de n’importe quelle table et ligne sous la forme :
Nom_table[id_ligne].Colonne
Démo : Spreadsheet
Formule :
import ast
import operator as op
class MathInterpreter:
__operators_map = {
ast.Add: op.add,
ast.Sub: op.sub,
ast.USub: op.neg,
ast.Mult: op.mul,
ast.Div: op.truediv,
}
@staticmethod
def eval(expression: str, variables) -> int | float:
root_node = ast.parse(expression, mode='eval')
return MathInterpreter.__walk(root_node, variables)
@staticmethod
def __walk(node: ast.AST, variables) -> int | float:
match node:
case ast.Expression():
return MathInterpreter.__walk(node.body, variables)
case ast.Num():
return node.n
case ast.BinOp():
left, right, op = node.left, node.right, node.op
method = MathInterpreter.__operators_map[type(op)]
return method(MathInterpreter.__walk(left, variables), MathInterpreter.__walk(right, variables))
case ast.UnaryOp():
operand, op = node.operand, node.op
method = MathInterpreter.__operators_map[type(op)]
return method(MathInterpreter.__walk(operand, variables))
case ast.Name():
id = node.id
return variables(id)
case ast.Attribute():
name = node.value.value.id
idx = node.value.slice.value
attr = node.attr
return variables(name, attr, idx)
case tp:
raise TypeError(tp)
def findVar(var, attr, idx):
match (var, attr, idx):
case (v, a, i):
return getattr(globals()[v].lookupOne(id=i), a)
raise KeyError("Ligne inconnue : "+var)
if $Formula != "":
return MathInterpreter.eval($Formula.replace(",","."), findVar)
J’ai utilisé comme base un algo trouvé ici : How to write a simple math interpreter in Python