Page 1 sur 1

Liste de course

Publié : lun. 24/nov./2025 14:39
par Micoute
Bonjour à tous,
je vous offre un programme pour fabriquer des listes de courses, le plus gros est fait, mais il vous faudra indiquer vos répertoires.
S'il vous manques des choses, je vous les ajouterai par ce forum.

Code : Tout sélectionner

;Liste de curses grand modèle
;{ Fichiers inclus à définir
;XIncludeFile "D:\Programmation\Prg Perso\Include\Date2.pbi"
;}
;{ Fichiers
Enumeration
  #Fichier_Courses
EndEnumeration
;}
;{ Fenêtres
Enumeration
  #Fenetre_principale
EndEnumeration
;}
;{ Gadgets
Enumeration
  ;{ Textes
  #Txt_Signature
  #Txt_Liste_Rayon
  #Txt_Liste_D_Achats
  #Txt_Liste_courses_ouvert
  #Txt_Fichier_courses_ouvert
  #Txt_Quantite
  #Txt_Alimentaire
  #Txt_Non_Alimentaire
  ;}
  ;{ Boutons
  #Btn_Boissons
  #Btn_Boucherie
  #Btn_Boulangerie
  #Btn_Charcuterie
  #Btn_Condiments
  #Btn_Conserves
  #Btn_Desserts
  #Btn_Epicerie
  #Btn_Fromagerie
  #Btn_Fruits_et_legumes
  #Btn_Pates
  #Btn_Poissonnerie
  #Btn_Produits_frais
  #Btn_Produits_laitiers
  #Btn_Fournitures
  #Btn_Linge
  #Btn_Menage
  #Btn_Soins_et_beaute
  #Btn_Dolce_Gusto
  #Btn_Traiteur
  #Btn_Surgeles
  #Btn_Accessoires
  #Btn_Fetes_et_cadeaux
  #Btn_Informatique
  #Btn_Linge_de_maison
  ;}
  ;{ Conteneurs
  #Ctn_Liste_Rayon
  #Ctn_Liste_courses
  #Ctn_Boutons
  #Ctn_Boutons_Alimentaire
  #Ctn_Boutons_Maison
  ;}
  ;{ Listes
  #Lst_Rayon
  #Lst_Courses
  ;}
  ;{ Boutons de contrôles
  #Btn_Charger_Courses
  #Btn_Sauvegarder_Courses
  #Btn_Supprimer_Courses
  #Btn_Supprimer_Liste
  #Btn_Imprimer
  #Btn_Quitter
  ;}
  EndEnumeration
  ;}
