diff --git a/incomp_apogee/Incomp Info impair.xml.xlsx b/OLD_incomp_apogee/Incomp Info impair.xml.xlsx
similarity index 100%
rename from incomp_apogee/Incomp Info impair.xml.xlsx
rename to OLD_incomp_apogee/Incomp Info impair.xml.xlsx
diff --git a/incomp_apogee/Incomp math impair.xml.xlsx b/OLD_incomp_apogee/Incomp math impair.xml.xlsx
similarity index 100%
rename from incomp_apogee/Incomp math impair.xml.xlsx
rename to OLD_incomp_apogee/Incomp math impair.xml.xlsx
diff --git a/OLD_incomp_apogee/Incomp matiere info automne.xml.xlsx b/OLD_incomp_apogee/Incomp matiere info automne.xml.xlsx
new file mode 100644
index 0000000000000000000000000000000000000000..4601fa7fec4b62ef040b69dc9892b07f66412dd1
Binary files /dev/null and b/OLD_incomp_apogee/Incomp matiere info automne.xml.xlsx differ
diff --git a/groupes_sillons/VET_JC_CLEAN.xlsx b/OLD_incomp_apogee/VET_JC_CLEAN.xlsx
similarity index 100%
rename from groupes_sillons/VET_JC_CLEAN.xlsx
rename to OLD_incomp_apogee/VET_JC_CLEAN.xlsx
diff --git a/OLD_incomp_apogee/VET_info.xlsx b/OLD_incomp_apogee/VET_info.xlsx
new file mode 100644
index 0000000000000000000000000000000000000000..4eafd59449d76df79e39546181df601a2784c901
Binary files /dev/null and b/OLD_incomp_apogee/VET_info.xlsx differ
diff --git a/incomp_apogee/incomp LV.xml.xlsx b/OLD_incomp_apogee/incomp LV.xml.xlsx
similarity index 100%
rename from incomp_apogee/incomp LV.xml.xlsx
rename to OLD_incomp_apogee/incomp LV.xml.xlsx
diff --git a/incomp_apogee/incomp chimie impair.xlsx b/OLD_incomp_apogee/incomp chimie impair.xlsx
similarity index 100%
rename from incomp_apogee/incomp chimie impair.xlsx
rename to OLD_incomp_apogee/incomp chimie impair.xlsx
diff --git a/groupes_sillons/VET_Info_semP25.xlsx b/groupes_sillons/VET_Info_semP25.xlsx
new file mode 100644
index 0000000000000000000000000000000000000000..98b4f6638036a699c4ffd0292a4e2eba94c12080
Binary files /dev/null and b/groupes_sillons/VET_Info_semP25.xlsx differ
diff --git a/groupes_sillons/VET_info.xlsx b/groupes_sillons/VET_info.xlsx
deleted file mode 100644
index 92cdb2dc2d47a5435c74310c55f640b097287d47..0000000000000000000000000000000000000000
Binary files a/groupes_sillons/VET_info.xlsx and /dev/null differ
diff --git a/incomp_apogee/Incomp Info info.xlsx b/incomp_apogee/Incomp Info info.xlsx
new file mode 100644
index 0000000000000000000000000000000000000000..a5897b204232f504d5b70b9a8003b577d5453a2a
Binary files /dev/null and b/incomp_apogee/Incomp Info info.xlsx differ
diff --git a/incomp_apogee/Incomp info.xlsx b/incomp_apogee/Incomp info.xlsx
new file mode 100644
index 0000000000000000000000000000000000000000..1ebd6d4a000d51f50b5ad8767099ab5d8d998a3f
Binary files /dev/null and b/incomp_apogee/Incomp info.xlsx differ
diff --git a/incompatibilites_manquantes.xlsx b/incompatibilites_manquantes.xlsx
new file mode 100644
index 0000000000000000000000000000000000000000..514877bc5592966cd9e846f8a29755437308fecd
Binary files /dev/null and b/incompatibilites_manquantes.xlsx differ
diff --git a/main.py b/main.py
index 45d6b2d729a5be79b72f57fce03d1ed9b2c60f91..3445e7874cdeb7707fa0d54d017993a5738fac21 100644
--- a/main.py
+++ b/main.py
@@ -2,7 +2,7 @@ import pandas as pd
 import os
 from itertools import combinations
 
