❌ Résoudre les cassages de champs référence dans Grist

:x: Résoudre les cassages de champs référence dans Grist

Ça vous énerve quand vous copiez-collez (ou que vous formuledinitialisationnez) dans un champ de type référence et que la liaison avec la table en question ne marche pas ? Vous savez, la petite case qui devient rouge – comme vous – d’insatisfaction ?

Dans ces cas-là, moi je souffle et je me dis : Ah oui, c’est vrai, j’avais trouvé une solution l’autre fois ! Alors je vous partage MA solution, mais si vous en avez une plus simple, je suis preneuse ! :pray:


Cas pratique : Lier des projets et des tâches

Prenons un cas simple avec deux tables :

  • PROJETS avec le champ NOM_PROJET.
  • TACHES avec les champs :
    • NOM_TACHE
    • PROJET_ASSOCIE (Texte – récupéré par une formule d’initialisation, par exemple).
    • LIEN_PROJET (Référence vers PROJETS).

Ajoutez cette formule dans LIEN_PROJET :

result = PROJETS.lookupOne(NOM_PROJET=rec.PROJET_ASSOCIE)
return result if result else None

Si PROJET_ASSOCIE existe bien dans la table PROJETS, alors le lien sera correctement établi.

Faites le test en copiant-collant le contenu de PROJET_ASSOCIE vers un champ COPIÉ COLLÉ :-1: de type Référence simple (comme LIEN_PROJET), et vous verrez la différence. :wink:

4 « J'aime »

Merci pour cette astuce qui m’aide à résoudre le problème que je citais ici !

C’est un peu de la bidouille, mais ça fait le job !

J’anticipe la question, pour un champ de type référence multiple, il faut que vos données multiples dans LIEN_PROJET soient séparées par une virgule et une espace==> ', ’
et il faut utiliser cette formule

projets = [p for p in PROJETS.all if p.NOM_PROJET in rec.PROJET_ASSOCIE.split(", ")]
return projets if projets else []

Top, merci pour l’astuce ! J’étais justement en train de rédiger une issue sur ce problème.

Donc ça signifie que, dans une colonne référence :

  • une formule d’initialisation qui retourne la ligne entière (« vraie référence ») via un lookup va permettre l’auto-résolution
  • une formule d’initialisation qui retourne la valeur du champ affiché ne permet pas l’auto-résolution

Par contre de mon côté quand je c/c dans une colonne référence, ça fonctionne bien :thinking:

Une idée de ce qui diffère avec ton cas ?

cc ref

C’est parce que tu copie colles à partir de la table7.
L’idée c’est le copier coller depuis la table8

Ca fonctionne si je copie colle de n’importe où (en soi je me dis heureusement vu que je copie juste un texte) :
ccref

ah marrant je n’ai pas le meme comportement de mon côté, le cc provoque une erreur

Bonjour. Je fais un message dans ce fil car ça correspond assez bien à ma problématique.

J’ai créé dans une table COMMANDE un champ calculé à la création d’une ligne avec la formule user.Email. Je souhaite que ce champ soit une référence de ma table UTILISATEURS notamment pour récupérer le service du demandeur automatiquement. Malheureusement il s’affiche en rouge et la liaison de se fait pas… une idée ?

Merci @audezu @celine

oui as tu testé la solution ?

j’ai testé

result = Utilisateurs.lookupOne(Mail=user.Email)
return result if result else None

et ça fonctionne bien !
il va falloir que je note ça dans mes tablettes

1 « J'aime »

@audezu @celine ,
Votre astuce marchait bien jusqu’ici et je m’en sers souvent. Mais voilà, sans savoir pourquoi cela ne fonctionne pas avec un champ, ChercheSIRET. Votre expertise est la bienvenue.

class Table_de_travail:
  @grist.formulaType(grist.Reference('TR_Exploitants'))
  def ChercheSIRET(rec, table):
    result = TR_Exploitants.lookupOne(N_SIRET=rec.Recherche).N_SIRET
    return result if (result and len(rec.Recherche)==14) else None

  @grist.formulaType(grist.Reference('TR_Exploitants'))
  def CherchePacage(rec, table):
    result = TR_Exploitants.lookupOne(Pacage=rec.Recherche)
    return result if (result and len(rec.Recherche)==9) else None

class TR_Exploitants:
  Pacage = grist.Text()
  N_SIRET = grist.Text()

bonjour, essaie d’enlever le .N_SIRET

class Table_de_travail:
@grist.formulaType(grist.Reference('TR_Exploitants'))
def ChercheSIRET(rec, table):
result = TR_Exploitants.lookupOne(N_SIRET=rec.Recherche)
return result if (result and len(rec.Recherche)==14) else None

@grist.formulaType(grist.Reference('TR_Exploitants'))
def CherchePacage(rec, table):
    result = TR_Exploitants.lookupOne(Pacage=rec.Recherche)
    return result if (result and len(rec.Recherche)==9) else None

class TR_Exploitants:
Pacage = grist.Text()
N_SIRET = grist.Text()
1 « J'aime »

Génial, ça fonctionne ! Merci