# Formules

- Human documentation: [https://docs.univer.ai/fr-FR/guides/sheets/features/core/formula](https://docs.univer.ai/fr-FR/guides/sheets/features/core/formula)

- Agent Markdown: [https://docs.univer.ai/fr-FR/guides/sheets/features/core/formula.md](https://docs.univer.ai/fr-FR/guides/sheets/features/core/formula.md)

- Requested language: `fr-FR`

- Content language: `fr-FR`

- Documentation version: `1.2.0`

- Source: [sheets/features/core/formula.fr-FR.mdx](https://github.com/dream-num/documentation/blob/dev/content/guides/sheets/features/core/formula.fr-FR.mdx)

---

Les formules constituent l’une des fonctionnalités principales d’Univer. Elles permettent de calculer des valeurs à partir de formules saisies dans les cellules. Les fonctions prises en charge sont compatibles avec Excel et comprennent notamment les fonctions mathématiques, logiques, textuelles et de date.

Lorsqu’un classeur contient un grand nombre de formules, leur calcul peut mobiliser le thread principal et réduire la réactivité de la page. Nous vous recommandons d’exécuter le calcul des formules dans un processus Worker afin de limiter son incidence sur le rendu et les interactions utilisateur. Pour en savoir plus sur la configuration, consultez la page [Web Workers](https://docs.univer.ai/fr-FR/guides/sheets/getting-started/worker.md).

## Configuration

Voici les liens vers les options de configuration associées au plugin de formules :

| Plugin                     | Option de configuration                                                               |
| -------------------------- | ------------------------------------------------------------------------------------- |
| `@univerjs/engine-formula` | [IUniverEngineFormulaConfig](https://docs.univer.ai/fr-FR/reference/packages/plugins/univerjs/engine-formula.md)     |
| `@univerjs/sheets-formula` | [IUniverSheetsFormulaBaseConfig](https://docs.univer.ai/fr-FR/reference/packages/plugins/univerjs/sheets-formula.md) |

`initialFormulaComputing` contrôle le calcul au chargement du classeur. Si les résultats enregistrés sont obsolètes, `CalculationMode.FORCED` les recalcule. En mode prédéfini, placez la même option dans `formula`.

Choisissez votre mode et ajoutez ces options à votre initialisation existante. Conservez les autres plugins et les paramètres de langue, de thème et de conteneur ; ne réenregistrez pas le même plugin.

#### Mode plugin

```typescript
import { CalculationMode, UniverSheetsFormulaPlugin } from '@univerjs/sheets-formula'

univer.registerPlugin(UniverSheetsFormulaPlugin, {
  initialFormulaComputing: CalculationMode.FORCED,
})
```

#### Mode prédéfini

```typescript
import { CalculationMode, UniverSheetsCorePreset } from '@univerjs/preset-sheets-core'
import { createUniver } from '@univerjs/presets'

const { univerAPI } = createUniver({
  presets: [
    UniverSheetsCorePreset({
      formula: {
        initialFormulaComputing: CalculationMode.FORCED,
      },
    }),
  ],
})
```

* `CalculationMode.FORCED`: Recalcule toutes les formules.
* `CalculationMode.WHEN_EMPTY`: Par défaut : calcule uniquement les cellules de formule sans valeur `v` enregistrée.
* `CalculationMode.NO_CALCULATION`: Désactive le calcul à l’initialisation.

## Références entre classeurs

Une formule peut agréger dans `Report` les ventes de `Sales.xlsx`. Contrairement à une référence vers une autre feuille du même classeur, elle identifie aussi le classeur source.

### Syntaxe des références

| Cas                            | Exemple                               | Cible                                         |
| ------------------------------ | ------------------------------------- | --------------------------------------------- |
| Autre feuille du même classeur | `=SUM(Data!A1:A10)`                   | Feuille Data du classeur courant              |
| Plage d’un autre classeur      | `=SUM('[Sales.xlsx]Data'!A1:A10)`     | Feuille Data de Sales.xlsx                    |
| Tableau d’un autre classeur    | `=SUM(Sales.xlsx!SalesTable[Amount])` | Colonne Amount du tableau SalesTable existant |

`Sales.xlsx` est un nom de classeur, pas un chemin ni une URL. Écrire une formule ne lit aucun fichier, ne télécharge pas Excel et ne connecte pas un éditeur dans une autre page. Créez le [tableau](https://docs.univer.ai/fr-FR/guides/sheets/features/table.md) avant d’utiliser une référence structurée.

### Référencer des classeurs chargés dans la même instance

Avec le moteur de base, chargez les deux classeurs dans la même instance Univer et le même environnement de calcul. Exécutez cet exemple après l’initialisation de Sheets. En mode plugin, importez aussi les extensions Facade indiquées sur cette page.

```typescript
const source = univerAPI.createWorkbook({
  id: 'sales-workbook',
  name: 'Sales.xlsx',
  sheetOrder: ['sales-data'],
  sheets: {
    'sales-data': {
      id: 'sales-data',
      name: 'Data',
      rowCount: 100,
      columnCount: 20,
      cellData: {
        0: { 0: { v: 100 } },
        1: { 0: { v: 200 } },
      },
    },
  },
}, { makeCurrent: false })

const report = univerAPI.createWorkbook({ id: 'report-workbook', name: 'Report' })
const resultCell = report.getActiveSheet().getRange('A1')
resultCell.setFormula("=SUM('[Sales.xlsx]Data'!A1:A2)")

const formula = univerAPI.getFormula()
formula.executeCalculation()
await formula.onCalculationResultApplied()
console.log(resultCell.getValue()) // 300
```

`makeCurrent: false` charge la source sans changer le classeur actif. Conservez `source` et `report` pour éviter d’écrire au mauvais endroit après un changement de classeur actif.

La recherche ignore la casse et privilégie le nom complet. À défaut, elle ignore les extensions Excel usuelles telles que `.xlsx` et `.xlsm`. Un nom absent ou ambigu produit `#REF!` : utilisez un nom unique.

### Associer une référence à un ID source stable

Pour associer un nom de formule à un ID de document stable, utilisez l’extension Pro `@univerjs-pro/engine-formula`. Configurez une [licence client](https://docs.univer.ai/fr-FR/server/license.md), remplacez `UniverFormulaEnginePlugin` par `UniverProFormulaEnginePlugin` à l’initialisation et importez la Facade Pro. N’enregistrez pas les deux moteurs. L’import de la Facade seul n’enregistre pas le plugin.

Cet exemple reprend les classeurs précédents dans un environnement configuré avec le moteur Pro :

```typescript
import '@univerjs-pro/engine-formula/facade'

const reference = univerAPI.getFormula().buildReference({
  hostUnitId: report.getId(),
  unit: {
    unitId: source.getId(),
    formulaQualifier: 'Sales Source',
  },
  target: {
    kind: univerAPI.Enum.FormulaReferenceType.SHEET_RANGE,
    sheetName: 'Data',
    range: { startRow: 0, endRow: 1, startColumn: 0, endColumn: 0 },
  },
})

resultCell.setFormula(`=SUM(${reference})`)
```

`hostUnitId` désigne le classeur contenant la formule, `unit.unitId` l’ID stable de la source et `formulaQualifier` son nom public dans la formule. Les coordonnées commencent à zéro et incluent la borne finale.

`buildReference()` renvoie un fragment sans `=` et enregistre l’association. Il ne charge pas la source et ne lance pas le calcul. Les données doivent provenir d’un classeur chargé dans l’environnement de calcul ou d’un fournisseur configuré. Pour une formule écrite à la main ou générée par l’application, créez d’abord l’association :

```typescript
const formula = univerAPI.getFormula()
const bound = formula.upsertExternalReference({
  unitId: report.getId(),
  qualifier: 'Sales Source',
  sourceUnitId: source.getId(),
  sourceUnitType: univerAPI.Enum.UniverInstanceType.UNIVER_SHEET,
})
if (!bound) throw new Error('Could not bind Sales Source')

resultCell.setFormula("=SUM('[Sales Source]Data'!A1:A2)")
```

Répéter la même association est idempotent. `qualifier` ne contient ni crochets ni guillemets. Les entiers positifs comme `1` et `2` sont réservés aux emplacements de liens externes Excel, pas aux ID métier. Conservez les ressources de liens lors d’un import : le texte de la formule seul ne suffit pas.

### Mettre à jour, enregistrer et décharger

Après une modification de la source via la Facade, lancez le calcul et attendez l’application des résultats avant de lire la cible. Le calcul asynchrone n’est pas nécessairement terminé au retour de `setFormula()` ou `setValue()`.

```typescript
const sourceSheet = source.getSheetBySheetId('sales-data')
if (!sourceSheet) throw new Error('Source sheet not found')
sourceSheet.getRange('A1').setValue(150)
formula.executeCalculation()
await formula.onCalculationResultApplied()
console.log(resultCell.getValue()) // 350
```

Utilisez `report.save()` pour enregistrer le snapshot complet avec les ressources d’association. Sauvegarder uniquement les formules perd la correspondance nom/ID. Enregistrez et chargez les données source séparément.

Une fois la source déchargée, une référence ordinaire à un classeur chargé ne peut plus la lire. Les références Pro ne peuvent poursuivre le calcul que si les fournisseurs ou caches disponibles apportent les données. Une association ne contient pas les données et ne garantit pas le calcul hors ligne. Une ancienne valeur affichée ne prouve pas que le résultat est à jour.

Supprimez une association Pro devenue inutile :

```typescript
univerAPI.getFormula().removeExternalReference({
  unitId: report.getId(),
  qualifier: 'Sales Source',
})
```

La suppression ne modifie ni n’efface les formules. Le calcul suivant résout à nouveau le nom : un classeur chargé portant ce nom peut encore être trouvé ; sinon, la référence renvoie `#REF!`. Modifiez ou effacez aussi les formules pour arrêter la référence. Voir les [API de référence FFormula](https://docs.univer.ai/fr-FR/reference/facade/formula.md).

## Références 3D

Une référence 3D couvre des feuilles consécutives du même classeur. Elle est distincte d’une référence entre classeurs.

```text
=SUM(Jan:Mar!B2:C3)
=SUM('Jan':'Mar'!B2)
```

La plage comprend Jan, Mar et toutes les feuilles intermédiaires dans l’ordre du classeur, et non par ordre alphabétique. Vérifiez la plage d’agrégation lorsque vous réordonnez les feuilles.

## Fonctions de formule prises en charge



## API Facade

Pour en savoir plus, consultez la documentation de l’[API Facade FFormula](https://docs.univer.ai/fr-FR/reference/facade/formula.md).

### Importation

> [!INFO: Remarque sur le mode plugin]
> Seul le mode plugin nécessite l’importation manuelle du package Facade. Le mode prédéfini inclut déjà le package
> Facade correspondant ; aucune importation supplémentaire n’est donc nécessaire.

```typescript
import '@univerjs/engine-formula/facade'
import '@univerjs/sheets-formula/facade'
import '@univerjs/sheets-formula-ui/facade'
```

### Afficher la boîte de dialogue de sélection de plages

`@univerjs/sheets-formula-ui/facade` ajoute `univerAPI.showRangeSelectorDialog`. Utilisez cette méthode lorsque votre interface personnalisée doit permettre aux utilisateurs de sélectionner une ou plusieurs plages avec le même sélecteur que celui des panneaux liés aux formules.

```typescript
const workbook = univerAPI.getActiveWorkbook()
const worksheet = workbook?.getActiveSheet()

if (workbook && worksheet) {
  await univerAPI.showRangeSelectorDialog({
    unitId: workbook.getId(),
    subUnitId: worksheet.getSheetId(),
    initialValue: [
      {
        unitId: workbook.getId(),
        sheetName: worksheet.getSheetName(),
        range: worksheet.getRange('A1:B2').getRange(),
      },
    ],
    maxRangeCount: 2,
    supportAcrossSheet: true,
    callback: (ranges, isCancel) => {
      console.log(ranges, isCancel)
    },
  })
}
```

### Exécuter le calcul des formules

```typescript
const formulaEngine = univerAPI.getFormula()
formulaEngine.executeCalculation()
```

### Arrêter le calcul des formules

```typescript
const formulaEngine = univerAPI.getFormula()
formulaEngine.stopCalculation()
```

### Début du calcul des formules

```typescript
// Listening to formula calculation start event
const formulaEngine = univerAPI.getFormula()
formulaEngine.calculationStart((forceCalculate) => {
  console.log(forceCalculate)
})
```

### Progression du calcul des formules

```typescript
// Listening to formula calculation processing event
const formulaEngine = univerAPI.getFormula()
formulaEngine.calculationProcessing((stageInfo) => {
  console.log(stageInfo)
})
```

### Fin du calcul des formules

```typescript
// Listening to formula calculation end event
const formulaEngine = univerAPI.getFormula()
formulaEngine.calculationEnd((functionsExecutedState) => {
  console.log(functionsExecutedState)
})
```

### Application du résultat du calcul des formules

```typescript
// Listening to formula calculation result applied event
const formulaEngine = univerAPI.getFormula()
formulaEngine.calculationResultApplied((result) => {
  console.log(result)
})

// Wait for formula calculation result to be applied
await formulaEngine.onCalculationResultApplied()
```

### Définir le mode de calcul des formules lors de l’initialisation des données

```typescript
const formulaEngine = univerAPI.getFormula()
formulaEngine.setInitialFormulaComputing(CalculationMode.FORCED)
```

Si cette API est appelée après le cycle de vie `Starting`, elle prendra effet lors de la prochaine création d’une feuille Univer Sheet.

Pour qu’elle prenne effet pendant l’initialisation en cours de la feuille Univer Sheet, vous pouvez l’appeler avant le cycle de vie `Ready`, par exemple :

```typescript
univerAPI.addEvent(univerAPI.Event.LifeCycleChanged, ({ stage }) => {
  if (stage === LifecycleStages.Starting) {
    const formulaEngine = univerAPI.getFormula()
    formulaEngine.setInitialFormulaComputing(CalculationMode.FORCED)
  }
})
```

### Calcul itératif

Le calcul itératif est propre au classeur et enregistré dans le champ `calculationSettings` de son instantané. Il est désactivé par défaut : les formules circulaires conservent leur valeur en cache, ou zéro en son absence. Activez-le pour les modèles qui utilisent volontairement des références circulaires.

| Option                 | Valeur par défaut | Comportement                                                                                                                                              |
| ---------------------- | ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `iterativeCalculation` | `false`           | Active le calcul itératif des références circulaires.                                                                                                     |
| `maxIterations`        | `100`             | Entier compris entre 1 et 32767.                                                                                                                          |
| `maxChange`            | `0.001`           | Seuil de convergence fini et positif. Le calcul s’arrête lorsque la variation de chaque résultat numérique du groupe circulaire ne dépasse plus ce seuil. |

Mettez à jour les trois paramètres ensemble via la Facade du classeur. La commande prend en charge l’annulation, le rétablissement et la collaboration ; elle renvoie `false` si le classeur est absent ou non modifiable. Les paramètres invalides sont normalisés aux valeurs par défaut.

```ts
const workbook = univerAPI.getActiveWorkbook()
if (!workbook) throw new Error('No active workbook')

const applied = workbook.setCalculationSettings({
  iterativeCalculation: true,
  maxIterations: 100,
  maxChange: 0.001,
})
if (!applied) throw new Error('Could not update calculation settings')

console.log(workbook.getCalculationSettings())
```

Vous pouvez aussi fournir `calculationSettings` à `createWorkbook()`. Chaque classeur conserve ses propres paramètres. Les options de calcul du ruban Formules proposent les mêmes réglages.

`getCircularReferences()` lit les diagnostics après l’application des résultats, sans lancer de calcul. Ils contiennent les identifiants des feuilles, les coordonnées à partir de zéro, les groupes circulaires, le nombre d’itérations et les informations de convergence disponibles.

```ts
const formula = univerAPI.getFormula()
formula.executeCalculation()
await formula.onCalculationResultApplied()
console.table(workbook.getCircularReferences())
```

### Obtenir le résultat de l’exécution de chaînes de formule

Exécutez un ensemble de formules de façon asynchrone et récupérez les résultats des calculs :

```typescript
const formulaEngine = univerAPI.getFormula()
const formulas = {
  Book1: {
    Sheet1: {
      2: {
        3: [
          // Full formula:
          '=SUM(A1:A10) + SQRT(D7)',

          // Decomposed sub-formulas (each one can be evaluated independently):
          'SUM(A1:A10)', // sub-formula 1
          'SQRT(D7)', // sub-formula 2
          'A1:A10', // range reference
          'D7', // single-cell reference
        ],
      },
      4: {
        5: ['=A2 + B2 + SQRT(C5)', 'A2', 'B2', 'SQRT(C5)'],
      },
    },
  },
}
const result = await formulaEngine.executeFormulas(formulas)
console.log(result)
```

## Formules personnalisées

Univer prend en charge les formules personnalisées. Consultez la section [Formules personnalisées](/blog/custom-formula) pour découvrir comment les implémenter.

## Questions fréquentes

### Les cellules contenant la formule `HYPERLINK` ne permettent pas d’utiliser les liens hypertextes

Vous devez importer le plugin de liens hypertextes pour Univer Sheets. Consultez le module [Liens hypertextes](https://docs.univer.ai/fr-FR/guides/sheets/features/hyper-link.md).

## Sémantique des valeurs de formule

`ISBLANK(A1)` vérifie le contenu de la cellule, pas seulement son résultat affiché. Une cellule effacée reste vide même avec du formatage ; une formule renvoyant `""` ne l’est pas. Le littéral `ISBLANK("")` vaut aussi `FALSE`. `UNIQUE` compare les textes sans tenir compte de la casse et conserve la première graphie. `PROPER` reconnaît les lettres Unicode, notamment latines accentuées, grecques et cyrilliques. `AVERAGE` agrège tout le tableau renvoyé par des fonctions comme `FILTER`.

```text
=ISBLANK("")                         → FALSE
=UNIQUE({"Univer";"univer";"Sheets"})  → {"Univer";"Sheets"}
=PROPER("élise müller")               → Élise Müller
=AVERAGE({3;7})                      → 5
```