-file_groupes_sillons = 'groupes_sillons/VET_Info.xlsx'
+file_groupes_sillons = 'groupes_sillons/VET_Info_semP25.xlsx'
 directory_incomp_path = 'incomp_apogee'
 files_incomp_apogee = [os.path.join(directory_incomp_path, file) for file in os.listdir(directory_incomp_path) if file.endswith('.xlsx')]
 
@@ -11,11 +11,11 @@ df['Sillon'] = df['Sillon'].ffill()
 df['CODE APOGEE'] = df['CODE APOGEE'].ffill()
 df['INTITULE MATIERE'] = df['INTITULE MATIERE'].ffill()
 
-sillon_to_groups = {}
-groupe_to_sillons = {}
-groupe_to_ue = {}
-groupe_to_intitule = {}
-groupe_to_coll = {}
+sillon_to_groups_with_ue = {}
+groupe_with_ue_to_sillons = {}
+groupe_with_ue_to_ue = {}
+groupe_with_ue_to_intitule = {}
+groupe_with_ue_to_coll = {}
 all_incompatibilities_apogee = set()
 all_incompatibilities_theory = set()
 
@@ -27,7 +27,7 @@ def dic_creator():
     for index, row in df.iterrows():
         group_name = row['Groupe'].strip().upper()
         sillon = row['Sillon']
-        ue = row['CODE APOGEE']
+        ue = row['CODE APOGEE'].strip().upper()
         intitule = row['INTITULE MATIERE']
 
         # si la cellule sillon est vide (cas fusion), on utilisera la dernière valeur connue
@@ -40,31 +40,33 @@ def dic_creator():
         if intitule:
             current_intitule = intitule
 
+        group_name_with_ue = current_ue + '-' + group_name
         sillons_list = str(current_sillon).split('+')
 
         for sillon in sillons_list:
             sillon = sillon.strip().upper()
-            if sillon and any(sillon == f"{i}{letter}" for i in range(1, 9) for letter in ['', 'A', 'B', 'a', 'b']):
-                if sillon in sillon_to_groups:
-                    sillon_to_groups[sillon].append(group_name)
+            if sillon and any(sillon == f"{i}{letter}" for i in range(1, 9) for letter in ['', 'A', 'B']):
+                if sillon in sillon_to_groups_with_ue:
+                    sillon_to_groups_with_ue[sillon].append(group_name_with_ue)
                 else:
-                    sillon_to_groups[sillon] = [group_name]
+                    sillon_to_groups_with_ue[sillon] = [group_name_with_ue]
             else:
-                print(f"Sillon pas reconnu pour {group_name}")
-        groupe_to_sillons[group_name] = [s.strip().upper() for s in sillons_list]
-        groupe_to_ue[group_name] = current_ue
-        groupe_to_intitule[group_name] = current_intitule
+                print(f"Sillon pas reconnu pour {group_name_with_ue}")
+        groupe_with_ue_to_sillons[group_name_with_ue] = [s.strip().upper() for s in sillons_list]
+        groupe_with_ue_to_ue[group_name_with_ue] = current_ue
+        groupe_with_ue_to_intitule[group_name_with_ue] = current_intitule
 
 def print_infos():
     print("--- Liste des groupes pour chaque sillon :")
-    for sillon, groupes in sillon_to_groups.items():
+    for sillon, groupes in sillon_to_groups_with_ue.items():
         print(f"Sillon {sillon}: {groupes}")
     print("\n--- Sillons pour chaque groupe :")
