# myFAB DB Externes

Module permettant de connecter une base SQL externe, d’exécuter une requête de lecture, puis de générer automatiquement un modèle OpenProd, ses vues, son action, son menu et son mécanisme de rechargement.

\*\* module disponible uniquement en v10 \*\*

# Documentation utilisateurs

Documentation fonctionnelle et technique couvrant l’installation, le paramétrage des connexions, la construction SQL, la génération du modèle OpenProd, le rechargement des données et la maintenance.

# Documentation du module

### **Présentation**

**1. Objectif**  
Le module permet d’exposer dans OpenProd des données issues d’une base SQL externe, sans développement spécifique pour chaque jeu de données.  
L’utilisateur définit une connexion, saisit une requête SQL de lecture, puis laisse le module créer le modèle OpenProd et l’interface associée.

Le résultat final est un modèle manuel OpenProd alimenté à partir de la requête distante, avec sa vue liste, sa vue formulaire, son action, son menu et un cron de rechargement.

**2. Principe général**

- Créer une configuration de connexion SQL externe et tester l’accès.
- Créer une source de données, saisir une requête SQL et prévisualiser le résultat.
- Générer le modèle OpenProd, ses champs, ses vues et son menu.
- Charger ou recharger les données depuis la base distante vers le modèle généré.

### **Installation**

<span style="font-weight: bold; background: white;">1. Prérequis</span>

<span style="background: white;">Le module repose sur SQLAlchemy et sur les drivers Python correspondant aux connecteurs utilisés :</span>

- <span style="background: white;">psycopg2 pour PostgreSQL</span>
- <span style="background: white;">pymysql pour MySQL</span>
- <span style="background: white;">pymssql pour SQL Server</span>

<span style="background: white;">Le connecteur SQLite est également supporté.</span>

<span style="background: white;">Tous les drivers sont téléchargéq lors de l'installation du module.</span>

<span style="font-weight: bold; background: white;">2. Point d’attention</span>

<span style="background: white;">Si le driver Python correspondant au connecteur choisi n’est pas installé sur le serveur, le test de connexion et l’ouverture de session échoueront avec un message explicite.</span>

### **<span style="background: white;">Configuration</span>**

<span style="font-weight: bold; background: white;">1. Menu de configuration</span>

<span style="background: white;">Le module ajoute un menu d’administration contenant :</span>

- <span style="background: white;">Sources de données</span>
- <span style="background: white;">Configurations de connexion</span>

<span style="font-weight: bold; background: white;">2. Configuration de connexion</span>

<span style="background: white;">Une configuration contient notamment :</span>

- <span style="background: white;">un nom unique de configuration</span>
- <span style="background: white;">un connecteur</span>
- <span style="background: white;">un serveur et un port si nécessaire</span>
- <span style="background: white;">une base cible</span>
- <span style="background: white;">un utilisateur et un mot de passe si le connecteur l’exige</span>
- <span style="background: white;">un timeout de connexion</span>

