BERKIOS Excel Engine (prototype initial)
Objectif : importer un classeur Excel existant et créer un fichier .berkios.json contenant les feuilles, cellules, formules traduites et diagnostics.
Prérequis
- Node.js >= 22.18
- Installer les dépendances :
npm installdans ce dossier.
Conversion
node src/cli.mjs "C:/chemin/classeur.xlsx"
node src/cli.mjs "C:/chemin/classeur.xlsm" "sortie.berkios.json"Formats ciblés : .xlsx, .xlsm, .xls. Le format de fichier est accepté indépendamment de la version d'Excel ayant créé le classeur (Excel 2013 et versions ultérieures). Les fonctions récentes propres à Microsoft 365 peuvent toutefois nécessiter une implémentation dédiée.
Contenu et limites actuelles
- Importe les noms des feuilles, plages utilisées, cellules, valeurs, formules, formats numériques, cellules fusionnées et noms définis.
- Traduit un premier ensemble de fonctions Excel (SUM, AVERAGE, IF, AND, ROUND, VLOOKUP, XLOOKUP, etc.) vers des noms d'expressions BERKIOS provisoires.
- Ajoute des diagnostics lorsque les fonctions/références ne sont pas reconnues.
- Détecte la présence d'un projet VBA binaire, mais ne prétend pas encore décompiler/traduire automatiquement les modules VBA. Le code VBA n'est jamais exécuté pendant l'import.
- Les feuilles sont conservées comme données structurées (
excelWorkbook) et converties en interfaces (voir « Génération des interfaces » ci-dessous). - Un import n'est pas une garantie de compatibilité parfaite. Toujours examiner
excelTranslation.diagnosticset tester le résultat avant usage en production.
Sécurité
Les macros, liens externes et formules doivent être traités comme du contenu non fiable. Aucun code VBA n'est exécuté par le convertisseur. Toute future exécution de macros traduites devra passer par les permissions et capacités du moteur BERKIOS, avec confirmation pour les accès fichiers, réseau et système.
Exécution autonome après conversion
Une fois le fichier .berkios.json créé, l'application convertie ne nécessite pas Microsoft Excel ni l'installation d'Excel sur la machine cible. Le classeur est stocké comme données structurées dans le JSON; le runtime BERKIOS relit ces données et recalcule le sous-ensemble de formules pris en charge. La dépendance xlsx sert uniquement à importer le fichier source .xlsx/.xlsm/.xls et n'est pas utilisée par le runtime après conversion.
API runtime (Node.js) :
import { loadBerkiosProject, readCell, writeCell, saveBerkiosProject } from './src/standalone-runtime.mjs';
const app = loadBerkiosProject('./gestion_stock.berkios.json');
console.log(readCell(app, 'Stock', 'B2'));
writeCell(app, 'Stock', 'A2', 42); // recalcule les formules prises en charge
saveBerkiosProject(app); // persiste les données dans le projet BERKIOSLimites importantes : le runtime autonome est une première couche technique, pas encore une intégration complète à tous les contrôles visuels et événements du Studio. Les fonctions/formules non prises en charge sont diagnostiquées et ne doivent pas être considérées comme fidèlement exécutées. Les macros VBA ne sont pas exécutées automatiquement. Les formules nécessitant des services Excel, des compléments, des connexions externes ou des fonctionnalités propriétaires nécessitent une réimplémentation BERKIOS explicite.
Traduction statique de modules VBA exportés (v0.7.147)
Le traducteur reconnaît maintenant un sous-ensemble supplémentaire : procédures Sub/Function, événements courants (Workbook_Open, Worksheet_Change, Worksheet_SelectionChange, *_Click, *_Change), affectations Range(...).Value, Cells(ligne,colonne).Value, MsgBox, Debug.Print, conditions If/ElseIf/Else et boucles simples For...To...Next. Les boucles et les événements restent marqués pour revue, car une syntaxe traduite ne garantit pas une équivalence de comportement.
Pour convertir les macros, exportez d'abord les modules VBA depuis l'éditeur VBA d'Excel vers des fichiers .bas ou .cls, puis fournissez-les à la commande d'import :
node src/cli.mjs "C:/fichiers/gestion.xlsm" "gestion.berkios.json" --vba "C:/fichiers/Module1.bas" --vba "C:/fichiers/Feuil1.cls"Les procédures et événements détectés sont enregistrés dans excelTranslation.macros et events; les appels inconnus et instructions sensibles produisent des diagnostics. Le moteur n'extrait pas automatiquement le code source depuis le projet VBA binaire et n'exécute jamais le VBA original. La traduction obtenue est une base à vérifier et non une garantie de conversion complète.
Événements Excel ↔ composants BERKIOS (v0.7.171)
src/component-event-bridge.mjs relie les événements importés (qui désignent un contrôle par son nom : btnEnregistrer_Click) aux composants générés (qui ont un identifiant : if_frmclient__btn_enregistrer).
linkExcelEventsToComponents(project, interfaces): à l'import, chaque événementui.click/ui.changereçoitcomponentIdetcomponentBinding(resolved,unresolvedouambiguous). Le nom de contrôle est déduit deBouton_Clickpour les modules VBA comme pour les UserForms ;formNamerestreint la recherche à l'interface du formulaire (interface.sourceForm). Rien n'est deviné : introuvable ou ambigu → diagnosticEXCEL_EVENT_COMPONENT_*etrequiresReview.bindExcelEventToComponent(project, eventId, componentId, interfaces): association manuelle d'un cas non résolu.handleComponentEvent(project, interfaces, { componentId, event: 'click'|'change'|'input', value? }, options): point d'entrée pour une interaction sur un composant.changeécrit la cellule liée (validation incluse), recalcule, puis déclenchesheet.changeetui.change. Retournechanges(propriétés de composants modifiées),messages(ui-message) etpending(événements non activés, non exécutés).describeExcelEventLinks(project): tableau de revue (cible résolue, actions valides, activable ou non).- Les liaisons cellule sont lues sous leurs deux formes : moteur
{sheet, cell}ou Studio{worksheet, address}(feuille absente = feuille active ; plageA1:B3refusée). La forme Studio n'est jamais réécrite.
Résoudre un événement ne l'active pas : il reste needs_review jusqu'à enableExcelEvent.
Runtime des événements (v0.7.148)
src/event-runtime.mjs route les événements vers une liste blanche d’actions Excel BERKIOS (excel-read, excel-write, excel-recalculate, excel-save). Les événements VBA restent à valider; aucun code VBA ou JavaScript n’est exécuté. Voir tests/event-runtime.test.mjs.
Génération des interfaces (v0.7.150)
Chaque feuille devient une interface du projet ; chaque UserForm exporté (.frm) devient une interface modale. Le rôle d'une feuille est déduit de sa structure (aucune macro n'est exécutée) :
| Structure détectée | Rôle | Interface générée |
|---|---|---|
| Ligne d'en-têtes + lignes de données | table | Modèle de données SQLite (types déduits des noms/valeurs, clé primaire, seed des lignes existantes) + tableau lié (recherche, tri, édition) + formulaire de saisie (data-create) |
En-têtes dont ≥ 2 « Total… », ou nom Rapport/Bilan/Synthèse… | report | Critères de filtre, cartes KPI, tableau de détail rattaché au modèle le plus proche |
| Paires libellé / formule | dashboard | Cartes KPI liées au modèle quand le calcul est exact (COUNTA, SUM, AVERAGE, MIN, MAX sur une colonne) |
| Texte seul | text | Étiquettes (titre, sous-titres, paragraphes) |
| En-têtes + cellules calculées | grid | Tableau en lecture seule |
Autres déductions : valeurs de listes de choix lues dans les critères de SUMIF/COUNTIF (ex. "DEPOT", "RETRAIT"), relations entre modèles (colonne ID_Client ↔ clé ID_Client), barre de navigation open-interface sur chaque page.
UserForms
node src/cli.mjs "gestion.xlsm" "gestion.berkios.json" --frm "frmMenu.frm" --frm "frmClient.frm"Exporter chaque UserForm depuis l'éditeur VBA (clic droit → Exporter un fichier…). Contrôles convertis : Label, TextBox, ComboBox, ListBox, CheckBox, OptionButton, CommandButton, Frame (positions des contrôles imbriqués cumulées). Gestionnaires xxx_Click reconnus : Unload Me/Me.Hide → close-interface, frmX.Show → open-interface, écriture dans Sheets("X") d'une feuille convertie en modèle → data-create (champs appariés par nom de contrôle : txtNom → nom). Le reste est signalé dans excelTranslation.diagnostics. Les ressources .frx ne sont pas lues.
Ce qui reste à vérifier après l'import
excelTranslation.kpiMappings: un KPIneeds_reviewest affiché avec⚠ à vérifier. Les sommes conditionnelles (SUMIF) ne sont pas calculables par un KPI (pas de filtre) ; le filtre détecté est conservé dans le mapping.excelTranslation.assumptions: choix proposés par défaut (ex. Sexe : M/F) absents du classeur.- Les règles métier écrites en VBA (numérotation, calcul de solde, contrôles) ne sont pas reprises.
Formules recalculées par le runtime (v0.7.168)
Le runtime autonome exécute localement, sans Excel, 98 fonctions (priorités 1 et 2 : SUMIF(S), COUNTIF(S), VLOOKUP, XLOOKUP, INDEX, MATCH, CONCATENATE, LEFT/RIGHT/MID/LEN, MOD, INT, SUBTOTAL, TODAY, NOW, DATE, YEAR/MONTH/DAY, TRIM, UPPER, LOWER, IFNA, IFERROR… et bien d'autres). La liste complète, générée depuis le code, est dans FONCTIONS_EXCEL.md.
Source unique : src/function-registry.mjs porte, pour chaque fonction, son nom Excel, son nom BERKIOS et son implémentation. Le traducteur (translateFormula), le moteur (recalculateWorkbook, supportedRuntimeFunctions) et le Studio la lisent : une fonction ne peut pas être « reconnue » sans être exécutable. translateFormula(...).executable indique si une formule entière est recalculable ; les fonctions Excel connues mais non exécutables (FILTER, OFFSET, INDIRECT, LET…) sont signalées par FORMULA_FUNCTION_UNSUPPORTED (reason: known-not-executable).
Le moteur gère les références inter-feuilles (Feuille!A1, 'Nom feuille'!A1:B2), les colonnes/lignes entières (A:A, 1:1), les noms définis, les constantes matricielles, les opérations matricielles dans SUMPRODUCT, les valeurs d'erreur Excel et la détection des références circulaires (FORMULA_CIRCULAR_REFERENCE).
Limites connues :
- Pas de déversement matriciel : un résultat de plusieurs cellules n'est pas écrit dans la feuille (diagnostic
FORMULA_RUNTIME_UNSUPPORTED,reason: array-result) ; il reste utilisable comme argument. - Classeurs liés : valeurs en lecture seule, sans noms définis externes ni références 3D externes (voir « Classeurs liés » ci-dessous) ; système de dates 1900 uniquement ; noms de mois et de jours de
TEXTnon pris en charge. - Les cellules en erreur sont stockées en texte (
calculatedValue: "#N/A") aveccalculationError. - Une cellule non calculable garde sa valeur Excel importée et le statut
needs_review;calculationDiagnosticen donne la cause.
Actions métier du runtime (v0.7.168)
Le code VBA importé n'est jamais exécuté. Un bouton, un formulaire ou un événement n'a d'effet que par des actions déclaratives BERKIOS : excel-read, excel-write, excel-recalculate, excel-save, ui-set-property, ui-message et run-procedure (procédure du même module). Chaque action est validée avant exécution (validateAction : adresse de cellule valide, valeurs littérales uniquement), reste en needs_review jusqu'à enableExcelEvent / enableExcelProcedure, et une erreur sur une action n'interrompt pas les suivantes. Les appels de procédures sont bornés (profondeur 8, 1000 actions par déclenchement). excelTranslation/project.procedures listent les procédures non-événement extraites du VBA.
Import complet d'un classeur : feuille de route et couverture (v0.7.198+)
SheetJS ne lit ni les macros, ni les graphiques, ni les dessins, ni les contrôles ActiveX, ni les zones d'impression. L'import lit donc directement le package OOXML (src/ooxml-reader.mjs, sans dépendance) et suit une matrice de couverture à trois statuts :
| Statut | Signification |
|---|---|
inventoried | Détecté et décrit dans project.excelPackage.inventory ; conservé intact dans l'archive d'origine, pas encore reproduit. Un diagnostic OOXML_<FAMILLE>_NOT_REPRODUCED le signale. |
imported | Converti en modèle BERKIOS (données exploitables par le Studio). |
rendered | Reproduit à l'écran / à l'impression. |
project.excelPackage.coverage liste uniquement les familles présentes dans le classeur : vba, charts, shapes, pictures, smartArt, activeX, formControls, printAreas, pageSetup, conditionalFormatting, dataValidations, sparklines, pivotTables, oleObjects, freezePanes.
Archive d'origine. Tant qu'une famille est inventoried, le convertisseur conserve le classeur source (project.excelImport.original : nom, taille, SHA-256, stockage). Option preserveOriginal : auto (défaut : copie « <projet>.source.xlsm » à côté du projet si des éléments ne sont pas reproduits), sidecar, embed (base64 dans le projet, 64 Mio max) ou none. En CLI : --keep-original[=auto|sidecar|embed|none].
État actuel (étape 1/10) : inventaire complet (VBA binaire repéré avec empreinte, graphiques avec séries, dessins avec ancrages, groupes imbriqués, images liées à leurs médias, ActiveX identifiés par classe, contrôles de formulaire avec cellule liée, zones/titres d'impression, mise en page, volets figés, formats conditionnels, validations, tableaux). Aucune famille n'est encore reproduite ; les .xls binaires ne sont pas inventoriés. ZIP64 refusé explicitement.
Limite sur la fidélité visuelle des classeurs
L'import conserve les données et plusieurs métadonnées Excel, mais le générateur actuel déduit un type d'interface (tableau, rapport, tableau de bord, grille ou texte) et reconstruit une interface BERKIOS. Il ne garantit pas une reproduction pixel à pixel de la feuille d'origine : tailles/positions exactes de chaque objet Excel, thèmes, dessins, graphiques, contrôles ActiveX, zones d'impression et comportements VBA complexes peuvent ne pas être reproduits. Ces éléments doivent être diagnostiqués séparément plutôt que présentés comme fidèlement importés.
Classeurs liés (v0.7.169)
Un classeur Excel qui lit un autre classeur (=[1]Budget!B2, =SUM('[2]Stock 2026'!A:A)) devient une application qui lit les valeurs embarquées de ce classeur, sans Excel et sans jamais suivre le chemin d'origine du lien.
Import. Le cache de dernière mise à jour d'Excel (xl/externalLinks) est lu sans SheetJS et stocké dans excelWorkbook.externalWorkbooks[] (index, fileName, target, source, sheets). Pour des valeurs plus récentes que ce cache, fournissez le classeur lié :
node src/cli.mjs "synthese.xlsx" "synthese.berkios.json" --linked "Budget.xlsx" --linked "Stock.xlsx"Dans un bundle : { "role": "linked-workbook", "path": "Budget.xlsx" } (répétable, facultatif). Le classeur lié est associé au lien par son nom de fichier.
source | Origine des valeurs |
|---|---|
excel-cache | cache de la dernière mise à jour dans Excel (à vérifier : peut être périmé) |
linked-file | classeur lié fourni à l'import (--linked) |
linked-project | autre projet BERKIOS converti, recalculé à l'ouverture |
manual | valeurs fournies par l'application via updateExternalLink |
Diagnostics (excelTranslation.diagnostics, bilan dans excelTranslation.externalLinks) : EXTERNAL_LINK_CACHED (valeurs du cache), EXTERNAL_LINK_UNRESOLVED (formule vers un classeur absent), EXTERNAL_LINK_REFRESH_ERROR (actualisation échouée dans Excel), EXTERNAL_LINK_UNUSED_FILE, EXTERNAL_LINK_KIND_UNSUPPORTED (DDE/OLE), EXTERNAL_LINK_XLS_NOT_READ (.xls : enregistrez en .xlsx).
Runtime :
import { loadBerkiosProject, readCell, listExternalLinks, updateExternalLink, updateExternalLinkFromProject } from './src/standalone-runtime.mjs';
// Deux projets convertis qui se lisent mutuellement (équivalent de « Mettre à jour les liens ») :
const app = loadBerkiosProject('synthese.berkios.json', { linkedProjects: { 'Budget.xlsx': 'budget.berkios.json' } });
updateExternalLink(app, 'Budget.xlsx', { Data: { A1: 200 } }); // valeurs fournies par l'application
listExternalLinks(app); // origine et date de chaque lienComportement : classeur ou feuille liée absent → la formule passe en needs_review (external-workbook-missing, external-sheet-missing), ses dépendants gardent la valeur Excel d'origine ; une cellule absente du classeur lié vaut vide ; [0] désigne le classeur courant.
Limites : lecture seule (aucune écriture vers un classeur lié) ; noms définis externes ([1]!Nom) et références 3D externes non exécutés ; liens DDE/OLE ignorés ; .xls : liens non lus ; pas de mise à jour automatique depuis le chemin d'origine (volontaire).
BERKIOS Excel Cloud Engine (prototype — phase 1)
The structural analyzer is available in src/cloud/analyzer.mjs. It creates a reviewable JSON inventory before any cloud backend is generated. See CLOUD_ENGINE_PHASE1.md.
npm run cloud:analyze -- ../chemin/classeur.xlsm --out ./rapport-cloud.jsonThis is deliberately an analysis-only phase: no workbook mutation, VBA execution, PostgreSQL writes, or remote synchronization.
Phase 3 — importation initiale
src/cloud/importer.mjs copie les lignes Excel vers PostgreSQL (validation, doublons, relations, rapport, reprise, correspondance ligne Excel ↔ enregistrement). Voir CLOUD_ENGINE_PHASE3.md.
npm run cloud:import -- ./classeur.xlsx --analysis ./a.json --plan ./p.json --dry-runCette page en Markdown · llms.txt · documentation complète pour les IA