-    for groupe, sillons in groupe_to_sillons.items():
+    for groupe, sillons in groupe_with_ue_to_sillons.items():
         print(f"Groupe {groupe}: {sillons}")
     print("\n--- UE pour chaque groupe :")
-    for groupe, cours in groupe_to_ue.items():
-        print(f"Groupe {groupe}: {cours}, {groupe_to_intitule[groupe]}")
+    for groupe, cours in groupe_with_ue_to_ue.items():
+        print(f"Groupe {groupe}: {cours}, {groupe_with_ue_to_intitule[groupe]}")
+    print(f"Nombre de groupes  : {len(groupe_with_ue_to_ue)}")
 
 # fonction pour vérifier si deux groupes donnés sont incompatibles (même sillon
 # en tenant compte des demi-sillons)
@@ -87,38 +89,47 @@ def check_incompatibility(group1, group2, sillon_dict):
 # est affiché.
 def verifier_apogee_vs_theory():
     for file in files_incomp_apogee:
-        df = pd.read_excel(file, engine='openpyxl')
-        for index, row in df.iterrows():
-            group1 = row['COD_EXT_GPE'].upper()
-            group2 = row['COD_EXT_GPE1'].upper()
-            groupe_to_coll[group1] = row['COD_EXT_COL'].upper()
-            groupe_to_coll[group2] = row['COD_EXT_COL1'].upper()
-
-            # on vérifie que les 2 groupes de l'incomp appartiennent à la VET
-            if (group1 in groupe_to_sillons and groupe_to_sillons[group1]
-                    and group2 in groupe_to_sillons and groupe_to_sillons[group2]):
-                # normalisation de l'ordre pour garantir la cohérence
-                group_pair = tuple(sorted((group1, group2)))
-
-                incompatibility, g1_sillons, g2_sillons = check_incompatibility(group1, group2, sillon_to_groups)
-                if incompatibility:
-                    all_incompatibilities_apogee.add(group_pair)
-                else:
-                    print(f"Erreur trouvée: {group1} ({groupe_to_ue[group1]}, {groupe_to_intitule[group1]}) et "
-                          f"{group2} ({groupe_to_ue[group2]}, {groupe_to_intitule[group2]}) "
-                          f"ne sont pas sur le même sillon mais déclarés incompatibles dans Apogee. "
-                          f"Sillon(s) de {group1}: {g1_sillons}, Sillon(s) de {group2}: {g2_sillons}")
+        sheets = pd.read_excel(file, sheet_name=None, engine='openpyxl')  # Charger tous les onglets
+        for sheet_name, df in sheets.items():  # Parcourir chaque onglet
+            print(f"Traitement de l'onglet : {sheet_name}")
+            for index, row in df.iterrows():
+                group = row['COD_EXT_GPE'].upper()
+                group1 = row['COD_EXT_GPE1'].upper()
+                ue = row['COD_EXT_COL'].upper()[:8]
+                ue1 = row['COD_EXT_COL1'].upper()[:8]
+
+                group_with_ue = ue + '-' + group
+                group1_with_ue1 = ue1 + '-' + group1
+
+                groupe_with_ue_to_coll[group_with_ue] = row['COD_EXT_COL'].upper()
+                groupe_with_ue_to_coll[group1_with_ue1] = row['COD_EXT_COL1'].upper()
+
+                # on vérifie que les 2 groupes de l'incomp appartiennent à la VET
+                if (group_with_ue in groupe_with_ue_to_sillons and groupe_with_ue_to_sillons[group_with_ue]
+                        and group1_with_ue1 in groupe_with_ue_to_sillons and groupe_with_ue_to_sillons[group1_with_ue1]):
+                    # normalisation de l'ordre pour garantir la cohérence
+                    group_pair = tuple(sorted((group_with_ue, group1_with_ue1)))
+
+                    incompatibility, g_sillons, g1_sillons = check_incompatibility(group_with_ue, group1_with_ue1,
+                                                                                sillon_to_groups_with_ue)
+                    if incompatibility:
+                        all_incompatibilities_apogee.add(group_pair)
+                    else:
+                        print(f"Erreur trouvée: {group} ({groupe_with_ue_to_ue[group_with_ue]}, {groupe_with_ue_to_intitule[group_with_ue]}) et "
+                              f"{group1} ({groupe_with_ue_to_ue[group1_with_ue1]}, {groupe_with_ue_to_intitule[group1_with_ue1]}) "
+                            f"ne sont pas sur le même sillon mais déclarés incompatibles dans Apogee. "
+                            f"Sillon(s) de {group}: {g_sillons}, Sillon(s) de {group1}: {g1_sillons}")
 
 # fonction qui génére toutes les incomp d'après la théorie de l'association groupes/sillons
 def incomp_theory_creator():
