diff --git a/e2e/lechapt-calmon.e2e-spec.ts b/e2e/lechapt-calmon.e2e-spec.ts
index f0b991c6dc52504a8c725ef68306d2a1cc09b229..4dd2d834c83c4d07e3470c727e06950f8e366bb7 100644
--- a/e2e/lechapt-calmon.e2e-spec.ts
+++ b/e2e/lechapt-calmon.e2e-spec.ts
@@ -36,11 +36,11 @@ describe("Lechapt&Calmon - ", () => {
         await browser.sleep(200);
 
         // open Lechapt-Calmon calculator
-        await listPage.clickMenuEntryForCalcType(1);
+        await listPage.clickMenuEntryForCalcType(35);
         await browser.sleep(200);
     }
 
-    it("when material is modified, results should change", async () => {
+    xit("when material is modified, results should change", async () => { // temporairement débranché, cf. jalhyd#334 / nghyd#585
         await setup();
 
         // select last material type
diff --git a/jalhyd_branch b/jalhyd_branch
index 0bd0de8433c44aa322701f9bf4b87ff6d54b525c..9e2dece83480eba1020a4a59afd1ed3e8eb63c31 100644
--- a/jalhyd_branch
+++ b/jalhyd_branch
@@ -1 +1 @@
-334-restructurer-lechapt-et-calmon-pour-de-nouvelles-lois-de-pertes-de-charge
+338-optimiser-l-affichage-des-unites
diff --git a/src/app/formulaire/elements/select/select-field-charttype.ts b/src/app/formulaire/elements/select/select-field-charttype.ts
index b6f35d3f932c8026a4dee3cc6297e81b1b14adf5..223dcaf39252a0cac32f7d3cf7ca9e52150047ba 100644
--- a/src/app/formulaire/elements/select/select-field-charttype.ts
+++ b/src/app/formulaire/elements/select/select-field-charttype.ts
@@ -20,7 +20,7 @@ export class SelectFieldChartType extends SelectField {
     protected populate() {
         for (const v of this._entryValues) {
             const id: string = ChartType[v];
-            this.addEntry(new SelectEntry(id, v));
+            this.addEntry(this.createOrGetEntry(id, v));
         }
     }
 
@@ -50,4 +50,4 @@ export class SelectFieldChartType extends SelectField {
 
         this._label = this.intlService.localizeText("INFO_PARAMFIELD_CHART_TYPE");
     }
-}
\ No newline at end of file
+}
diff --git a/src/app/formulaire/elements/select/select-field-device-loi-debit.ts b/src/app/formulaire/elements/select/select-field-device-loi-debit.ts
index 2c556ff0a54de8e207e0d6e077e53f3f198d9039..07c1f555a52e05e8664209e9ec2ee510ed83ad01 100644
--- a/src/app/formulaire/elements/select/select-field-device-loi-debit.ts
+++ b/src/app/formulaire/elements/select/select-field-device-loi-debit.ts
@@ -47,7 +47,7 @@ export class SelectFieldDeviceLoiDebit extends SelectField {
         const stName = StructureType[stCode];
         if (la[stName] !== undefined) {
             for (const ld of la[stName]) {
-                const e: SelectEntry = new SelectEntry(this._entriesBaseId + LoiDebit[ld], ld);
+                const e: SelectEntry = this.createOrGetEntry(this._entriesBaseId + LoiDebit[ld], ld);
                 this.addEntry(e);
             }
         }
diff --git a/src/app/formulaire/elements/select/select-field-device-structure-type.ts b/src/app/formulaire/elements/select/select-field-device-structure-type.ts
index aee9297606d7f0d756521e19b4d6c36ceecd8e85..7b188d114de529c84e9c403274e689986f9d408a 100644
--- a/src/app/formulaire/elements/select/select-field-device-structure-type.ts
+++ b/src/app/formulaire/elements/select/select-field-device-structure-type.ts
@@ -24,7 +24,7 @@ export class SelectFieldDeviceStructureType extends SelectField {
     protected populate() {
         // possible values depend on CalcType
         for (const st in (this.nub as ParallelStructure).getLoisAdmissibles()) {
-            const e: SelectEntry = new SelectEntry(this._entriesBaseId + st, StructureType[st]);
+            const e: SelectEntry = this.createOrGetEntry(this._entriesBaseId + st, StructureType[st]);
             this.addEntry(e);
         }
     }
diff --git a/src/app/formulaire/elements/select/select-field-downstream-basin.ts b/src/app/formulaire/elements/select/select-field-downstream-basin.ts
index dd39ce85724ea830962b6abfa61d7564db7c72a5..9c34a16e8c8b147328ea5cd0430b0c514b485782 100644
--- a/src/app/formulaire/elements/select/select-field-downstream-basin.ts
+++ b/src/app/formulaire/elements/select/select-field-downstream-basin.ts
@@ -19,13 +19,13 @@ export class SelectFieldDownstreamBasin extends SelectField {
         for (const b of preBarrageD.bassins) {
             const pos = b.findPositionInParent();
             if (posUb === undefined || pos > posUb) {
-                const e = new SelectEntry(this._entriesBaseId + b.uid, b.uid);
+                const e = this.createOrGetEntry(this._entriesBaseId + b.uid, b.uid);
                 e.intlInfo = b.description;
                 this.addEntry(e);
             }
         }
         // river downstream
-        const e = new SelectEntry(this._entriesBaseId + "none", undefined);
+        const e = this.createOrGetEntry(this._entriesBaseId + "none", undefined);
         e.intlInfo = "INFO_LIB_AVAL";
         this.addEntry(e);
     }
diff --git a/src/app/formulaire/elements/select/select-field-nub-prop.ts b/src/app/formulaire/elements/select/select-field-nub-prop.ts
index df62610a8a9c288d571618c59d954eec395d7546..4fa8c4e862ff14dbbbde8b26d2a31ff49fcc50ac 100644
--- a/src/app/formulaire/elements/select/select-field-nub-prop.ts
+++ b/src/app/formulaire/elements/select/select-field-nub-prop.ts
@@ -31,7 +31,7 @@ export class SelectFieldNubProperty extends SelectField {
         if (enumClass !== undefined) {
             // add one select entry per enum entry, in the enum order
             for (let j = 0; j < Object.keys(enumClass).length / 2; j++) {
-                this.addEntry(new SelectEntry(this._entriesBaseId + j, j));
+                this.addEntry(this.createOrGetEntry(this._entriesBaseId + j, j));
             }
         }
     }
diff --git a/src/app/formulaire/elements/select/select-field-remous-target.ts b/src/app/formulaire/elements/select/select-field-remous-target.ts
index 20b40cc473bbe7395462953dd359638a1f9e217a..f6eb90e6ff1917981c2885e5afd618e235a357e6 100644
--- a/src/app/formulaire/elements/select/select-field-remous-target.ts
+++ b/src/app/formulaire/elements/select/select-field-remous-target.ts
@@ -19,9 +19,9 @@ export class SelectFieldRemousTarget extends SelectField {
 
     protected populate() {
         // driven by string[], not enum (easier for variable names)
-        this.addEntry(new SelectEntry(this._entriesBaseId + "none", ""));
+        this.addEntry(this.createOrGetEntry(this._entriesBaseId + "none", ""));
         for (const at of CourbeRemous.availableTargets) {
-            const e: SelectEntry = new SelectEntry(this._entriesBaseId + at, at);
+            const e: SelectEntry = this.createOrGetEntry(this._entriesBaseId + at, at);
             this.addEntry(e);
         }
     }
diff --git a/src/app/formulaire/elements/select/select-field-searched-param.ts b/src/app/formulaire/elements/select/select-field-searched-param.ts
index 1342fb643e31b378ea799dc166f3277714d9b123..339acbfe5702e623c3cc8041b2860ad7ef0fe3f6 100644
--- a/src/app/formulaire/elements/select/select-field-searched-param.ts
+++ b/src/app/formulaire/elements/select/select-field-searched-param.ts
@@ -28,7 +28,7 @@ export class SelectFieldSearchedParam extends SelectField {
                 const calc = fs.getFormulaireFromId(p.originNub.uid).calculatorName;
                 const varName = fs.expandVariableName(p.originNub.calcType, p.symbol);
                 const label = `${p.symbol} - ${varName} (${calc})`;
-                this.addEntry(new SelectEntry(this._entriesBaseId + p.getParentComputeNode(false).uid + "_" + p.symbol, p, decodeHtml(label)));
+                this.addEntry(this.createOrGetEntry(this._entriesBaseId + p.getParentComputeNode(false).uid + "_" + p.symbol, p, decodeHtml(label)));
             }
         }
     }
diff --git a/src/app/formulaire/elements/select/select-field-solver-targeted-result.ts b/src/app/formulaire/elements/select/select-field-solver-targeted-result.ts
index a547bde3c6e1036f697281d8449d6b0df74b2fcf..36094a8dddfc808aea5ce6c8031de91bed17c1c9 100644
--- a/src/app/formulaire/elements/select/select-field-solver-targeted-result.ts
+++ b/src/app/formulaire/elements/select/select-field-solver-targeted-result.ts
@@ -24,12 +24,12 @@ export class SelectFieldSolverTargetedResult extends SelectField {
         // 1. calculated param
         const ntc = (this.nub as Solveur).nubToCalculate;
         if (ntc?.calculatedParam !== undefined) { // some nubs have no calculatedParam, for ex. SectionParam
-            this.addEntry(new SelectEntry(this._entriesBaseId + "none", ""));
+            this.addEntry(this.createOrGetEntry(this._entriesBaseId + "none", ""));
         }
         // 2. extra results
         if (ntc?.resultsFamilies !== undefined) {
             for (const er of Object.keys(ntc.resultsFamilies)) {
-                const e: SelectEntry = new SelectEntry(this._entriesBaseId + er, er);
+                const e: SelectEntry = this.createOrGetEntry(this._entriesBaseId + er, er);
                 this.addEntry(e);
             }
         }
diff --git a/src/app/formulaire/elements/select/select-field-solveur-target.ts b/src/app/formulaire/elements/select/select-field-solveur-target.ts
index aecd238b8d87d8836879bedf48ea707e21894e40..b98546e221fc7bf13c782ca43440e24df9f34320 100644
--- a/src/app/formulaire/elements/select/select-field-solveur-target.ts
+++ b/src/app/formulaire/elements/select/select-field-solveur-target.ts
@@ -33,7 +33,7 @@ export class SelectFieldSolverTarget extends SelectField {
                     const varName = fs.expandVariableName(cn.calcType, cn.calculatedParam.symbol);
                     label += ` / ${varName} (${cn.calculatedParam.symbol})`;
                 }
-                this.addEntry(new SelectEntry(this._entriesBaseId + cn.uid, cn.uid, decodeHtml(label)));
+                this.addEntry(this.createOrGetEntry(this._entriesBaseId + cn.uid, cn.uid, decodeHtml(label)));
             } else {
                 // silent fail, this Solveur nub was probably loaded before all the candidate nubs are done loading
             }
diff --git a/src/app/formulaire/elements/select/select-field-species-list.ts b/src/app/formulaire/elements/select/select-field-species-list.ts
index 9401148c35ace8289cb150c5b2c8691f9dfc681e..7b94345aa073bbd77580775e01dfc5504d78fb64 100644
--- a/src/app/formulaire/elements/select/select-field-species-list.ts
+++ b/src/app/formulaire/elements/select/select-field-species-list.ts
@@ -24,14 +24,14 @@ export class SelectFieldSpeciesList extends SelectField {
         const especeNubs = Session.getInstance().getAllNubs().filter((element) => element.calcType === CalculatorType.Espece);
         for (const en of especeNubs) {
             const form = ServiceFactory.formulaireService.getFormulaireFromNubId(en.uid);
-            const e = new SelectEntry(this._entriesBaseId + en.uid, en.uid);
+            const e = this.createOrGetEntry(this._entriesBaseId + en.uid, en.uid);
             e.intlInfo = { "isnub": true, "code": "INFO_VERIFICATEUR_CUSTOM_SPECIES", "id": en.uid };
             this.addEntry(e);
         }
         // add all FishSpecies
         for (let j = 1; j < Object.keys(FishSpecies).length / 2; j++) { // exclude "0" (SPECIES_CUSTOM)
             const spgId = FishSpecies[j].substring(FishSpecies[j].lastIndexOf("_") + 1);
-            const e = new SelectEntry(this._entriesBaseId + spgId, FishSpecies[j]);
+            const e = this.createOrGetEntry(this._entriesBaseId + spgId, FishSpecies[j]);
             e.intlInfo = { "isnub": false, "code": FishSpecies[j] }
             this.addEntry(e);
         }
diff --git a/src/app/formulaire/elements/select/select-field-target-pass.ts b/src/app/formulaire/elements/select/select-field-target-pass.ts
index 10cd639a1b125fec2a7af633bfeb4cbde056f07d..6383c02ffc159a14afa7f6a11dce014769c48af9 100644
--- a/src/app/formulaire/elements/select/select-field-target-pass.ts
+++ b/src/app/formulaire/elements/select/select-field-target-pass.ts
@@ -33,7 +33,7 @@ export class SelectFieldTargetPass extends SelectField {
             const nub = fs.getFormulaireFromId(cn.uid);
             if (nub) {
                 const label = nub.calculatorName + " (" + fs.getLocalisedTitleFromCalculatorType(nub.calculatorType) + ")";
-                this.addEntry(new SelectEntry(this._entriesBaseId + cn.uid, cn.uid, decodeHtml(label)));
+                this.addEntry(this.createOrGetEntry(this._entriesBaseId + cn.uid, cn.uid, decodeHtml(label)));
             } else {
                 // silent fail, this Verificateur nub was probably loaded before all the candidate nubs are done loading
             }
diff --git a/src/app/formulaire/elements/select/select-field-upstream-basin.ts b/src/app/formulaire/elements/select/select-field-upstream-basin.ts
index d240d097c39d795647ab3cda6a4f0a78cac18b14..cc70f8a53860ce6c5d140c695c4121fd37d635e6 100644
--- a/src/app/formulaire/elements/select/select-field-upstream-basin.ts
+++ b/src/app/formulaire/elements/select/select-field-upstream-basin.ts
@@ -17,7 +17,7 @@ export class SelectFieldUpstreamBasin extends SelectField {
         const posDb = pbWallU.bassinAval?.findPositionInParent();
 
         // river upstream
-        const e = new SelectEntry(this._entriesBaseId + "none", undefined);
+        const e = this.createOrGetEntry(this._entriesBaseId + "none", undefined);
         e.intlInfo = "INFO_LIB_AMONT";
         this.addEntry(e);
 
@@ -25,7 +25,7 @@ export class SelectFieldUpstreamBasin extends SelectField {
         for (const b of preBarrageU.bassins) {
             const pos = b.findPositionInParent();
             if (posDb === undefined || pos < posDb) {
-                const e = new SelectEntry(this._entriesBaseId + b.uid, b.uid);
+                const e = this.createOrGetEntry(this._entriesBaseId + b.uid, b.uid);
                 e.intlInfo = b.description;
                 this.addEntry(e);
             }
diff --git a/src/app/formulaire/elements/select/select-field.ts b/src/app/formulaire/elements/select/select-field.ts
index 5e490c754d4246759a7ffd9e820b50be973188cd..86a9880048beb87da66730ef9ec3b69a45c770b3 100644
--- a/src/app/formulaire/elements/select/select-field.ts
+++ b/src/app/formulaire/elements/select/select-field.ts
@@ -36,6 +36,11 @@ export abstract class SelectField extends Field {
      */
     protected _messageWhenEmpty: string;
 
+    /**
+     * map id <-> select entry
+     */
+    protected _entryMap: { [key: string]: SelectEntry } = {};
+
     constructor(parent: FormulaireNode) {
         super(parent);
         this.clearEntries();
@@ -210,6 +215,15 @@ export abstract class SelectField extends Field {
         this._entries.push(e);
     }
 
+    protected createOrGetEntry(id: string, val: any, lbl?: string): SelectEntry {
+        let res: SelectEntry = this._entryMap[id];
+        if (res === undefined) {
+            res = new SelectEntry(id, val, lbl);
+            this._entryMap[id] = res;
+        }
+        return res;
+    }
+
     public getEntryFromValue(val: any): SelectEntry {
         for (const se of this._entries) {
             if (se.value === val) {
diff --git a/src/app/services/formulaire.service.ts b/src/app/services/formulaire.service.ts
index e54805c7d5ed9279f1cbed3150cdfe8f6ec5d65c..880741539bbb62d7a033a5dedc60ad76cc84eeaf 100644
--- a/src/app/services/formulaire.service.ts
+++ b/src/app/services/formulaire.service.ts
@@ -58,6 +58,7 @@ import { FormulaireEspece } from "../formulaire/definition/form-espece";
 import { FormulairePrebarrage } from "../formulaire/definition/form-prebarrage";
 import { ServiceFactory } from "./service-factory";
 import { FormulairePressureLoss } from "app/formulaire/definition/form-pressureloss";
+import { getNubResultUnit } from "jalhyd";
 
 @Injectable()
 export class FormulaireService extends Observable {
@@ -194,7 +195,7 @@ export class FormulaireService extends Observable {
      * Returns variable name and unit from symbol
      * @param calcType
      * @param symbol
-     * @param forceUnit if given, will be used as nuit
+     * @param forceUnit if given, will be used as unit
      */
     public expandVariableNameAndUnit(calcType: CalculatorType, symbol: string, forceUnit?: string): string {
         let s = this.expandVariableName(calcType, symbol);
@@ -217,16 +218,8 @@ export class FormulaireService extends Observable {
         if (forceUnit) {
             unit = forceUnit;
         } else {
-            // create dummy Nub from CalcType just to get results units
-            let dummyNub: Nub;
-            try {
-                dummyNub = Session.getInstance().createNub(new Props({ "calcType": calcType }));
-            } catch (e) {
-                // silent fail
-            }
-            if (dummyNub?.resultsUnits && dummyNub.resultsUnits[symbol]) {
-                unit = dummyNub.resultsUnits[symbol];
-            } else {
+            unit = getNubResultUnit(calcType, symbol);
+            if (unit === undefined) {
                 // last chance: if unit cannot be read in model, use translation files
                 const unitKey = "UNIT_" + symbolBase;
                 if (langCache && langCache[unitKey] !== undefined) {