;{ Polices
Enumeration
  #Police
  #Police_Grasse
  #Police_Lst
  #Police_Impression
EndEnumeration
;}
;{ Structures
Structure sProduit
  Produit.s
  Rayon.s
  Magasin.s
EndStructure
Structure sCourse
  Produit.s
  Rayon.s
EndStructure
;}
;{ Variables
Global Evenement,  Rep$ = GetPathPart(ProgramFilename()) : SetCurrentDirectory(Rep$)
Global.sCourse NewList Courses()
Global.sProduit NewList Lst_Produits(), NewList ListeProduitsTemporelle.sProduit() ; Liste temporaire pour stocker les produits d'un rayon
Global$ FichierBDD$ ;= Rep$ + "Bdd\produits_achats.json"
Global$ FichierCourses$, Rayon$, Fichier_par_defaut ;= Rep$ + "Courses\.Json"
Global Element, PageH, PrinterW, PrinterH, i, x = 10, Charge.b = #False, Sauve.b = #False, Modif.b = #False, LngLst, LngLstMod, Quantite
Global ProduitSelectionne.s, RayonSelectionne.s, RayonActif.s, Produit.s, RayonActuel.s, Txt.s
;}
;{ Plugins
UsePNGImageDecoder()
;}
;{ Chargement est assignations des polices
LoadFont(#Police, "FontAwesome", 20, #PB_Font_HighQuality)
LoadFont(#Police_Grasse, "FontAwesome", 19, #PB_Font_Bold)
LoadFont(#Police_Lst, "FontAwesome", 20, #PB_Font_HighQuality)
LoadFont(#Police_Impression, "DejaVu Sans Mono", 60, #PB_Font_Bold)
SetGadgetFont(#PB_Default, FontID(#Police))
;}
;{ Déclarations des procédures
Declare Charger_produits()
Declare Quitter()
Declare Programme_principal()
Declare AfficherRayon(Rayon.s)
Declare SelectionnerProduit()
Declare GestionBoutonsRayon()
Declare SupprimerProduitCourse()
Declare SupprimerFichierCourses()
Declare Choisir_Liste_de_courses(Message$="")
Declare Charger_Courses()
Declare Sauvegarder_Courses()
Declare Imprimer()
;}
;{ Initialisations et lancement du programme principal
Programme_principal()
;}
;{ Macros et procédures
Macro TrierListeStruc(_NomListe_, _options_, _Champ_Structure_)
  ; Cette macro simplifie l'utilisation de la fonction intégrée SortTxtucturedList().
  SortStructuredList(_NomListe_, _options_, OffsetOf(_Champ_Structure_), TypeOf(_Champ_Structure_))
EndMacro
Procedure Charger_produits()
  If ReadFile(#Fichier_Courses, FichierBDD$)
    CloseFile(#Fichier_Courses)
        ;Lecture du fichier JSON
    LoadJSON(#Fichier_Courses, FichierBDD$, #PB_JSON_NoCase)
        ;Extraction de la chaine JSON vers la liste chainée produits
    ExtractJSONList(JSONValue(#Fichier_Courses),Lst_Produits())
    
    TrierListeStruc(Lst_Produits(), #PB_Sort_Ascending, sProduit\Produit)
    TrierListeStruc(Lst_Produits(), #PB_Sort_Ascending, sProduit\Rayon)
    TrierListeStruc(Lst_Produits(), #PB_Sort_Ascending, sProduit\Magasin)
    Sauve = #False
  Else
    MessageRequester("ATTENTION","Le fichier " + FichierBDD$ + " ne peut pas être chargé")
  EndIf
EndProcedure
Procedure Quitter()
  Protected Reponse = 0
  ; Vérifie que l'événement est bien un clic sur le bouton Quitter
  Select EventType()
    Case #PB_EventType_LeftClick
      If Sauve = #False And Modif = #True And ListSize(Courses()) > 0
        Reponse = MessageRequester("ATENTION", "Vous n'avez pas sauvegardé votre travail" + #LF$ + #LF$ + "Voulez-vous le faire maintenant ?", #PB_MessageRequester_YesNo|#PB_MessageRequester_Info)
        If Reponse = #PB_MessageRequester_Yes
          Sauvegarder_Courses()
        EndIf
      EndIf
      ; Fermeture propre de la fenêtre principale
      CloseWindow(#Fenetre_principale)
      End
  EndSelect
EndProcedure
Procedure Programme_principal()
  If OpenWindow(#Fenetre_principale, 0, 0, 1990, 1080, "Liste de courses", #PB_Window_BorderLess|#PB_Window_ScreenCentered)
    TextGadget(#Txt_Signature, 40, 0, 1970, 40, UCase("Liste de courses par Micoute " + NomJourSemaine(Date()) + " " + Day(Date()) + " " + NomMois(Date()) + " " + Year(Date())),#SS_CENTERIMAGE|#SS_CENTER)
    SetGadgetFont(#Txt_Signature, FontID(#Police_Grasse))
    ContainerGadget(#Ctn_Boutons_Alimentaire, 40, 40, 350, 1000, #PB_Container_BorderLess)
    TextGadget(#Txt_Alimentaire, 0, 0, 350, 40, "Alimentaires",#SS_CENTERIMAGE|#SS_CENTER)
    ButtonImageGadget(#Btn_Boissons, 0, 40, 350, 40, 0)
    ButtonImageGadget(#Btn_Boucherie, 0, 80, 350, 40, 0)
    ButtonImageGadget(#Btn_Boulangerie, 0, 120, 350, 40, 0)
    ButtonImageGadget(#Btn_Charcuterie, 0, 160, 350, 40, 0)
    ButtonImageGadget(#Btn_Condiments, 0, 200, 350, 40, 0)
    ButtonImageGadget(#Btn_Conserves, 0, 240, 350, 40, 0)
    ButtonImageGadget(#Btn_Desserts, 0, 280, 350, 40, 0)
    ButtonImageGadget(#Btn_Epicerie, 0, 320, 350, 40, 0)
    ButtonImageGadget(#Btn_Fromagerie, 0, 360, 350, 40, 0)
    ButtonImageGadget(#Btn_Fruits_et_legumes, 0, 400, 350, 40, 0)
    ButtonImageGadget(#Btn_Pates, 0, 440, 350, 40, 0)
    ButtonImageGadget(#Btn_Poissonnerie, 0, 480, 350, 40, 0)
    ButtonImageGadget(#Btn_Produits_frais, 0, 520, 350, 40, 0)
    ButtonImageGadget(#Btn_Produits_laitiers, 0, 560, 350, 40, 0)
    ButtonImageGadget(#Btn_Dolce_Gusto, 0, 600, 350, 40, 0)
    ButtonImageGadget(#Btn_Traiteur, 0, 640, 350, 40, 0)
    ButtonImageGadget(#Btn_Surgeles, 0, 680, 350, 40, 0)
    CloseGadgetList()
    ContainerGadget(#Ctn_Boutons_Maison, 430, 40, 350, 1000, #PB_Container_BorderLess)
    TextGadget(#Txt_Non_Alimentaire, 0, 0, 350, 40, "Non Alimentaires",#SS_CENTERIMAGE|#SS_CENTER)
    ButtonImageGadget(#Btn_Accessoires, 0, 40, 350, 40, 0)
    ButtonImageGadget(#Btn_Fetes_et_cadeaux, 0, 80, 350, 40, 0)
    ButtonImageGadget(#Btn_Informatique, 0, 120, 350, 40, 0)
    ButtonImageGadget(#Btn_Linge_de_maison, 0, 160, 350, 40, 0)
    ButtonImageGadget(#Btn_Soins_et_beaute, 0, 200, 350, 40, 0)
    ButtonImageGadget(#Btn_Fournitures, 0, 240, 350, 40, 0)
    ButtonImageGadget(#Btn_Linge, 0, 280, 350, 40, 0)
    ButtonImageGadget(#Btn_Menage, 0, 320, 350, 40, 0)
    CloseGadgetList()
    
    ContainerGadget(#Ctn_Liste_Rayon, 820, 40, 350, 1000, #PB_Container_BorderLess)
    TextGadget(#Txt_Liste_Rayon, 0, 0, 370, 40, "Liste vide", #SS_CENTERIMAGE|#SS_CENTER)
    ListIconGadget(#Lst_Rayon, 0, 40, 370, 960, "", 340, #LVS_NOCOLUMNHEADER)
    CloseGadgetList()
    
    ContainerGadget(#Ctn_Boutons, 1210, 40, 350, 1000, #PB_Container_BorderLess)
    ButtonImageGadget(#Btn_Charger_Courses,     0,   40, 350, 100, 0)
    ButtonImageGadget(#Btn_Sauvegarder_Courses, 0, 204, 350, 100, 0)
    ButtonImageGadget(#Btn_Supprimer_Courses,   0, 378, 350, 100, 0)
    ButtonImageGadget(#Btn_Supprimer_Liste,     0, 552, 350, 100, 0)
    ButtonImageGadget(#Btn_Imprimer,            0, 726, 350, 100, 0)
    ButtonImageGadget(#Btn_Quitter,             0, 900, 350, 100, 0)
    CloseGadgetList()
    
    ContainerGadget(#Ctn_Liste_courses, 1600, 40, 350, 1000, #PB_Container_BorderLess)
    TextGadget(#Txt_Liste_D_Achats, 0, 0, 370, 40, "Liste d'achats", #SS_CENTERIMAGE|#SS_CENTER)
    ListIconGadget(#Lst_Courses, 0, 40, 350, 960, "", 340, #LVS_NOCOLUMNHEADER)
    CloseGadgetList()
    
    TextGadget(#Txt_Liste_courses_ouvert, 35, 1040, 270, 30, "Fichier de courses ouvert : ", #SS_CENTERIMAGE)
    TextGadget(#Txt_Fichier_courses_ouvert, 305, 1040, 600, 30, "aucun", #SS_CENTERIMAGE)
    TextGadget(#Txt_Quantite, 1335+390, 1040, 350, 30, "", #SS_CENTERIMAGE)
    
    ;Textes des boutons
    ;{ Boutons rayons
    SetGadgetText(#Btn_Boissons, "Boissons")
    SetGadgetText(#Btn_Boucherie, "Boucherie")
    SetGadgetText(#Btn_Boulangerie, "Boulangerie")
    SetGadgetText(#Btn_Charcuterie, "Charcuterie")
    SetGadgetText(#Btn_Condiments, "Condiments")
    SetGadgetText(#Btn_Conserves, "Conserves")
    SetGadgetText(#Btn_Desserts, "Desserts")
    SetGadgetText(#Btn_Epicerie, "Epicerie")
    SetGadgetText(#Btn_Fromagerie, "Fromagerie")
    SetGadgetText(#Btn_Fruits_et_legumes, "Fruits et légumes")
    SetGadgetText(#Btn_Pates, "Pâtes, purée et féculents")
    SetGadgetText(#Btn_Poissonnerie, "Poissonnerie")
    SetGadgetText(#Btn_Produits_frais, "Produits frais")
    SetGadgetText(#Btn_Produits_laitiers, "Produits laitiers")
    SetGadgetText(#Btn_Fournitures, "Fournitures")
    SetGadgetText(#Btn_Linge, "Linge")
    SetGadgetText(#Btn_Menage, "Ménage")
    SetGadgetText(#Btn_Soins_et_beaute, "Soins et beauté")
    SetGadgetText(#Btn_Dolce_Gusto, "Dolce Gusto")
    SetGadgetText(#Btn_Traiteur, "Traiteur")
    SetGadgetText(#Btn_Surgeles, "Surgelés")
    SetGadgetText(#Btn_Accessoires, "Accessoires")
    SetGadgetText(#Btn_Fetes_et_cadeaux, "Fêtes et cadeaux")
    SetGadgetText(#Btn_Informatique, "Informatique")
    SetGadgetText(#Btn_Linge_de_maison, "Linge de maison")
    ;}
    ;{ Boutons de contrôles
    SetGadgetText(#Btn_Charger_Courses, "Charger liste de courses")
    SetGadgetText(#Btn_Sauvegarder_Courses, "Sauvegarder la liste")
    SetGadgetText(#Btn_Supprimer_Courses, "Supprimer ce produit")
    SetGadgetText(#Btn_Supprimer_Liste, "Supprimer une liste de courses")
    SetGadgetText(#Btn_Imprimer, "Imprimer la liste de courses")
    SetGadgetText(#Btn_Quitter, "Quitter le programme")
    ;}
    ;{ Polices    
    SetGadgetFont(#Lst_Rayon, FontID(#Police_Lst))
    SetGadgetFont(#Txt_Liste_Rayon, FontID(#Police_Grasse))
    SetGadgetFont(#Lst_Courses, FontID(#Police_Lst))
    ;}
    ;Couleurs
    SetWindowColor(#Fenetre_principale, $8C1601)
    SetGadgetColor(#Txt_Signature, #PB_Gadget_BackColor, GetWindowColor(#Fenetre_principale))
    SetGadgetColor(#Ctn_Boutons, #PB_Gadget_BackColor, GetWindowColor(#Fenetre_principale))
    SetGadgetColor(#Txt_Signature, #PB_Gadget_FrontColor, $FED1C9)
    SetGadgetColor(#Ctn_Boutons_Alimentaire, #PB_Gadget_BackColor, GetWindowColor(#Fenetre_principale))
    SetGadgetColor(#Ctn_Boutons_Maison, #PB_Gadget_BackColor, GetWindowColor(#Fenetre_principale))
    SetGadgetColor(#Txt_Alimentaire, #PB_Gadget_FrontColor, $FED1C9)
    SetGadgetColor(#Txt_Alimentaire,  #PB_Gadget_BackColor, GetWindowColor(#Fenetre_principale))
    SetGadgetColor(#Txt_Non_Alimentaire, #PB_Gadget_FrontColor, $FED1C9)
    SetGadgetColor(#Txt_Non_Alimentaire,  #PB_Gadget_BackColor, GetWindowColor(#Fenetre_principale))
    SetGadgetColor(#Txt_Liste_D_Achats, #PB_Gadget_FrontColor, $FED1C9)
    SetGadgetColor(#Txt_Liste_D_Achats,  #PB_Gadget_BackColor, GetWindowColor(#Fenetre_principale))
    
    SetGadgetColor(#Txt_Liste_Rayon, #PB_Gadget_FrontColor, $FED1C9)
    SetGadgetColor(#Txt_Liste_Rayon, #PB_Gadget_BackColor, GetWindowColor(#Fenetre_principale))
    SetGadgetColor(#Lst_Courses, #PB_Gadget_BackColor, $FED1C9)
    SetGadgetColor(#Lst_Rayon, #PB_Gadget_BackColor, $FED1C9)
    For i = #Txt_Liste_courses_ouvert To #Txt_Quantite
      SetGadgetColor(i, #PB_Gadget_BackColor, GetWindowColor(#Fenetre_principale))
      SetGadgetColor(i, #PB_Gadget_FrontColor, $FED1C9)
      SetGadgetFont(i, FontID(#Police_Grasse))
    Next i
    
    Charger_produits()
    ;{ Evénements liés
    BindGadgetEvent(#Btn_Quitter, @Quitter())
    ;}
  EndIf
EndProcedure
Procedure AfficherRayon(Rayon.s)
  ClearGadgetItems(#Lst_Rayon) ; Vider la liste avant d'afficher les nouveaux produits
    ForEach Lst_Produits()
    If Lst_Produits()\Rayon = Rayon
      AddGadgetItem(#Lst_Rayon, -1, Lst_Produits()\Produit); + "|" + Lst_Produits()\Rayon) ; Ajouter le produit et le rayon
    EndIf
  Next
EndProcedure
Procedure SelectionnerProduit()
  Protected Index = GetGadgetState(#Lst_Rayon) ; Récupère l'indice sélectionné
  If Index <> -1 ; Vérifie qu'une ligne est bien sélectionnée
    Protected Produit.s = GetGadgetItemText(#Lst_Rayon, Index, 0) ; Récupère la chaîne sélectionnée
      SetGadgetItemColor(#Lst_Rayon, GetGadgetState(#Lst_Rayon), #PB_Gadget_BackColor, RGB(255, 255, 0)) ; Jaune pour surligner
      ;Debug "Produit : " + Produit
      ;Debug "Rayon actif : " + RayonActif
      ; Ajouter le produit à la liste #Lst_Courses
      AddElement(Courses())
      Courses()\Produit = Produit
      Courses()\Rayon = RayonActif
      AddGadgetItem(#Lst_Courses, -1, Produit)
      Modif = #True
    LngLst = ListSize(Courses())
            If LngLst < 2
              Txt = " article"
            Else
              Txt = " articles"
            EndIf
    SetGadgetText(#Txt_Quantite, Str(LngLst) + Txt)
  Else
    ;Debug "Aucune ligne sélectionnée dans #Lst_Rayon."
  EndIf
EndProcedure

Procedure GestionBoutonsRayon()
  Select EventGadget()
    Case #Btn_Boissons
      AfficherRayon("Boissons")
      RayonActif = "Boissons"
      ;Debug "Rayon actif : " + RayonActif
    Case #Btn_Boucherie
      AfficherRayon("Boucherie")
      RayonActif = "Boucherie"
      ;Debug "Rayon actif : " + RayonActif
    Case #Btn_Boulangerie
      AfficherRayon("Boulangerie")
      RayonActif = "Boulangerie"
      ;Debug "Rayon actif : " + RayonActif
    Case #Btn_Charcuterie
      AfficherRayon("Charcuterie")
      RayonActif = "Charcuterie"
      ;Debug "Rayon actif : " + RayonActif
    Case #Btn_Condiments
      AfficherRayon("Condiments")
      RayonActif = "Condiments"
      ;Debug "Rayon actif : " + RayonActif
    Case #Btn_Conserves
      AfficherRayon("Conserves")
      RayonActif = "Conserves"
      ;Debug "Rayon actif : " + RayonActif
    Case #Btn_Desserts
      AfficherRayon("Desserts")
      RayonActif = "Desserts"
      ;Debug "Rayon actif : " + RayonActif
    Case #Btn_Epicerie
      AfficherRayon("Epicerie")
      RayonActif = "Epicerie"
      ;Debug "Rayon actif : " + RayonActif
    Case #Btn_Fromagerie
      AfficherRayon("Fromagerie")
      RayonActif = "Fromagerie"
      ;Debug "Rayon actif : " + RayonActif
    Case #Btn_Fruits_et_legumes
      AfficherRayon("Fruits et légumes")
      RayonActif = "Fruits et légumes"
      ;Debug "Rayon actif : " + RayonActif
    Case #Btn_Pates
      AfficherRayon("Pâtes, riz, purée et féculents")
      RayonActif = "Pâtes"
      ;Debug "Rayon actif : " + RayonActif
    Case #Btn_Poissonnerie
      AfficherRayon("Poissonnerie")
      RayonActif = "Poissonnerie"
      ;Debug "Rayon actif : " + RayonActif
    Case #Btn_Produits_frais
      AfficherRayon("Produits frais")
      RayonActif = "Produits frais"
      ;Debug "Rayon actif : " + RayonActif
    Case #Btn_Produits_laitiers
      AfficherRayon("Produits laitiers")
      RayonActif = "Produits laitiers"
      ;Debug "Rayon actif : " + RayonActif
    Case #Btn_Fournitures
      AfficherRayon("Fournitures")
      RayonActif = "Fournitures"
      ;Debug "Rayon actif : " + RayonActif
    Case #Btn_Linge
      AfficherRayon("Linge")
      RayonActif = "Linge"
      ;Debug "Rayon actif : " + RayonActif
    Case #Btn_Menage
      AfficherRayon("Ménage")
      RayonActif = "Ménage"
      ;Debug "Rayon actif : " + RayonActif
    Case #Btn_Soins_et_beaute
      AfficherRayon("Soins et beauté")
      RayonActif = "Soins et beauté"
      ;Debug "Rayon actif : " + RayonActif
    Case #Btn_Dolce_Gusto
      AfficherRayon("Dolce Gusto")
      RayonActif = "Dolce Gusto"
      ;Debug "Rayon actif : " + RayonActif
    Case #Btn_Traiteur
      AfficherRayon("Traiteur")
      RayonActif = "Traiteur"
      ;Debug "Rayon actif : " + RayonActif
    Case #Btn_Surgeles
      AfficherRayon("Surgelés")
      RayonActif = "Surgelés"
      ;Debug "Rayon actif : " + RayonActif
    Case #Btn_Accessoires
      AfficherRayon("Accessoires")
      ;RayonActif = "Accessoires"
      ;Debug "Rayon actif : " + RayonActif
    Case #Btn_Fetes_et_cadeaux
      AfficherRayon("Fêtes et cadeaux")
      RayonActif = "Fêtes et cadeaux"
      ;Debug "Rayon actif : " + RayonActif
    Case #Btn_Informatique
      AfficherRayon("Informatique")
      RayonActif = "Informatique"
      ;Debug "Rayon actif : " + RayonActif
    Case #Btn_Linge_de_maison
      AfficherRayon("Linge de maison")
      RayonActif = "Linge de maison"
      ;Debug "Rayon actif : " + RayonActif
  EndSelect
  SetGadgetText(#Txt_Liste_Rayon, UCase(RayonActif))
EndProcedure
Procedure RafraichirListeCourses()
  ClearGadgetItems(#Lst_Courses) ; Supprime tous les éléments du gadget liste

  ; Re-remplit le gadget avec les éléments restants dans la liste chaînée
  ForEach Courses()
    AddGadgetItem(#Lst_Courses, -1, Courses()\Produit)
  Next
EndProcedure
Procedure SupprimerProduitCourse()
  Protected Index = GetGadgetState(#Lst_Courses) ; Récupère l’indice de la sélection
  ;Debug "Index sélectionné : " + Str(Index) ; Vérification

  If Index <> -1 ; Vérifie qu’une ligne est bien sélectionnée
    Protected Selection.s = GetGadgetItemText(#Lst_Courses, Index, 0) ; Produit sélectionné
    Protected Reponse = MessageRequester("Confirmation", "Voulez-vous vraiment supprimer : " + Selection + " ?", #PB_MessageRequester_YesNo)

    If Reponse = #PB_MessageRequester_Yes
      ; Supprime l’élément du gadget liste
      RemoveGadgetItem(#Lst_Courses, Index)
      
      ; Supprime l’élément correspondant dans la liste chaînée
      ForEach Courses()
        If Courses()\Produit = Selection
          DeleteElement(Courses()) 
          ;Debug "Produit supprimé dans la liste chaînée : " + Selection
          Modif = #True
          Break
        EndIf
      Next

      ; Rafraîchit l'affichage du gadget liste
      RafraichirListeCourses()
    Else
      ;Debug "Suppression annulée."
    EndIf
  Else
    ;Debug "Aucune sélection dans la liste des courses."
    MessageRequester("Erreur", "Veuillez sélectionner un produit à supprimer.")
  EndIf
EndProcedure
Procedure SupprimerFichierCourses()
  Protected Reponse
  Select EventType()
    Case #PB_EventType_LeftClick 
      If FichierCourses$ = ""
        Choisir_Liste_de_courses("Choisissez la liste de courses à supprimer")
        If FichierCourses$ <> ""
          Reponse = MessageRequester("ATTENTION", "Désirez-vous vraiment supprimer le fichier "+#LF$+#LF$+FichierCourses$+" ?", #PB_MessageRequester_YesNo|#PB_MessageRequester_Warning)
          If Reponse = #PB_MessageRequester_Yes
            DeleteFile(FichierCourses$)
            MessageRequester("Information", "Votre fichier a été supprimé avec succès", #PB_MessageRequester_Info)
            Quitter()
          EndIf
        EndIf
      EndIf 
  EndSelect
EndProcedure
Procedure Choisir_Liste_de_courses(Message$="")
  Protected Resultat, Filtre$ = "Fichier de courses *.Json"
  Resultat = ReadFile(#Fichier_Courses, Fichier_par_defaut)
  If Resultat <> 0
    FichierCourses$ = Fichier_par_defaut
    If FichierCourses$ <> ""
      If Right(FichierCourses$, 5) <> ".Json"
        FichierCourses$  + ".Json"
      EndIf
    EndIf
  ElseIf Resultat = 0 ;le fichier n'existe pas
    FichierCourses$ = OpenFileRequester(Message$, Fichier_par_defaut, Filtre$, 0)
    If FichierCourses$ <> ""
      If Right(FichierCourses$, 5) <> ".Json"
        FichierCourses$  + ".Json"
      EndIf
    Else
      MessageRequester("Information", "La sélection a été annulée.", #PB_MessageRequester_Ok|#PB_MessageRequester_Info)
    EndIf
  Else
    MessageRequester("Information","Impossible d'ouvrir le fichier!" + #LF$ + #LF$ + "Le programme va se fermer" , #PB_MessageRequester_Error)
    End
  EndIf
EndProcedure
Procedure Charger_Courses()
  
  Select EventType()
    Case #PB_EventType_LeftClick 
      If FichierCourses$ = ""
        Choisir_Liste_de_courses("Choisissez la liste de course à utiliser")
        If FichierCourses$ <> ""          
          LoadJSON(#Fichier_Courses, FichierCourses$)
          ExtractJSONList(JSONValue(#Fichier_Courses), Courses())
          If LastElement(Courses()) <> 0
            SortStructuredList(Courses(), #PB_Sort_Ascending, OffsetOf(sCourse\Rayon), TypeOf(sCourse\Rayon))
            ForEach Courses()
              AddGadgetItem(#Lst_Courses, -1, Courses()\Produit)
              SetGadgetItemData(#Lst_Courses, CountGadgetItems(#Lst_Courses) - 1, ListIndex(Courses()))
              
              ;{ Accorder les produits avec les rayons correspondants)
              With Courses()
                ; Exemple : ajouter un indicateur pour le rayon ou le formater
                ;Debug \Produit + " => " + \Rayon
              EndWith
            Next
            LngLst = ListSize(Courses())
            If LngLst < 2
              Txt = " article"
            Else
              Txt = " articles"
            EndIf  
            SetGadgetText(#Txt_Quantite,  Str(LngLst) + Txt)
            SetGadgetText(#Txt_Fichier_courses_ouvert, GetFilePart(FichierCourses$, #PB_FileSystem_NoExtension))
          EndIf
        EndIf
      EndIf
  EndSelect                
EndProcedure                
Procedure Sauvegarder_Courses()
  If ListSize(Courses()) > 0
    SortStructuredList(Courses(), #PB_Sort_Ascending, OffsetOf(sCourse\Produit), TypeOf(sCourse\Produit))
    SortStructuredList(Courses(), #PB_Sort_Ascending, OffsetOf(sCourse\Rayon), TypeOf(sCourse\Rayon))
    Select EventType()
      Case #PB_EventType_LeftClick 
        Protected Resultat, Filtre$ = Rep$ + "Courses\Fichier de courses *.Json"
        If FichierCourses$ = ""
          FichierCourses$ = SaveFileRequester("Donne un nom à ton fichier de courses", Filtre$, "Json", 0)
        EndIf  
        If Right(FichierCourses$, 5) <> ".Json"
          FichierCourses$  + ".Json"
        EndIf
        Charge = #True
        If Charge = #True
          DeleteFile(FichierCourses$)
        EndIf
        CreateJSON(#Fichier_Courses)
        InsertJSONList(JSONValue(#Fichier_Courses), Courses())
        Resultat = SaveJSON(#Fichier_Courses, FichierCourses$, #PB_JSON_PrettyPrint)
        If Resultat
          MessageRequester("INFO", "Votre fichier " + FichierCourses$ + " a été sauvegardé et le programme va se fermer", #PB_MessageRequester_Ok|#PB_MessageRequester_Info)
          Sauve = #True
          Quitter()
        EndIf
    EndSelect
  EndIf
EndProcedure
Procedure.i Pair(Nombre.i) ; - Indique si un nombre est pair
  If Nombre & 1 = 0
    ProcedureReturn #True
  Else
    ProcedureReturn #False
  EndIf
EndProcedure
Procedure.i Impair(Nombre.i) ; - Indique si un nombre est impair
  If Nombre & 1 = 1
    ProcedureReturn #True
  Else
    ProcedureReturn #False  
  EndIf
EndProcedure
Procedure CentrerTexteXY(X0.i, X1.i, y.i, Texte.s, Couleur.i) ; Centre le texte entre X0 et X1 à la hauteur et à la couleur choisies.  
  Protected X.i = (X1 + X0 - TextWidth(Texte)) / 2
  DrawText(X, y, Texte, Couleur)
EndProcedure
Procedure AfficherListe(List param.sProduit(), Rayon.s)
  CentrerTexteXY(X, 2892, PageH, UCase(Rayon), $FF)
  PageH + TextHeight(Rayon)
  If Impair(i)
    i + 1
  EndIf  
  ForEach param()
    If Pair(i)
      DrawText(x, PageH, Chr(9675) + " " + param()\Produit, $000000)
      i + 1
    ElseIf Impair(i)
      DrawText(x + 1446, PageH, Chr(9675) + " " + param()\Produit, $000000)
      PageH + TextHeight(param()\Produit)
      i + 1
    EndIf
  Next
  If Impair(ListSize(param()))
    PageH + TextHeight(" ")
  EndIf
EndProcedure
Procedure Imprimer()
  If ListSize(Courses()) > 0
    If PrintRequester()
      ;Debug "Imprimante sélectionnée."
      
      PrinterW = PrinterPageWidth()
      PrinterH = PrinterPageHeight()
      
      If StartPrinting("Courses")
        If StartDrawing(PrinterOutput())
          DrawingMode(#PB_2DDrawing_Transparent)
          DrawingFont(FontID(#Police_Impression))
          
          Protected PageH = 0
          
          ForEach Courses()
            ; Détecter le changement de rayon
            If Courses()\Rayon <> RayonActuel
              If RayonActuel <> "" ; Si ce n'est pas le premier rayon, imprimer les produits
                AfficherListe(ListeProduitsTemporelle(), RayonActuel)
                ClearList(ListeProduitsTemporelle()) ; Réinitialiser la liste temporaire
              EndIf
              
              RayonActuel = Courses()\Rayon
              ;Debug "Rayon actif : " + RayonActuel
            EndIf
            
            ; Ajouter le produit courant à la liste temporaire
            AddElement(ListeProduitsTemporelle())
            ListeProduitsTemporelle()\Produit = Courses()\Produit
          Next
          
          ; Imprimer les produits du dernier rayon après la boucle
          If RayonActuel <> ""
            AfficherListe(ListeProduitsTemporelle(), RayonActuel)
          EndIf
          
          StopDrawing()
        Else
          ;Debug "Erreur lors du dessin sur l'imprimante."
        EndIf
        StopPrinting()
      Else
        ;Debug "Erreur lors du démarrage de l'impression."
      EndIf
    Else
      ;Debug "Aucune imprimante sélectionnée."
    EndIf
  Else
    ;Debug "Liste de courses vide."
  EndIf
EndProcedure
;{- Boucle événementielle
Repeat
  Evenement = WaitWindowEvent()
  Select Evenement
    Case #PB_Event_Gadget
      Select EventGadget()
        Case #Btn_Charger_Courses
          Charger_Courses()
        Case #Btn_Supprimer_Liste
          SupprimerFichierCourses()
        Case #Btn_Imprimer
          Imprimer()
        Case #Btn_Supprimer_Courses
          SupprimerProduitCourse()
        Case #Btn_Sauvegarder_Courses
          Sauvegarder_Courses()
        Case #Lst_Rayon
          If EventType() = #PB_EventType_LeftClick
            SelectionnerProduit()
          EndIf
        Default
          GestionBoutonsRayon()
      EndSelect
    Case #PB_Event_CloseWindow
      Break
  EndSelect
ForEver
;}

Re: Liste de course

Publié : lun. 24/nov./2025 15:49
par Mindphazer
Bonjour Micoute,
ton programme génère une erreur en ligne 169 : NomJourSemaine() n'est pas une fonction
Je suppose que cette procédure se trouve dans ton fichier Date2.pbi qu'on voit commentée à la ligne 3 de ton programme...

Re: Liste de course

Publié : lun. 24/nov./2025 16:07
par Micoute
Il te faudra pour cela inclure le fichier Date2.pbi que j'ai déjà envoyé dans Applcations.