-    for sillon, groups in sillon_to_groups.items():
+    for sillon, groups in sillon_to_groups_with_ue.items():
         # ajout de toutes les paires du même sillon
         for group1, group2 in combinations(groups, 2):
-            if (groupe_to_ue[group1] != groupe_to_ue[group2]): # les groupes doivent appartenir à des UE différentes
+            if (groupe_with_ue_to_ue[group1] != groupe_with_ue_to_ue[group2]): # les groupes doivent appartenir à des UE différentes
                 all_incompatibilities_theory.add(tuple(sorted((group1, group2))))
         # ajout des paires entre demi-sillons A et non-A ou B et non-B
         base_sillon = ''.join(filter(str.isdigit, sillon))
-        for other_sillon, other_groups in sillon_to_groups.items():
+        for other_sillon, other_groups in sillon_to_groups_with_ue.items():
             if other_sillon != sillon and ''.join(filter(str.isdigit, other_sillon)) == base_sillon:
                 if not ((sillon.endswith('A') and other_sillon.endswith('B')) or (sillon.endswith('B') and other_sillon.endswith('A'))):
                     for group1 in groups:
@@ -132,30 +143,59 @@ def verifier_theory_vs_apogee():
     if missing_incompatibilities:
         print("Oublis détectés dans les incompatibilités:")
         for group1, group2 in missing_incompatibilities:
