diff --git a/app/comp/res_compat.py b/app/comp/res_compat.py
index 5ac18ff4e..d48c727de 100644
--- a/app/comp/res_compat.py
+++ b/app/comp/res_compat.py
@@ -54,6 +54,7 @@ class NotesTableCompat(ResultatsSemestre):
         self.ue_rangs_by_group = {}  # { ue_id : {group_id : (Series, Series)}}
         self.expr_diagnostics = ""
         self.parcours = self.formsemestre.formation.get_parcours()
+        self._modimpls_dict_by_ue = {}  # local cache
 
     def get_inscrits(self, include_demdef=True, order_by=False) -> list[Identite]:
         """Liste des étudiants inscrits
@@ -145,6 +146,10 @@ class NotesTableCompat(ResultatsSemestre):
         """Liste des modules pour une UE (ou toutes si ue_id==None),
         triés par numéros (selon le type de formation)
         """
+        # cached ?
+        modimpls_dict = self._modimpls_dict_by_ue.get(ue_id)
+        if modimpls_dict:
+            return modimpls_dict
         modimpls_dict = []
         for modimpl in self.formsemestre.modimpls_sorted:
             if (ue_id is None) or (modimpl.module.ue.id == ue_id):
@@ -152,6 +157,7 @@ class NotesTableCompat(ResultatsSemestre):
                 # compat ScoDoc < 9.2: ajoute matières
                 d["mat"] = modimpl.module.matiere.to_dict()
                 modimpls_dict.append(d)
+        self._modimpls_dict_by_ue[ue_id] = modimpls_dict
         return modimpls_dict
 
     def compute_rangs(self):
diff --git a/app/models/modules.py b/app/models/modules.py
index 5ab4466bc..793c75a67 100644
--- a/app/models/modules.py
+++ b/app/models/modules.py
@@ -175,6 +175,12 @@ class Module(db.Model):
         # Liste seulement les coefs définis:
         return [(c.ue, c.coef) for c in self.get_ue_coefs_sorted()]
 
+    def get_codes_apogee(self) -> set[str]:
+        """Les codes Apogée (codés en base comme "VRT1,VRT2")"""
+        if self.code_apogee:
+            return {x.strip() for x in self.code_apogee.split(",")}
+        return set()
+
 
 class ModuleUECoef(db.Model):
     """Coefficients des modules vers les UE (APC, BUT)
diff --git a/app/models/ues.py b/app/models/ues.py
index 52cd3788c..6d4efabc6 100644
--- a/app/models/ues.py
+++ b/app/models/ues.py
@@ -120,3 +120,9 @@ class UniteEns(db.Model):
             (Module.module_type != scu.ModuleType.SAE),
             (Module.module_type != scu.ModuleType.RESSOURCE),
         ).all()
+
+    def get_codes_apogee(self) -> set[str]:
+        """Les codes Apogée (codés en base comme "VRT1,VRT2")"""
+        if self.code_apogee:
+            return {x.strip() for x in self.code_apogee.split(",")}
+        return set()
diff --git a/app/scodoc/sco_apogee_csv.py b/app/scodoc/sco_apogee_csv.py
index 7fe9501df..10f5e4b51 100644
--- a/app/scodoc/sco_apogee_csv.py
+++ b/app/scodoc/sco_apogee_csv.py
@@ -958,6 +958,20 @@ class ApoData(object):
         """
         codes_by_sem = {}
         for sem in self.sems_etape:
+            formsemestre = FormSemestre.query.get_or_404(sem["formsemestre_id"])
+            # L'ensemble des codes apo associés aux modules:
+            codes_modules = set().union(
+                *[
+                    modimpl.module.get_codes_apogee()
+                    for modimpl in formsemestre.modimpls
+                ]
+            )
+            codes_ues = set().union(
+                *[
+                    ue.get_codes_apogee()
+                    for ue in formsemestre.query_ues(with_sport=True)
+                ]
+            )
             s = set()
             codes_by_sem[sem["formsemestre_id"]] = s
             for col_id in self.col_ids[4:]:
@@ -971,23 +985,12 @@ class ApoData(object):
                     s.add(code)
                     continue
                 # associé à une UE:
-                formsemestre = FormSemestre.query.get_or_404(sem["formsemestre_id"])
-                nt: NotesTableCompat = res_sem.load_formsemestre_results(formsemestre)
-                for ue in nt.get_ues_stat_dict():
-                    if ue["code_apogee"]:
-                        codes = {x.strip() for x in ue["code_apogee"].split(",")}
-                        if code in codes:
-                            s.add(code)
-                            continue
+                if code in codes_ues:
+                    s.add(code)
+                    continue
                 # associé à un module:
-                modimpls = nt.get_modimpls_dict()
-                for modimpl in modimpls:
-                    module = modimpl["module"]
-                    if module["code_apogee"]:
-                        codes = {x.strip() for x in module["code_apogee"].split(",")}
-                        if code in codes:
-                            s.add(code)
-                            continue
+                if code in codes_modules:
+                    s.add(code)
         # log('codes_by_sem=%s' % pprint.pformat(codes_by_sem))
         return codes_by_sem