[![image.png](https://docs.myfab.fr/uploads/images/gallery/2026-06/scaled-1680-/LXoimage.png)](https://docs.myfab.fr/uploads/images/gallery/2026-06/LXoimage.png)

<span style="font-weight: bold; background: white;">3. Test de connexion</span>

<span style="background: white;">Le bouton Tester la connexion vérifie que la session SQL externe peut être ouverte.</span>

<span style="background: white;">Le résultat est enregistré dans un journal directement sur la configuration.</span>

<span style="background: white;">En cas d’erreur, le message remonte une information exploitable pour l’utilisateur : cible visée, timeout éventuel et détail technique retourné par le driver SQL.</span>

### **<span style="background: white;">Paramétrage d'une source</span>**

<span style="font-weight: bold; background: white;">1. Informations principales</span>

<span style="background: white;">Une source de données associe :</span>

- <span style="background: white;">un nom unique de source</span>
- <span style="background: white;">une configuration de connexion</span>
- <span style="background: white;">une requête SQL de lecture</span>
- <span style="background: white;">un nom technique de base pour générer le modèle OpenProd</span>

[![image.png](https://docs.myfab.fr/uploads/images/gallery/2026-06/scaled-1680-/2X7image.png)](https://docs.myfab.fr/uploads/images/gallery/2026-06/2X7image.png)

<span style="font-weight: bold; background: white;">2. Règles sur la requête SQL</span>

<span style="background: white;">La requête est validée avant exécution. Le module n’accepte que des requêtes de lecture.</span>

- <span style="background: white;">les requêtes SELECT sont autorisées</span>
- <span style="background: white;">les requêtes WITH sont acceptées si elles débouchent sur une lecture</span>
- <span style="background: white;">les mots-clés de modification comme INSERT, UPDATE ou DELETE sont refusés</span>
- <span style="background: white;">les requêtes multiples sont interdites</span>

[![image.png](https://docs.myfab.fr/uploads/images/gallery/2026-06/scaled-1680-/JYBimage.png)](https://docs.myfab.fr/uploads/images/gallery/2026-06/JYBimage.png)

<span style="font-weight: bold; background: white;">3. Colonne obligatoire</span>

<span style="background: white;">La requête doit obligatoirement exposer une colonne Name.</span>

<span style="background: white;">Cette colonne est transformée en champ x\_name dans le modèle généré et sert de base au display\_name OpenProd.</span>

<span style="font-weight: bold; background: white;">4. Variable de date</span>

<span style="background: white;">La variable %date peut être utilisée dans la requête.</span>

<span style="background: white;">Au moment de l’exécution, elle est remplacée par la dernière date de synchronisation connue.</span>

<span style="background: white;">Exemple :</span>

<span style="background: white;">SELECT Name, code, date\_modification FROM ma\_vue\_source WHERE date\_modification &gt; %date</span>

<span style="font-weight: bold; background: white;">5. Prévisualisation</span>

<span style="background: white;">Le bouton Prévisualiser la requête exécute une version limitée de la requête et affiche le résultat directement dans la fiche.</span>

<span style="background: white;">Cette étape sert à contrôler les colonnes retournées et la cohérence du jeu de données avant de générer le modèle.</span>

<span style="font-weight: bold; background: white;">6. État de la source</span>

<span style="background: white;">Le workflow de la source est volontairement simple :</span>

- <span style="background: white;">Brouillon : la requête et la structure peuvent être modifiées</span>
- <span style="background: white;">Modèle et interface chargés : le modèle existe, la requête est verrouillée, seuls les rechargements sont attendus</span>

<span style="background: white;">Pour modifier la structure après génération, il faut utiliser le bouton Brouillon, puis relancer la création ou mise à jour du modèle et de l’interface.</span>

[![image.png](https://docs.myfab.fr/uploads/images/gallery/2026-06/scaled-1680-/QQVimage.png)](https://docs.myfab.fr/uploads/images/gallery/2026-06/QQVimage.png)

### **Utilisation du module**

<span style="font-weight: bold; background: white;">1. Création du modèle et de l’interface</span>

<span style="background: white;">Le bouton Créer ou mettre à jour le modèle et l’interface analyse les colonnes de la requête, crée ou met à jour le modèle manuel OpenProd, ses champs, sa vue liste, sa vue formulaire, son action, son menu et son cron de rechargement.</span>

<span style="background: white;">La conversion des colonnes suit les règles suivantes :</span>

- <span style="background: white;">Name devient x\_name</span>
- <span style="background: white;">id devient x\_source\_id pour éviter les collisions avec l’identifiant OpenProd</span>
- <span style="background: white;">les autres colonnes deviennent des champs x\_\* sécurisés</span>
- <span style="background: white;">le champ technique x\_user\_id est ajouté pour tracer l’utilisateur créateur des enregistrements importés</span>

<span style="font-weight: bold; background: white;">2. Chargement des données</span>

<span style="background: white;">Le bouton Charger ou recharger les données exécute la requête source complète, vide les enregistrements déjà présents dans le modèle généré, puis recrée les lignes à partir du résultat courant.</span>

<span style="background: white;">Le chargement est donc un rechargement complet, et non une mise à jour ligne par ligne.</span>

<span style="background: white;">Cette stratégie simplifie la maintenance et garantit que le contenu du modèle reflète exactement le résultat SQL courant.</span>

<span style="font-weight: bold; background: white;">3. Ouverture de la liste générée</span>

<span style="background: white;">Le bouton Ouvrir la liste générée ouvre directement l’action créée pour le modèle généré, ce qui permet de consulter les données importées comme n’importe quel objet OpenProd.</span>

<span style="font-weight: bold; background: white;">4. Vidage des données</span>

<span style="background: white;">Le bouton Vider les données du modèle supprime les lignes importées sans supprimer le modèle, ses champs ni son interface.</span>

**<span style="background: white;">5. Rafraichir les données automatiquement</span>**

<span style="background: white;">Pour rafraichir les données deux options s'offrent à vous :</span>

- <span style="background: white;">Utiliser le bouton d'action de rafraichissement des données présent dans la vue formulaire </span>
- <span style="background: white;">Activer le cron créé automatiquement en même temps que le modèle et lui donner une valeur temporelle.</span>

# Installation

**1. Prérequis**  
Le module repose sur SQLAlchemy et sur les drivers Python correspondant aux connecteurs utilisés :

- <span class="_inlineMarkdown_x0d1c_75 inline-markdown text-size-chat-sm font-mono blend bg-token-text-code-block-background rounded-sm px-1.5 py-0.5 leading-none extension:bg-token-foreground/10 electron:bg-token-list-hover-background/60">psycopg2</span> pour PostgreSQL
- <span class="_inlineMarkdown_x0d1c_75 inline-markdown text-size-chat-sm font-mono blend bg-token-text-code-block-background rounded-sm px-1.5 py-0.5 leading-none extension:bg-token-foreground/10 electron:bg-token-list-hover-background/60">pymysql</span> pour MySQL
- <span class="_inlineMarkdown_x0d1c_75 inline-markdown text-size-chat-sm font-mono blend bg-token-text-code-block-background rounded-sm px-1.5 py-0.5 leading-none extension:bg-token-foreground/10 electron:bg-token-list-hover-background/60">pymssql</span> pour SQL Server

Le connecteur SQLite est également supporté.

Tous les drivers sont téléchargéq lors de l'installation du module.

**2. Point d’attention**  
Si le driver Python correspondant au connecteur choisi n’est pas installé sur le serveur, le test de connexion et l’ouverture de session échoueront avec un message explicite.

# Configuration

**1. Menu de configuration**  
Le module ajoute un menu d’administration contenant :

- <span class="_inlineMarkdown_x0d1c_75 inline-markdown text-size-chat-sm font-mono blend bg-token-text-code-block-background rounded-sm px-1.5 py-0.5 leading-none extension:bg-token-foreground/10 electron:bg-token-list-hover-background/60">Sources de données</span>
- <span class="_inlineMarkdown_x0d1c_75 inline-markdown text-size-chat-sm font-mono blend bg-token-text-code-block-background rounded-sm px-1.5 py-0.5 leading-none extension:bg-token-foreground/10 electron:bg-token-list-hover-background/60">Configurations de connexion</span>

**2. Configuration de connexion**  
Une configuration contient notamment :

- un nom unique de configuration
- un connecteur
- un serveur et un port si nécessaire
- une base cible
- un utilisateur et un mot de passe si le connecteur l’exige
- un timeout de connexion [![image.png](https://docs.myfab.fr/uploads/images/gallery/2026-05/scaled-1680-/KIhimage.png)](https://docs.myfab.fr/uploads/images/gallery/2026-05/KIhimage.png)

**3. Test de connexion**  
Le bouton <span class="_inlineMarkdown_x0d1c_75 inline-markdown text-size-chat-sm font-mono blend bg-token-text-code-block-background rounded-sm px-1.5 py-0.5 leading-none extension:bg-token-foreground/10 electron:bg-token-list-hover-background/60">Tester la connexion</span> vérifie que la session SQL externe peut être ouverte.  
Le résultat est enregistré dans un journal directement sur la configuration.

En cas d’erreur, le message remonte une information exploitable pour l’utilisateur : cible visée, timeout éventuel et détail technique retourné par le driver SQL.

# Maintenance, bonnes pratiques et point d'attention

### **Maintenance et bonne pratique**

**1. Évolution du schéma SQL**  
Si la requête évolue et change de colonnes ou de types, il faut repasser la source en <span class="_inlineMarkdown_x0d1c_75 inline-markdown text-size-chat-sm font-mono blend bg-token-text-code-block-background rounded-sm px-1.5 py-0.5 leading-none extension:bg-token-foreground/10 electron:bg-token-list-hover-background/60">Brouillon</span>, puis relancer la génération du modèle et de l’interface avant tout nouveau rechargement.

**2. Verrouillages de sécurité**

- le nom des configurations de connexion doit être unique
- le nom des sources doit être unique
- la requête SQL ne peut plus être modifiée lorsque l’état n’est plus <span class="_inlineMarkdown_x0d1c_75 inline-markdown text-size-chat-sm font-mono blend bg-token-text-code-block-background rounded-sm px-1.5 py-0.5 leading-none extension:bg-token-foreground/10 electron:bg-token-list-hover-background/60">Brouillon</span>
- les champs structurants du modèle généré sont verrouillés une fois l’interface créée

**3. Suppression d’une source**  
La suppression d’une source supprime également les objets OpenProd générés qui lui sont associés : modèle manuel, données, vues, action, menu, cron et droits d’accès générés par le module.

**4. Recommandations**

- privilégier des requêtes SQL lisibles, stables et limitées au besoin métier réel
- conserver un alias <span class="_inlineMarkdown_x0d1c_75 inline-markdown text-size-chat-sm font-mono blend bg-token-text-code-block-background rounded-sm px-1.5 py-0.5 leading-none extension:bg-token-foreground/10 electron:bg-token-list-hover-background/60">Name</span> explicite dans la requête pour obtenir des libellés utilisateurs clairs
- tester systématiquement la connexion et la prévisualisation avant la première génération
- utiliser <span class="_inlineMarkdown_x0d1c_75 inline-markdown text-size-chat-sm font-mono blend bg-token-text-code-block-background rounded-sm px-1.5 py-0.5 leading-none extension:bg-token-foreground/10 electron:bg-token-list-hover-background/60">%date</span> uniquement si une première synchronisation a déjà été réalisée

### **Point d'attention**

Le module utilise des drivers python afin de se connecter aux différents système de gestion de base de données. Veuillez donc vous assurer d'avoir une version de votre système géré pas un des drivers suivant.

**SQLAlchemy (Python)**

1. Python 3.x: 3.7 ou plus récent

**PyMySQL (MySQL)**

1. Python 3.x: 3.7 ou plus récent
2. Mysql 5.7 ou plus récent
3. MariaDB 10.4 ou plus récent

**Pymssql (SQL Server)**

1. Python 3.x: 3.7 ou plus récent
2. FreeTDS 1.4.10 ou plus récent
3. Cython 3.0.7 ou plus récent
4. Microsoft SQL Server 2005 ou plus récent

<dl class="field-list simple" id="bkmrk-charge-syst%C3%A8me-le-ra"><dt class="field-odd">**Charge système**

</dt><dd class="field-odd">Le rafraîchissement des tables créées étant géré par des tâches planifiées (crons), l’activation d’un grand nombre de crons peut augmenter la charge système et ralentir le serveur. Il est donc recommandé d’éviter l’exécution simultanée de nombreux crons ou de configurer des fréquences de rafraîchissement trop élevées.

</dd></dl>**Modification de schéma**

<dl class="field-list simple" id="bkmrk-dans-le-cas-o%C3%B9-vous-"><dd class="field-odd">Dans le cas où vous repassez un enregistrement au brouillon afin de modifier son schéma (suppression ou ajout de colonnes), les vues personnalisées créées ainsi que les actions serveur utilisant le modèle généré peuvent devenir obsolètes. Cela peut notamment être dû à un changement de nom d’un champ ou à sa suppression.

</dd></dl>

# Exemple de mise en oeuvre

Exemple de mise en place d’une source de données externe alimentant un modèle OpenProd à partir d’une table SQL distante contenant des clients ou des tiers.

# Exemple

1. **Créer la configuration de connexion**  
    Créer une configuration nommée par exemple <span class="_inlineMarkdown_x0d1c_75 inline-markdown text-size-chat-sm font-mono blend bg-token-text-code-block-background rounded-sm px-1.5 py-0.5 leading-none extension:bg-token-foreground/10 electron:bg-token-list-hover-background/60">ERP secondaire - PostgreSQL ou SQL Server</span> avec :

- Connecteur : <span class="_inlineMarkdown_x0d1c_75 inline-markdown text-size-chat-sm font-mono blend bg-token-text-code-block-background rounded-sm px-1.5 py-0.5 leading-none extension:bg-token-foreground/10 electron:bg-token-list-hover-background/60">PostgreSQL</span>
- Serveur : <span class="_inlineMarkdown_x0d1c_75 inline-markdown text-size-chat-sm font-mono blend bg-token-text-code-block-background rounded-sm px-1.5 py-0.5 leading-none extension:bg-token-foreground/10 electron:bg-token-list-hover-background/60">10.0.0.15</span>
- Port : <span class="_inlineMarkdown_x0d1c_75 inline-markdown text-size-chat-sm font-mono blend bg-token-text-code-block-background rounded-sm px-1.5 py-0.5 leading-none extension:bg-token-foreground/10 electron:bg-token-list-hover-background/60">5432</span>
- Base : <span class="_inlineMarkdown_x0d1c_75 inline-markdown text-size-chat-sm font-mono blend bg-token-text-code-block-background rounded-sm px-1.5 py-0.5 leading-none extension:bg-token-foreground/10 electron:bg-token-list-hover-background/60">erp\_reporting</span>
- Utilisateur : compte de lecture dédié

- Connecteur : <span class="_inlineMarkdown_x0d1c_75 inline-markdown text-size-chat-sm font-mono blend bg-token-text-code-block-background rounded-sm px-1.5 py-0.5 leading-none extension:bg-token-foreground/10 electron:bg-token-list-hover-background/60">SQL Server</span>
- Serveur : <span class="_inlineMarkdown_x0d1c_75 inline-markdown text-size-chat-sm font-mono blend bg-token-text-code-block-background rounded-sm px-1.5 py-0.5 leading-none extension:bg-token-foreground/10 electron:bg-token-list-hover-background/60">10.0.0.16</span>
- Port : 1433
- Base : <span class="_inlineMarkdown_x0d1c_75 inline-markdown text-size-chat-sm font-mono blend bg-token-text-code-block-background rounded-sm px-1.5 py-0.5 leading-none extension:bg-token-foreground/10 electron:bg-token-list-hover-background/60">erp\_exemple</span>
- Utilisateur : compte de lecture dédié

**2. Créer la source de données**  
Créer une source nommée <span class="_inlineMarkdown_x0d1c_75 inline-markdown text-size-chat-sm font-mono blend bg-token-text-code-block-background rounded-sm px-1.5 py-0.5 leading-none extension:bg-token-foreground/10 electron:bg-token-list-hover-background/60">Clients externes</span> puis associer la configuration précédente.

**3. Saisir la requête SQL**  
Exemple :  
<span class="_inlineMarkdown_x0d1c_75 inline-markdown text-size-chat-sm font-mono blend bg-token-text-code-block-background rounded-sm px-1.5 py-0.5 leading-none extension:bg-token-foreground/10 electron:bg-token-list-hover-background/60">SELECT customer\_name AS Name, customer\_code AS test, city AS test2, last\_update FROM customer\_export WHERE active = true</span>

Dans cet exemple, la colonne <span class="_inlineMarkdown_x0d1c_75 inline-markdown text-size-chat-sm font-mono blend bg-token-text-code-block-background rounded-sm px-1.5 py-0.5 leading-none extension:bg-token-foreground/10 electron:bg-token-list-hover-background/60">Name</span> alimente automatiquement le champ <span class="_inlineMarkdown_x0d1c_75 inline-markdown text-size-chat-sm font-mono blend bg-token-text-code-block-background rounded-sm px-1.5 py-0.5 leading-none extension:bg-token-foreground/10 electron:bg-token-list-hover-background/60">x\_name</span> du modèle généré.  
Les colonnes <span class="_inlineMarkdown_x0d1c_75 inline-markdown text-size-chat-sm font-mono blend bg-token-text-code-block-background rounded-sm px-1.5 py-0.5 leading-none extension:bg-token-foreground/10 electron:bg-token-list-hover-background/60">test</span> et <span class="_inlineMarkdown_x0d1c_75 inline-markdown text-size-chat-sm font-mono blend bg-token-text-code-block-background rounded-sm px-1.5 py-0.5 leading-none extension:bg-token-foreground/10 electron:bg-token-list-hover-background/60">test2</span> deviendront respectivement <span class="_inlineMarkdown_x0d1c_75 inline-markdown text-size-chat-sm font-mono blend bg-token-text-code-block-background rounded-sm px-1.5 py-0.5 leading-none extension:bg-token-foreground/10 electron:bg-token-list-hover-background/60">x\_test</span> et <span class="_inlineMarkdown_x0d1c_75 inline-markdown text-size-chat-sm font-mono blend bg-token-text-code-block-background rounded-sm px-1.5 py-0.5 leading-none extension:bg-token-foreground/10 electron:bg-token-list-hover-background/60">x\_test2</span>.

**4. Prévisualiser**  
Utiliser le bouton <span class="_inlineMarkdown_x0d1c_75 inline-markdown text-size-chat-sm font-mono blend bg-token-text-code-block-background rounded-sm px-1.5 py-0.5 leading-none extension:bg-token-foreground/10 electron:bg-token-list-hover-background/60">Prévisualiser la requête</span> pour vérifier que les colonnes exposées, les libellés et les lignes retournées correspondent au besoin.

**5. Générer le modèle OpenProd**  
Cliquer sur <span class="_inlineMarkdown_x0d1c_75 inline-markdown text-size-chat-sm font-mono blend bg-token-text-code-block-background rounded-sm px-1.5 py-0.5 leading-none extension:bg-token-foreground/10 electron:bg-token-list-hover-background/60">Créer ou mettre à jour le modèle et l’interface</span>.  
Le module crée alors un modèle manuel du type <span class="_inlineMarkdown_x0d1c_75 inline-markdown text-size-chat-sm font-mono blend bg-token-text-code-block-background rounded-sm px-1.5 py-0.5 leading-none extension:bg-token-foreground/10 electron:bg-token-list-hover-background/60">x\_external\_clients\_externes</span> avec les champs nécessaires et l’interface OpenProd associée.

**6. Charger les données**  
Cliquer sur <span class="_inlineMarkdown_x0d1c_75 inline-markdown text-size-chat-sm font-mono blend bg-token-text-code-block-background rounded-sm px-1.5 py-0.5 leading-none extension:bg-token-foreground/10 electron:bg-token-list-hover-background/60">Charger ou recharger les données</span> pour importer les lignes dans le modèle généré, puis ouvrir la liste avec le bouton dédié.

**7. Variante incrémentale**  
Si la table source contient une date de modification, la requête peut être adaptée avec <span class="_inlineMarkdown_x0d1c_75 inline-markdown text-size-chat-sm font-mono blend bg-token-text-code-block-background rounded-sm px-1.5 py-0.5 leading-none extension:bg-token-foreground/10 electron:bg-token-list-hover-background/60">%date</span> après une première synchronisation réussie.

# Utilisation dans une action serveur

Il est possible d'utiliser un enregistrement du module directement dans une action serveur.

La méthode à utiliser est <span class="_inlineMarkdown_x0d1c_75 inline-markdown text-size-chat-sm font-mono blend bg-token-text-code-block-background rounded-sm px-1.5 py-0.5 leading-none extension:bg-token-foreground/10 electron:bg-token-list-hover-background/60">mf\_execute</span>, qui attend comme paramètres une requête SQL via <span class="_inlineMarkdown_x0d1c_75 inline-markdown text-size-chat-sm font-mono blend bg-token-text-code-block-background rounded-sm px-1.5 py-0.5 leading-none extension:bg-token-foreground/10 electron:bg-token-list-hover-background/60">query</span>, des paramètres d’exécution optionnels via <span class="_inlineMarkdown_x0d1c_75 inline-markdown text-size-chat-sm font-mono blend bg-token-text-code-block-background rounded-sm px-1.5 py-0.5 leading-none extension:bg-token-foreground/10 electron:bg-token-list-hover-background/60">execute\_params</span>, et un booléen <span class="_inlineMarkdown_x0d1c_75 inline-markdown text-size-chat-sm font-mono blend bg-token-text-code-block-background rounded-sm px-1.5 py-0.5 leading-none extension:bg-token-foreground/10 electron:bg-token-list-hover-background/60">metadata</span> permettant de préciser si le retour doit inclure uniquement les lignes ou également les métadonnées de colonnes.

[![image.png](https://docs.myfab.fr/uploads/images/gallery/2026-06/scaled-1680-/B65image.png)](https://docs.myfab.fr/uploads/images/gallery/2026-06/B65image.png)

Côté Openprod, pour faire de la lecture en test il est recommandé d'utiliser la méthode UserError qui permet d'afficher soit les noms des colonnes, soit leur contenu. Ici avec les variables cols et rows.

*Affichage de la variable 'cols' :*

[![image.png](https://docs.myfab.fr/uploads/images/gallery/2026-06/scaled-1680-/FuTimage.png)](https://docs.myfab.fr/uploads/images/gallery/2026-06/FuTimage.png)