Sources, export et push
Trois chemins d'écriture existent, chacun avec une cible différente :
- la répercussion écrit la préparation de création dans la source.
- l'export réécrit les valeurs des SO bake dans les fichiers de feuille.
- le Push écrit les valeurs des SO bake vers la feuille Google en direct, cellule par cellule.
Sources d'import
La source d'import est un choix de premier ordre dans l'asset de paramètres. Chaque source déclare sa propre capacité de création (CanAuthor) :
| Source | Ce qu'elle lit | Création (écriture en retour) |
|---|---|---|
| LocalFile | Un dossier de fichiers .tsv / .csv / .xlsx (enfants immédiats uniquement ; un fichier = un onglet, les classeurs xlsx apportent leurs feuilles) | Complète — répercussion, modification de structure, renommage de clé/onglet |
| GoogleSheet · SheetsApi | Une feuille de calcul privée/partagée via une authentification JWT de compte de service (guide de configuration) | Complète — écritures de cellule chirurgicales, réécriture de structure, Push |
| GoogleSheet · ExportUrl | Une feuille partagée par lien via son URL d'export — aucune authentification requise | Lecture seule (CanAuthor = false) — Push/répercussion/modification de structure/suppression sont désactivés, avec une explication |
| Fournisseurs personnalisés | Tout ce qu'un plugin enregistre (ISheetSourceProvider — DB, REST, formats maison) | Au choix du fournisseur, via son indicateur CanAuthor |
Remarques :
- ExportUrl requiert une gid map (nom d'onglet → valeur
#gid=). Une URL d'export sans gid renvoie silencieusement seulement le premier onglet, la map est donc imposée (GoogleSheetGidMapMissing, les gid en double sont rejetés). Le mode SheetsApi découvre automatiquement les onglets et n'a besoin d'aucune map. - Le lecteur/écrivain xlsx intégré est un OOXML écrit à la main (
System.IO.Compression+System.Xmluniquement — aucun NPOI/ClosedXML, zéro code tiers), si bien qu'il n'ajoute aucune DLL susceptible d'entrer en collision avec d'autres assets de votre projet. C'est un codec unique, partagé : le même lecteur tourne dans l'éditeur Unity et — compilé en WebAssembly — dans l'application web, si bien que les deux hôtes ne peuvent jamais se contredire sur une cellule. Il est volontairement minimal et honnête à ce sujet — valeurs uniquement, aucun recalcul :- Une cellule de formule fournit la valeur mise en cache dans le fichier. Une formule sans valeur en cache, et une cellule d'erreur (
#REF!,#DIV/0!), sont rejetées (UnsupportedXlsxCell) — enregistrez le classeur une fois dans Excel pour mettre les valeurs en cache, ou matérialisez les formules. - Une cellule au format date est lue comme sa date, rendue
yyyy-MM-dd— aussi bien le type de cellule ISO qu'un nombre brut dont le style est un format de date, avec les systèmes de dates 1900 et 1904 tous deux honorés — au lieu du numéro de série brut que stocke le fichier. Les autres formats numériques, les cellules fusionnées et les graphiques ne sont pas importés. - Ces interprétations — valeurs de formule mises en cache, dates en texte affiché, mise en forme ignorée — sont la politique fixe du lecteur dans les deux hôtes, et la boîte de dialogue d'import de l'application web nomme en plus celles qui se sont réellement produites dans une note « Comment ce classeur a été lu ».
- Une tabulation ou un saut de ligne à l'intérieur d'une cellule est rejeté (
UnsupportedCellCharacter) — utilisez;pour les listes. - Les codes de type de cellule que le lecteur ne reconnaît pas sont lus comme leur texte brut stocké, et non rejetés.
- Une cellule de formule fournit la valeur mise en cache dans le fichier. Une formule sans valeur en cache, et une cellule d'erreur (
- Les fichiers locaux doivent être en Unicode. Un BOM UTF-8 ou un BOM UTF-16 (LE ou BE) est honoré ; en l'absence de BOM, le fichier est décodé en UTF-8 strict. Un encodage historique sur un octet comme CP949 ou Shift-JIS est rejeté (
UnsupportedEncoding), et non deviné. Une supposition se décoderait différemment d'une machine à l'autre et corromprait silencieusement les données. Réenregistrez le fichier en UTF-8. - Une source peut renvoyer une sortie partielle — un fichier cassé ne fait pas perdre les onglets lisibles ; les problèmes arrivent sous forme de diagnostics.
- Les fournisseurs de source personnalisés sont découverts automatiquement et apparaissent dans la même liste déroulante de paramètres — voir Création de plugins.
- Le studio vous prévient quand la source a évolué sans vous. Au focus de la fenêtre — ou à la demande depuis le menu ⋯ — le studio relit la source et la compare à l'instantané de votre dernier import, et n'affiche un badge que lorsque les données diffèrent réellement : une feuille simplement réenregistrée ou reformatée reste silencieuse, car la comparaison porte sur le contenu, pas sur les horodatages. Cliquer sur le badge propose de lancer l'import ; rien n'interroge sur une minuterie, rien n'importe de lui-même, et être hors ligne ou non autorisé signifie simplement l'absence de badge. Cela fonctionne de la même façon pour chaque type de source — fichiers locaux, feuilles par URL d'export et Sheets API, à l'identique.
Export — la moitié retour de l'aller-retour
⋯ ▸ Lancer l'export dans la barre d'outils du Data Studio réécrit les valeurs des SO bake dans les fichiers de feuille.
- La structure vient de la baseline, les valeurs des SO. L'export échange les valeurs actuelles dans l'instantané de baseline de la structure de votre feuille. Les lignes de marqueur, l'ordre des colonnes, les commentaires et le texte écrit à la main sont préservés à 100 %.
- Aller-retour sémantique des valeurs : la normalisation
1.0↔1est autorisée (valeur identique) ; les flottants utilisent le format d'aller-retour le plus court ; toujours un.décimal. - Formats :
Tsv/Csv/Xlsx/Json/MatchSource— chaque onglet retourne au format depuis lequel il a été importé ; une origine Google ou inconnue retombe sur Tsv.Jsonest un format de sortie uniquement, pensé pour des machines plutôt que des tableurs : un fichier par onglet, les enregistrements comme des objets,int/float/boolcomme de vrais nombres et booléens JSON, et toute autre valeur — références, listes, couleurs, courbes, types personnalisés — dans le texte de cellule canonique exact que porte la feuille, si bien qu'un serveur ou un outil externe peut consommer les données de jeu sans analyser le texte de la feuille. JSON n'est pas une source d'import, et un fichier JSON ne porte aucune structure de feuille à faire aller-retour — la feuille reste canonique. TSV et CSV écrivent un fichier par onglet ;Xlsxécrit tous les onglets exportés dans un seul classeur (SheetForge.xlsx), chaque onglet comme sa propre feuille dans l'ordre des onglets — un classeur est le format fait pour contenir plusieurs feuilles, et les garder ensemble est aussi ce qui permet aux menus déroulants de référence de pointer d'une feuille à l'autre (ci-dessous). SousMatchSource, les onglets d'origine xlsx se rassemblent dans ce classeur unique tandis que les autres retournent à leurs propres fichiers. Un nom de feuille que les règles du classeur ne peuvent pas porter (trop long, ou un caractère interdit) est ajusté et signalé par son nom — jamais renommé silencieusement. - La fraîcheur est imposée : exporter avec un bake périmé après un changement de schéma échoue avec
ExportSchemaMismatch. LaSchemaFingerprintdu bake doit correspondre à celle de la baseline, lancez donc d'abord un import. - Les références d'asset s'exportent sous forme du texte d'adresse qu'utilise la feuille — la clé, ou
parent[sub]pour un sous-asset ; le groupe est celui de la colonne — jamais sous forme de GUID. Les colonnes typées (AssetRef@Group<Type>) font l'aller-retour de la même façon. Les valeursColor,AnimationCurveetGradientreviennent sous leur forme de texte canonique (voir Syntaxe des feuilles) ; une courbe sans clé s'exporte comme une cellule vide, et une couleur est bornée à 0…1 (pas de HDR).
Push — écriture en retour au niveau de la cellule vers Google Sheets
⋯ ▸ Push vers Google Sheet dans la barre d'outils du Data Studio envoie les valeurs des SO bake vers la feuille en direct, cellule par cellule. L'élément est désactivé, avec la raison précisée, sauf si la source active est Google Sheets en mode API. Il est conçu pour ne jamais corrompre une feuille en direct que quelqu'un d'autre est en train de modifier.
Trois garanties découlent de cette chaîne :
- Rien n'est envoyé sans votre approbation d'un plan au niveau de la cellule.
- Une cellule modifiée sur la feuille en direct après votre import est ignorée, jamais écrasée.
- Une suppression de ligne n'est envoyée que lorsque la feuille en direct montre encore cette clé sur exactement cette ligne — tout ce qui a dérivé est ignoré avec un avis, jamais deviné.
La chaîne de sécurité, dans l'ordre :
- Identifiants SheetsApi requis — le Push en mode ExportUrl est refusé avant tout appel réseau (
GooglePushRequiresSheetsApi). - Une colonne clé est requise par onglet poussé — le Push relocalise chaque ligne par clé dans la feuille en direct. C'est ainsi qu'il détecte une ligne qui a bougé et ignore cette écriture en toute sécurité, sans jamais l'envoyer à la mauvaise ligne. Un onglet sans clé comportant des changements est refusé (
PushKeylessTabUnsupported). - Plan + approbation : un diff au niveau de la cellule (baseline contre SO actuelle) est calculé sous forme de plan — écritures, ajouts, suppressions de ligne. Le plan est présenté pour approbation explicite avant que quoi que ce soit ne soit envoyé ; les suppressions figurent dans leur propre section, chacune nommée par la clé qui va disparaître. Rejet = zéro cellule envoyée.
- Nouvelle récupération en direct avant envoi : immédiatement avant l'envoi, la feuille en direct est récupérée de nouveau et comparée. Les cellules en conflit sont ignorées, jamais écrasées (signalées comme avertissements) :
PushConflictCellChanged— un tiers a modifié cette cellule.PushConflictRowMoved— la clé a été trouvée à une ligne différente de celle vue par votre import, donc l'écriture est ignorée (jamais envoyée à la mauvaise ligne). Réimportez pour resynchroniser, puis relancez un Push.PushConflictRowMissing— la ligne a été supprimée de l'extérieur.PushConflictDuplicateLiveKey/PushConflictAppendKeyExists— cibles ambiguës.
- Les suppressions de ligne sont associées par clé avant d'être envoyées. Un enregistrement que vous avez supprimé n'est retiré de la feuille en direct qu'après que la récupération précédant l'envoi confirme que sa clé se trouve toujours sur exactement la ligne vue par votre import : une ligne déjà disparue compte comme faite (un nouveau Push ne supprime rien deux fois), et une clé trouvée sur une ligne différente — la feuille a dérivé — est ignorée avec un avis, jamais supprimée par position. Les suppressions sont envoyées en dernier, de bas en haut à l'intérieur de chaque onglet, si bien que les suppressions antérieures ne peuvent pas décaler les coordonnées de celles qui suivent. Une source incapable de supprimer des lignes (un fournisseur personnalisé sans cette capacité) retombe honnêtement sur l'ancien comportement : la suppression est signalée et la ligne en direct vous est laissée.
Après un Push, vérifiez les compteurs appliqué/ignoré du rapport. Si des cellules ont été ignorées, réimportez pour réconcilier, puis relancez un Push.
Changements de structure vers Google
Les modifications de structure (colonnes, marqueurs, réorganisation, renommages) sur une source Google réécrivent l'onglet cible entier. Une vérification de diff en direct vient d'abord, et une approbation explicite est requise avant d'écraser quoi que ce soit qui aurait changé sur la feuille depuis votre dernier import. Les modifications de valeur restent chirurgicales (par cellule) ; seule la structure emprunte le chemin de réécriture.
Enregistrements Addressables effectués par une répercussion
Déposer un asset sur une cellule AssetRef@Group dans le Data Studio, ou en choisir un depuis le projet, peut préparer un changement dans le projet en plus de la feuille : ajouter l'asset au groupe, le déplacer depuis un autre groupe, ou créer le groupe. Ces enregistrements font partie de la répercussion et s'exécutent à un endroit fixe de la chaîne — le même endroit pour un dossier local, une feuille Google et un fournisseur de source personnalisé :
- La validation préalable valide l'état projeté entier avec les enregistrements préparés comptant comme présents, si bien qu'une cellule qui pointe vers un asset pas encore enregistré n'est pas une erreur.
- La feuille est écrite. Si l'écriture est annulée ou échoue, rien de ce qui suit ne s'exécute : les paramètres Addressables restent intacts et les enregistrements restent préparés pour la prochaine tentative. Une répercussion qui n'a pu écrire aucun onglet parce que chaque onglet touché a été sauté (par exemple quand seuls des onglets d'origine classeur ont été touchés) ne les exécute pas non plus. Une répercussion qui n'a rien du tout à écrire dans la feuille — le seul changement préparé est un enregistrement — les exécute bel et bien et réimporte ; aucune autre modification préparée n'est validée par ce passage, si bien qu'il reste annulable.
- Les enregistrements s'exécutent, dans l'ordre : les groupes sont créés en premier (avec les
BundledAssetGroupSchemaetContentUpdateGroupSchemapar défaut), puis les entrées sont ajoutées ou déplacées et reçoivent leur adresse, et les paramètres sont enregistrés une seule fois. Chaque élément est revérifié immédiatement avant de s'exécuter et est sauté plutôt que forcé quand l'asset a été supprimé depuis, quand l'adresse est désormais prise par un autre asset dans ce groupe, quand le groupe n'a pas pu être créé ou trouvé, et quand plus aucune cellule ne référence l'adresse (un enregistrement ne crée jamais une entrée que rien ne désigne, et un groupe dont chaque entrée a été sautée n'est pas créé non plus). Si le projet n'a pas encore d'asset de paramètres Addressables, un est créé pour l'occasion. - La liste préparée est effacée — les éléments appliqués comme les sautés — et le réimport automatique suit, si bien que le bake voit les nouvelles entrées. Un enregistrement sauté est donc honnêtement signalé à ce réimport comme
UnknownAssetKeysur la cellule qui en avait besoin.
La console porte une ligne par résultat — Addressables: 'address' → group 'Group' pour chaque élément appliqué, Addressables: skipped 'address' (reason) comme avertissement pour chaque élément sauté — et une ligne de résumé Addressables: N registered, M skipped. Pour une source dossier local, la boîte de dialogue de fin de la répercussion se termine par cette même ligne de résumé.
Les menus déroulants inscrits dans la feuille
Les colonnes dont les choix sont finis reçoivent une règle de validation des données attachée à la feuille, afin que la personne qui modifie dans Google Sheets ou Excel choisisse dans une liste plutôt que de devoir se souvenir des orthographes. Rien n'a besoin d'être activé : les règles sont calculées à chaque Export, Push et écriture en retour de création, et appliquées partout où la cible peut les porter.
| Colonne | Règle |
|---|---|
Scalaire Enum<T> | Une liste fixe des membres de cet enum. |
Scalaire de référence (RecordId@Tab, et un type personnalisé avec parité de référence — §4.4a) | Une plage sur la colonne clé de l'onglet cible, laissée ouverte, de sorte que les enregistrements ajoutés à l'onglet cible rejoignent la liste d'eux-mêmes. |
List<>, les colonnes wrapper, la colonne clé elle-même | Aucune règle — une seule cellule y porte plusieurs valeurs, ou il n'y a pas de cible à lister. |
- Un guide, jamais une contrainte. Chaque règle est non stricte (Google
strict:false, xlsxshowErrorMessage="0") : une valeur en dehors de la liste est signalée par un marqueur d'avertissement mais reste acceptée. Un rejet strict casserait le flux de travail ordinaire « écrire la référence maintenant, définir l'enregistrement plus tard ». Il entrerait aussi en conflit avec les propres suggestions de correspondance la plus proche de l'import. - Les règles sont des métadonnées d'affichage, pas des valeurs. Elles n'apparaissent jamais dans une cellule, si bien que l'aller-retour n'est pas affecté. Un export sans règles est identique bit à bit à un export produit avant que cela n'existe.
- Appliquées indépendamment des valeurs. Attacher les règles est une étape à part entière plutôt qu'un effet de bord de l'écriture des cellules. Le flux le plus courant — ajouter un membre d'enum, ne changer aucune donnée — n'envoie aucune cellule, donc un effet de bord ne se déclencherait jamais. Attacher est idempotent, donc relancer l'opération ne change rien.
- Un échec est un avertissement, pas un push en échec. Si les valeurs sont bien parties et que seules les règles n'ont pas pu être attachées, le push a quand même réussi ; relancez-le et seules les règles seront réappliquées.
Ce que chaque format peut porter :
| Cible | Mécanisme | Remarques |
|---|---|---|
| Google Sheets (Push / écriture en retour) | setDataValidation, groupé en une seule requête | Les deux types de règle. La plage de référence omet sa ligne de fin, si bien qu'elle suit l'onglet cible à mesure qu'il grandit. |
| xlsx (Export) | dataValidations après les données de la feuille | Les deux types de règle. Comme l'export est un classeur unique, une plage de référence pointe vers la colonne clé de la feuille cible à l'intérieur du même fichier, laissée ouverte vers le bas de la feuille — la même signification que porte la plage Google. Une règle est encore ignorée, et nommée dans l'avertissement, dans trois cas honnêtes : un membre de liste contenant une virgule (le séparateur en ligne le scinderait), une liste en ligne dépassant la limite de spécification de 255 caractères (c'est la liste entière entre guillemets que le format plafonne), et une plage dont l'onglet cible n'est pas dans le classeur. |
| TSV / CSV (Export) | — | Le texte brut n'a nulle part où les placer. |
| JSON (Export) | — | Un fichier de données, pas un tableur — il n'y a aucune cellule à laquelle attacher un menu déroulant. |
Tout ce qui est laissé de côté est signalé honnêtement comme un unique avertissement DropdownNotSupportedByFormat par exécution, nommant chaque colonne concernée. La réponse à « pourquoi y a-t-il des menus déroulants sur Google mais pas dans mon fichier ? » se trouve donc dans le rapport plutôt que d'être un mystère. C'est un avertissement et non une erreur car les valeurs elles-mêmes ont été exportées intégralement ; seul le confort d'édition manque.
La gid map
Utilisée uniquement en mode ExportUrl. Chaque entrée fait correspondre un nom d'onglet à la valeur #gid= de la feuille (visible dans l'URL du navigateur lorsque l'onglet est sélectionné). L'inspecteur de paramètres n'affiche la map que lorsqu'elle est pertinente.
Vous n'avez pas besoin de copier ces nombres depuis le navigateur un par un. L'inspecteur de l'asset de paramètres dispose d'une section Google Sheets qui remplit la map pour vous.
- En mode ExportUrl, Auto-remplir le gid depuis le direct lit la liste des onglets de la feuille de calcul en direct et réécrit la map entière à partir de celle-ci, puis enregistre l'asset de paramètres.
- En mode SheetsApi, le même panneau propose à la place Récupérer la liste des onglets en direct, qui se contente de vous montrer les onglets que la feuille possède actuellement. Ce mode découvre les gid par lui-même et n'a besoin d'aucune map.
Une réserve : l'auto-remplissage dialogue avec l'API Sheets, il a donc besoin d'une clé de compte de service configurée, même si l'import ExportUrl lui-même n'en a pas besoin. Sans cela, il s'arrête et le signale plutôt que d'écrire une map à moitié remplie.
Le hook de fraîcheur de build — un bake périmé fait échouer le build
Avant chaque build, un hook pré-build vérifie trois choses pour chaque type Database généré et commité :
- (i) la SO bake existe ;
- (ii) son empreinte de schéma correspond à la baseline ;
- (iii) son enregistrement Addressables existe.
Tout échec interrompt le build avec une phrase exploitable (par ex. « ouvrez Tools/SheetForge/Data Studio, appuyez sur ↓ Pull from source, puis lancez le build »). C'est ce qui rend sûr le fait que « les SO bake sont gitignorées » : une machine clonée ou de CI ne peut physiquement pas livrer un cache vide.
Pages associées
- Prise en main — configuration et sécurité de la clé de compte de service
- Concepts fondamentaux — les baselines et le modèle d'aller-retour
- Data Studio — les écritures de création face au Push
- Capacités et limites — la liste complète des limites Google/xlsx