-            print(f"{group1} ({groupe_to_ue[group1]}, {groupe_to_intitule[group1]}) et "
-                  f"{group2} ({groupe_to_ue[group2]}, {groupe_to_intitule[group2]}) "
+            print(f"{group1.split('-')[0]} ({groupe_with_ue_to_ue[group1]}, {groupe_with_ue_to_intitule[group1]}) et "
+                  f"{group2.split('-')[0]} ({groupe_with_ue_to_ue[group2]}, {groupe_with_ue_to_intitule[group2]}) "
                   f"devraient être incompatibles mais ne sont pas listés dans Apogée.")
     else:
         print("Aucun oubli détecté.")
 
 
+# vérifie que tous les groupes présents comme clés dans le dictionnaire `groupe_to_ue`
+# apparaissent dans au moins une paire de `all_incompatibilities_apogee`.
+def verify_group_names_are_in_apogee():
+    missing_groups = set()
+
+    for groupe in groupe_with_ue_to_ue.keys():
+        # vérifie si le groupe est dans au moins une paire d'incompatibilités
+        if not any(groupe in pair for pair in all_incompatibilities_apogee):
+            missing_groups.add(groupe)
+    if missing_groups:
+        print(f"Les groupes suivants ne sont pas référencés dans Apogée : {missing_groups}")
+    else:
+        print("Tous les groupes souhaités sont référencés dans Apogée ")
+
+
 def export_missing_incomp():
     missing_incompatibilities = all_incompatibilities_theory - all_incompatibilities_apogee
     if missing_incompatibilities:
         data = []
         for group1, group2 in missing_incompatibilities:
+            # Vérification de la présence des collections
+            coll1 = groupe_with_ue_to_coll.get(group1, "???")
+            coll2 = groupe_with_ue_to_coll.get(group2, "???")
+
+            # Afficher un message si une collection est inconnue
+            if coll1 == "???":
+                print(f"Attention, collection inconnue pour le groupe {group1}")
+            if coll2 == "???":
+                print(f"Attention, collection inconnue pour le groupe {group2}")
+
             data.append([
-                group1, groupe_to_ue[group1], groupe_to_intitule[group1], groupe_to_coll[group1],
-                group2, groupe_to_ue[group2], groupe_to_intitule[group2], groupe_to_coll[group2]
+                group1.split('-')[0],
+                groupe_with_ue_to_ue[group1],
+                groupe_with_ue_to_intitule[group1],
+                coll1,
+                group2.split('-')[0],
+                groupe_with_ue_to_ue[group2],
+                groupe_with_ue_to_intitule[group2],
+                coll2
             ])
 
-        # Creating a DataFrame
         df = pd.DataFrame(data, columns=[
             'Groupe 1', 'UE 1', 'Intitule 1', 'Coll 1',
             'Groupe 2', 'UE 2', 'Intitule 2', 'Coll 2'
         ])
 
-        # Writing to an Excel file
         df.to_excel('incompatibilites_manquantes.xlsx', index=False)
         print("Oublis détectés dans les incompatibilités et écrits dans 'incompatibilites_manquantes.xlsx'.")
     else:
@@ -168,5 +208,9 @@ print("--- Apogee vs. theory:")
 verifier_apogee_vs_theory()
 print("--- Theory vs. apogee:")
 incomp_theory_creator()
-verifier_theory_vs_apogee()
-#export_missing_incomp()
+verify_group_names_are_in_apogee()
+print(f"Theory nb incomp : {len(all_incompatibilities_theory)}")
+print(f"Apogee nb incomp : {len(all_incompatibilities_apogee)}")
+#verifier_theory_vs_apogee()
+export_missing_incomp()
+
diff --git a/requirements.txt b/requirements.txt
new file mode 100644
index 0000000000000000000000000000000000000000..ccdd6eda7737cb4fd63f32bb97841388975685f0
--- /dev/null
+++ b/requirements.txt
@@ -0,0 +1,57 @@
+aiofiles==23.2.1
+anyio==4.1.0
+beautifulsoup4==4.12.3
+certifi==2023.5.7
+charset-normalizer==3.3.2
+ci-info==0.3.0
+click==8.1.7
+configobj==5.0.8
+configparser==6.0.0
+DateTime==5.4
+days==0.0.3
+et-xmlfile==1.1.0
+etelemetry==0.3.1
+filelock==3.13.1
+frontend==0.0.3
+future==0.18.3
+get-rankings==0.8
+h11==0.14.0
+httplib2==0.22.0
+idna==3.6
+isodate==0.6.1
+itsdangerous==2.1.2
+looseversion==1.3.0
+lxml==4.9.3
+networkx==3.2.1
+nibabel==5.1.0
+nipype==1.8.6
+numpy==1.25.2
+openpyxl==3.1.2
+packaging==23.2
+pandas==2.0.3
+parsedate==0.0.1
+pathlib==1.0.1
+pillow==10.3.0
+prov==2.0.0
+pydot==1.4.2
+PyMuPDF==1.23.7
+PyMuPDFb==1.23.7
+pyparsing==3.1.1
+PyPDF2==3.0.1
+python-dateutil==2.8.2
+pytz==2023.3
+pyxnat==1.6
+rdflib==7.0.0
+requests==2.31.0
+scipy==1.11.4
+simplejson==3.19.2
+six==1.16.0
+sniffio==1.3.0
+soupsieve==2.5
+starlette==0.33.0
+tqdm==4.66.1
+traits==6.3.2
+tzdata==2023.3
+urllib3==2.1.0
+uvicorn==0.24.0.post1
+zope.interface==6.1