[TUTO débutants] les modules

Informations pour bien débuter en PureBasic
Avatar de l’utilisateur
microdevweb
Messages : 1798
Inscription : mer. 29/juin/2011 14:11
Localisation : Belgique

[TUTO débutants] les modules

Message par microdevweb »

"Oméga" m'a suggéré de faire un tutoriel sur les modules.

Plan du tutoriel

Pourquoi; quand; comment?

ce tuto étant destiner à un membre que je ne désire plus aider, je ne poursuivrais pas les point repris ci-dessous.
Je ne pense pas que cela manquera à la communauté et sauf avis contraire de votre part ce tuto en restera la.


Travailler avec plusieurs modules (Annuler)

Trucs et astuces (Annuler)
Dernière modification par microdevweb le sam. 18/août/2018 15:42, modifié 2 fois.
Windows 10 64 bits PB: 5.70 ; 5.72 LST
Work at Centre Spatial de Liège
Avatar de l’utilisateur
microdevweb
Messages : 1798
Inscription : mer. 29/juin/2011 14:11
Localisation : Belgique

Re: [TUTO débutants] les modules

Message par microdevweb »

Pourquoi; quand; comment?

Pourquoi
En programmation il est fortement conseillé de proscrire les variables globales.
Mais alors comment faire, des fois les procédures seules ne suffisent pas.

Même s'il apparaît que de développer de façon structurée et modulaire peut prendre plus de temps, on récupère ce temps perdu le jour ou l'on doit replonger dans le code de son logiciel des années plus tard.

Certains modules conçus de façon efficace seront facilement réutilisables.

Quand

Dès qu'un code prend un peu de volume il devient vraiment intéressant de développer de façon modulaire.

Les modules de "PureBasic" sont équivalents aux espaces de noms du langage C.

Si plusieurs personnes travaillent sur un même projet, il risque d'utiliser les mêmes noms de variable ou de procédures. L'utilisation de modules le permet sans soucis.

Comment

Déclare un module est assez simple. Il suffit de regarder le code ci-dessous.

Code : Tout sélectionner

DeclareModule MonModule
  
EndDeclareModule
Module MonModule
  
EndModule
Mais comment ça marche ? Allez-vous me dire.

Et bien assez simplement, tout ce qui est entre les balises DeclareModule et EndDeclareModule sera accessible depuis l'extérieur du module mais ne rentrera pas en concurrence avec votre autre code.

Exemple :

Code : Tout sélectionner

Global maVariable = 10
DeclareModule MonModule
  Global maVariable = 50
EndDeclareModule
Module MonModule
  
EndModule

Debug maVariable ; retourne 10
Debug MonModule::maVariable ; retourne 50
Tout ce qui est déclaré entre les balises module et EndModule sera privé et accessible uniquement dans le module.

Donc avec ce concept on peut vraiment structurer sont codes de façon efficace.

Passons à la pratique, je vais reprendre l'exemple de mon tutoriel sur les structures.

Dans le cadre d'un module classique je placerais mes structures dans Module, mais je vais faire hériter de ces structures dans un autre module client je les ai donc rendues publique.

Remarque : Dans ce cas j'ai pour habitude de faire précéder mes structures, variable, procédure d'un _ (ce qui revient à dire touche pas à ça petit ... :mrgreen: )

Code complet :

Code : Tout sélectionner


DeclareModule Contacts
  Structure _adresse
    rue.s
    numero.l
    codePostal.l
    localite.s
  EndStructure
  Structure _contact
    nom.s
    prenom.s
    telephone.s
    monAdresse._adresse
  EndStructure
  
  Declare addContact(nom.s,prenom.s,telephone.s)
  Declare setAdresse(rue.s,numero.l,codePostal.l,localite.s)
  Declare.s getNom()
  Declare.s getPrenom()
  Declare.s getTelephone()
  Declare getCodePostal()
  Declare.s getLocalite()
  Declare getNumero()
  Declare.s getRue()
  Declare setNom(nom.s)
  Declare setPrenom(prenom.s)
  Declare setTelephone(telephone.s)
  Declare setCodePostal(codePostal)
  Declare setLocalite(localite.s)
  Declare setNumero(numero)
  Declare setRue(rue.s)
  Declare initList()
  Declare nextItem()
EndDeclareModule
Module Contacts
  Global NewList mesContacts._contact()
  ;-* Procédures privées
  
  ;}
  ;-* Procédures publiques
  ; ajoute un nouveau contact
  Procedure addContact(nom.s,prenom.s,telephone.s)
    With mesContacts()
      AddElement(mesContacts())
      \nom = nom
      \prenom = prenom
      \telephone = telephone
    EndWith
  EndProcedure
  ; initialise l'addresse, et à utilisé parès l'ajout
  ; car lélément de la liste reste actif
  Procedure setAdresse(rue.s,numero.l,codePostal.l,localite.s)
    With mesContacts()\monAdresse
      \rue = rue
      \numero = numero
      \codePostal = codePostal
      \localite = localite
    EndWith
  EndProcedure
  ; place la liste avec aucun élément current
  Procedure initList()
    ResetList(mesContacts())
  EndProcedure
  ; passe à l'élément suivant
  Procedure nextItem()
    ProcedureReturn NextElement(mesContacts())
  EndProcedure
  ;-* Getters
  Procedure.s getNom()
    With mesContacts()
      ProcedureReturn \nom
    EndWith
  EndProcedure
  
  Procedure.s getPrenom()
    With mesContacts()
      ProcedureReturn \prenom
    EndWith
  EndProcedure
  
  Procedure.s getTelephone()
    With mesContacts()
      ProcedureReturn \telephone
    EndWith
  EndProcedure
  
  Procedure getCodePostal()
    With mesContacts()\monAdresse
      ProcedureReturn \codePostal
    EndWith
  EndProcedure
  
  Procedure.s getLocalite()
    With mesContacts()\monAdresse
      ProcedureReturn \localite
    EndWith
  EndProcedure
  
  Procedure getNumero()
    With mesContacts()\monAdresse
      ProcedureReturn \numero
    EndWith
  EndProcedure
  
  Procedure.s getRue()
    With mesContacts()\monAdresse
      ProcedureReturn \rue
    EndWith
  EndProcedure
  
  ;}
  ;-* Setters
  Procedure setNom(nom.s)
    With mesContacts()
      \nom = nom
    EndWith
  EndProcedure
  
  Procedure setPrenom(prenom.s)
    With mesContacts()
      \prenom = prenom
    EndWith
  EndProcedure
  
  Procedure setTelephone(telephone.s)
    With mesContacts()
      \telephone = telephone
    EndWith
  EndProcedure
  
  Procedure setCodePostal(codePostal)
    With mesContacts()\monAdresse
      \codePostal = codePostal
    EndWith
  EndProcedure
  
  Procedure setLocalite(localite.s)
    With mesContacts()\monAdresse
      \localite = localite
    EndWith
  EndProcedure
  
  Procedure setNumero(numero)
    With mesContacts()\monAdresse
      \numero = numero
    EndWith
  EndProcedure
  
  Procedure setRue(rue.s)
    With mesContacts()\monAdresse
      \rue = rue
    EndWith
  EndProcedure
  ;}
  ;}
EndModule

; teste du module
Contacts::addContact("Bielen","Pierre","04/221 48 87")
Contacts::setAdresse("Rue Sainry",140,4870,"Trooz")
Contacts::addContact("Dumond","Albert","04/251 48 87")
Contacts::setAdresse("Rue du Bord",200,4000,"Liège")

Contacts::initList()
While Contacts::nextItem() 
  Debug Contacts::getNom()
  Debug Contacts::getPrenom()
  Debug Contacts::getTelephone()
  Debug Contacts::getRue()
  Debug Contacts::getNumero()
  Debug Contacts::getCodePostal()
  Debug Contacts::getLocalite()
Wend
Ce code peut vous sembler fastidieux parce que j'ai implémenté des getters et des setters. On peut éviter cela en placent Global NewList mes contacts ._contact() dans le DeclareModule et avoir ainsi accès à la liste.

Cependant encapsuler ses données est une bonne habitude, car vous aller lire les données dans plusieurs endroits du code.

Imaginer maintenant que vous deviez modifier les données reçues avant de les sauver. Ou les données envoyées. Avec ce système vous ne devrez modifier que le Getters ou Setters sans rien modifié d'autres
Dernière modification par microdevweb le sam. 18/août/2018 12:50, modifié 1 fois.
Windows 10 64 bits PB: 5.70 ; 5.72 LST
Work at Centre Spatial de Liège
Avatar de l’utilisateur
microdevweb
Messages : 1798
Inscription : mer. 29/juin/2011 14:11
Localisation : Belgique

Re: [TUTO débutants] les modules

Message par microdevweb »

Passage de paramètres.
Windows 10 64 bits PB: 5.70 ; 5.72 LST
Work at Centre Spatial de Liège
Avatar de l’utilisateur
microdevweb
Messages : 1798
Inscription : mer. 29/juin/2011 14:11
Localisation : Belgique

Re: [TUTO débutants] les modules

Message par microdevweb »

Trucs et astuces
Windows 10 64 bits PB: 5.70 ; 5.72 LST
Work at Centre Spatial de Liège
Avatar de l’utilisateur
microdevweb
Messages : 1798
Inscription : mer. 29/juin/2011 14:11
Localisation : Belgique

Re: [TUTO débutants] les modules

Message par microdevweb »

Omega

Ce tuto [TUTO] Programmation structurée (terminé au point de vue model)

Fait la relation sqlite et structure, mais il est plus compliqué. Sqlite un moyen de sauvegarde, les structures servent aux travail en mémoire. Les modules permettent de scinder le code en modules autonomes.
Windows 10 64 bits PB: 5.70 ; 5.72 LST
Work at Centre Spatial de Liège
Avatar de l’utilisateur
omega
Messages : 617
Inscription : sam. 26/nov./2011 13:04
Localisation : Alger

Re: [TUTO débutants] les modules

Message par omega »

Bonjour à tous
Fait la relation sqlite et structure
C'est ça ce que je cherche à savoir depuis le début. Structure est l'image d'UN ENREGISTREMENT d'une table sqlite. Cela veut dire que les mises à jour sur table sqlite se feront à partir des champs de la structure? Où se trouve l'avantage de la structure à ce moment là? Quelle différence y a t il avec les variables mémoires?
Sqlite est un moyen de sauvegarde, les structures servent aux travail en mémoire.
Même les tables sqlite sont utilisées en mémoire (ouverture, écriture, test, mise à jour) tout ça c'est du travail en mémoire et sur disque aussi...
Question: Est ce qu'une structure ne doit contenir qu'un seul enregistrement (en cours) pendant le traitement d'une table sqlite ?

Merci
Win7 (x64) 64 bits Pb 5.72
Avatar de l’utilisateur
Micoute
Messages : 2522
Inscription : dim. 02/oct./2011 16:17
Localisation : 35520 La Mézière

Re: [TUTO débutants] les modules

Message par Micoute »

bonjour omega,

si ça peut t'être utile, voici un exemple de programme que j'utilise,
il utilise une structure, une liste et une base de données JSON:

Code : Tout sélectionner

;Gestion Liste d'achats
; 13 avril 2018
; PB 5.70
; par Micoute


Enumeration	Fichiers
  #FichierJSON
EndEnumeration

Enumeration Fenetres
  #Fenetre_edition
EndEnumeration

Enumeration	Gadgets
  #Liste_produits
  #Txt_Magasin
  #Txt_Rayon
  #Txt_Nom_Produit
  #Txt_CP
  #Txt_Ville
  #Str_Magasin
  #Str_Rayon
  #Str_Nom_Produit
  #Btn_Nouveau
  #Btn_Maj
  #Btn_Supprimer
  #Btn_Sauvegarder
  #Btn_Quitter
  #Txt_Nb_Enreg
EndEnumeration

Enumeration Polices
  #Police
  #Police2
  #Police_Txt
EndEnumeration

;Structure d'un produit
Structure Produit
  Magasin.s
  Rayon.s
  Produit.s
EndStructure

Global.l Evenement

;Création d'une liste vierge pour les produits
Global NewList produits.produit()
Global$ FichierJson = "D:\Programmation\Donnees\produits_achats.json"

Declare Quitter()
Declare Programme_principal()
Declare Charger_produits()
Declare GestionEvenements()
Declare Nouveauproduit()
Declare Selectionproduit()  
Declare Supprimerproduit()
Declare Majproduit()
Declare Sauvegardeproduits()

LoadFont(#Police, "Cambria", 16, #PB_Font_Bold)
LoadFont(#Police_Txt, "A_Nefel_Botan", 10, #PB_Font_Bold)
LoadFont(#Police2, "FontAwesome", 18, #PB_Font_Bold)

Programme_principal()

Macro TrierListeStruc(_NomListe_, _Options_, _Champ_Structure_)
  ; Cette macro simplifie l'utilisation de la fonction intégrée SortStructuredList().
  SortStructuredList(_NomListe_, _Options_, OffsetOf(_Champ_Structure_), TypeOf(_Champ_Structure_))
EndMacro

Procedure Quitter()
  CloseWindow(#Fenetre_edition)
  End
EndProcedure
Procedure Programme_principal()
  If OpenWindow(#Fenetre_edition, 767, 175, 520, 500, "Base de données", #PB_Window_TitleBar|#PB_Window_ScreenCentered)
    SetWindowColor(#Fenetre_edition, $F8BFB8)
    SetGadgetFont(#PB_Default, FontID(#Police))
    ListIconGadget(#Liste_produits, 10, 10, WindowWidth(#Fenetre_edition)-20, 260, "Rayon", 130, #PB_ListIcon_FullRowSelect|#PB_ListIcon_AlwaysShowSelection|#PB_ListIcon_HeaderDragDrop)
    AddGadgetColumn(#Liste_produits, 1, "Produit", 130)
    AddGadgetColumn(#Liste_produits, 2, "Nom", 220)
    TextGadget(#Txt_Magasin, 10, 280, 140, 25, "Magasin", #PB_Text_Right)
    TextGadget(#Txt_Rayon, 10, 310, 140, 25, "Rayon", #PB_Text_Right)
    TextGadget(#Txt_Nom_Produit, 10, 340, 140, 25, "Nom produit", #PB_Text_Right)
    StringGadget(#Str_Magasin, 160, 280, 350, 25, "")
    StringGadget(#Str_Rayon, 160, 310, 350, 25, "")
    StringGadget(#Str_Nom_Produit, 160, 340, 350, 25, "")
    ButtonGadget(#Btn_Nouveau, 10, 400, 130, 40, "Nouveau")
    ButtonGadget(#Btn_Maj, 200, 400, 130, 40, "Mise à jour")
    ButtonGadget(#Btn_Supprimer, 380, 400, 130, 40, "Supprimer")
    ButtonGadget(#Btn_Sauvegarder, 10, 450, 130, 40, "Sauvegarder")
    ButtonGadget(#Btn_Quitter, 380, 450, 130, 40, "Quitter")
    TextGadget(#Txt_Nb_Enreg, 180, 460, 200, 25, "")
    
    ;Lectures des produits 
    Charger_produits()
    
    For i = #Btn_Nouveau To #Btn_Quitter
      SetGadgetFont(i, FontID(#Police2))
    Next i
    
    SetGadgetText(#Txt_Nb_Enreg, Str(ListSize(produits())) + " enregistrements")
    SetGadgetColor(#Txt_Nb_Enreg, #PB_Gadget_BackColor, GetWindowColor(#Fenetre_edition))
    
    For i = #Txt_Magasin To #Txt_Nom_Produit
      SetGadgetFont(i, FontID(#Police_Txt))
      SetGadgetFont(#Txt_Nb_Enreg, FontID(#Police_Txt))
      SetGadgetColor(i, #PB_Gadget_BackColor, GetWindowColor(#Fenetre_edition))
    Next i
    
    For i = #Str_Magasin To #Str_Nom_Produit
      SetGadgetFont(i, FontID(#Police_Txt))
      SetGadgetColor(i, #PB_Gadget_BackColor, $B8F7F8)
    Next i  
    
    For i = 0 To CountGadgetItems(#Liste_produits) ;ListIconGadget
      If i%2 = 1                                     ; si notre compteur est pair
        SetGadgetItemColor(#Liste_produits, i, #PB_Gadget_FrontColor, $0000FF)
        SetGadgetItemColor(#Liste_produits, i, #PB_Gadget_BackColor, $FFE8FF)
      Else ; sinon, s'il est impair
        SetGadgetItemColor(#Liste_produits, i, #PB_Gadget_FrontColor, $FF0000)
        SetGadgetItemColor(#Liste_produits, i, #PB_Gadget_BackColor, $FFE9E8)
      EndIf  
    Next i
    
    ;Contrôle de la saisie (Le Magasin ou la raison sociale est obligatoire)
    BindGadgetEvent(#Str_Magasin, @GestionEvenements())
    
    ;Mise en place d'un nouveau produit
    BindGadgetEvent(#Btn_Nouveau, @Nouveauproduit()) 
    
    ;Un produit est selectionné dans la liste
    BindGadgetEvent(#Liste_produits, @Selectionproduit())
    
    ;Ajout ou modification d'un produit
    BindGadgetEvent(#Btn_Maj, @Majproduit()) 
    
    ;Supression d'un produit
    BindGadgetEvent(#Btn_Supprimer, @Supprimerproduit()) 
    
    ;Fermeture de l'application et sauvegarde des produits
    BindGadgetEvent(#Btn_Sauvegarder, @Sauvegardeproduits())
    
    ;Quitter le programme sans sauvegarder
    BindEvent(#PB_Event_CloseWindow, @Quitter())
    BindGadgetEvent(#Btn_Quitter, @Quitter())
    
    DisableGadget(#Btn_Sauvegarder, #True)
    ;DisableGadget(#Btn_Nouveau, #False)
    
    Nouveauproduit()
    
    SetActiveGadget(#Str_Magasin)
  EndIf
EndProcedure

;Chargement des produits existants
Procedure Charger_produits()
  If ReadFile(#FichierJSON, FichierJson)
    CloseFile(#FichierJSON)
    
    ;Lecture du fichier JSON
    LoadJSON(#FichierJSON, FichierJson, #PB_JSON_NoCase)
    
    ;Extraction de la chaine JSON vers la liste chainée produits
    ExtractJSONList(JSONValue(#FichierJSON), produits())
    
    TrierListeStruc(produits(), #PB_Sort_Ascending, produit\Produit)
    TrierListeStruc(produits(), #PB_Sort_Ascending, produit\Rayon)
    TrierListeStruc(produits(), #PB_Sort_Ascending, produit\Magasin)
    
    ;Affichage de la liste des produits
    ForEach(produits())
      With produits()
        AddGadgetItem(#Liste_produits, -1, \Magasin + #LF$ + \Rayon + #LF$ + \Produit)
        SetGadgetItemData(#Liste_produits, CountGadgetItems(#Liste_produits)-1, ListIndex(produits()))
      EndWith                
    Next
    
  EndIf
EndProcedure

;Gestionnaire de contrôle de la saisie
Procedure GestionEvenements()
  Protected Evenement = EventType()
  
  Select Evenement
    Case #PB_EventType_Change
      If Trim(GetGadgetText(#Str_Magasin)) <> ""
        DisableGadget(#Btn_Nouveau, #True)
        DisableGadget(#Btn_Maj, #False)
        DisableGadget(#Btn_Sauvegarder, #False)
      Else
        DisableGadget(#Btn_Nouveau, #False)
        DisableGadget(#Btn_Maj, #True)
        DisableGadget(#Btn_Sauvegarder, #True)
      EndIf         
  EndSelect
  
EndProcedure

;Nouveau produit (Remise à zéro des champs de saisie)
Procedure Nouveauproduit()
  SetWindowData(#Fenetre_edition, 0) ;C'est une création
  
  SetGadgetText(#Str_Magasin, "")
  SetGadgetText(#Str_Rayon, "")
  SetGadgetText(#Str_Nom_Produit, "")
  
  DisableGadget(#Btn_Nouveau, #False)
  DisableGadget(#Btn_Maj, #True)
  DisableGadget(#Btn_Supprimer, #True)
  
  SetGadgetText(#Btn_Maj, Chr($F067))
  SetActiveGadget(#Str_Magasin)
EndProcedure

;Un produit est sélectionné dans la liste
Procedure Selectionproduit()  
  Protected Item = GetGadgetState(#Liste_produits)
  
  If Item <> -1
    SelectElement(produits(), GetGadgetItemData(#Liste_produits, Item))
    With produits()
      SetGadgetText(#Str_Magasin, \Magasin)
      SetGadgetText(#Str_Rayon, \Rayon)
      SetGadgetText(#Str_Nom_Produit, \Produit)
    EndWith  
  EndIf
  
  ;C'est une modification de produit
  SetWindowData(#Fenetre_edition, 1) 
  
  DisableGadget(#Btn_Nouveau, #False)
  DisableGadget(#Btn_Maj, #False)
  DisableGadget(#Btn_Supprimer, #False)
  
  SetGadgetText(#Btn_Maj, Chr($F040))
  SetActiveGadget(#Str_Magasin)
EndProcedure

;Suppression d'un produit
Procedure Supprimerproduit()
  If MessageRequester("Information", "Etes vous sûr de supprimer un produit ?" + #CRLF$ + "cette action est irrémédiable !", #PB_MessageRequester_YesNo) = #PB_MessageRequester_Yes
    SetWindowData(#Fenetre_edition, 3) ;C'est une suppression
    Majproduit()
  EndIf
EndProcedure

;Gestionnaire de mise à jour des produits 
Procedure Majproduit()
  Protected.s Magasin = GetGadgetText(#Str_Magasin)
  Protected.s Rayon = GetGadgetText(#Str_Rayon)
  Protected.s Nom_Produit  = GetGadgetText(#Str_Nom_Produit)
  
  DisableGadget(#Btn_Sauvegarder, 0)
  
  Select GetWindowData(#Fenetre_edition)
    Case 0 ;Création d'un produit
      AddElement(produits())
      With produits()
        \Magasin = Magasin
        \Rayon = Rayon
        \Produit = Nom_Produit
        AddGadgetItem(#Liste_produits, -1, \Magasin + #LF$ + \Rayon + #LF$ + \Produit)
        SetGadgetItemData(#Liste_produits, CountGadgetItems(#Liste_produits)-1, ListIndex(produits()))
      EndWith
      
    Case 1 ;Modification d'un produit
      With produits()
        \Magasin = Magasin
        \Rayon = Rayon
        \Produit = Nom_Produit
        SetGadgetItemText(#Liste_produits, ListIndex(produits()), \Magasin, 0)
        SetGadgetItemText(#Liste_produits, ListIndex(produits()), \Rayon, 1)
        SetGadgetItemText(#Liste_produits, ListIndex(produits()), \Produit, 2)
      EndWith
      Nouveauproduit()
      
    Case 3 ;Suppression d'un produit
      RemoveGadgetItem(#Liste_produits, ListIndex(produits()))
      DeleteElement(produits())
      
      ;Mise à jour des index de liaison ListIconGadget <-> produits()
      ForEach(produits())
        SetGadgetItemData(#Liste_produits, ListIndex(produits()), ListIndex(produits()))
      Next
      
  EndSelect
  
EndProcedure

;Sauvegarde automatique des produits à la fermeture de l'application
Procedure Sauvegardeproduits()
  
  ;Création d'un objet JSON
  CreateJSON(#FichierJSON)
  
  ;Insertion de la liste chainée "produits" dans l'objet JSON
  InsertJSONList(JSONValue(#FichierJSON), produits())
  
  ;Sauvegarde du fichier
  SaveJSON(#FichierJSON, FichierJson, #PB_JSON_PrettyPrint)
  
  MessageRequester("Information", "Le fichier " + #DQUOTE$ + GetFilePart(FichierJson) + #DQUOTE$ + " a été sauvegardé" + #LF$ + #LF$ + "et va se fermer", #PB_MessageRequester_Info)
  
  Quitter()
EndProcedure

;- Boucle
Repeat
  Evenement = WaitWindowEvent()
  Select Evenement
      
    Case #PB_Event_Gadget
      Select EventGadget()
        Case #Btn_Quitter
          Quitter()
      EndSelect
      
    Case #PB_Event_CloseWindow
      Select EventWindow()
        Case #Fenetre_edition
          Quitter()
          Break
      EndSelect
  EndSelect
ForEver
Microsoft Windows 10 Famille 64 bits : Carte mère : ASRock 970 Extreme3 R2.0 : Carte Graphique NVIDIA GeForce RTX 3080 : Processeur AMD FX 6300 6 cœurs 12 threads 3,50 GHz PB 5.73 PB 6.00 LTS (x64)
Un homme doit être poli, mais il doit aussi être libre !
Avatar de l’utilisateur
falsam
Messages : 7244
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: [TUTO débutants] les modules

Message par falsam »

@Micoute : En principe c'est un tutoriel sur les modules et ..... je ne vois pas de module.
Configuration : Windows 11 Famille 64-bit - PB 6.03 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Avatar de l’utilisateur
Micoute
Messages : 2522
Inscription : dim. 02/oct./2011 16:17
Localisation : 35520 La Mézière

Re: [TUTO débutants] les modules

Message par Micoute »

bonsoir falsam, tu as raison, mais c'est très facile a transformer en module, car les procédures sont déclarées donc le plus dur est déjà fait.
Microsoft Windows 10 Famille 64 bits : Carte mère : ASRock 970 Extreme3 R2.0 : Carte Graphique NVIDIA GeForce RTX 3080 : Processeur AMD FX 6300 6 cœurs 12 threads 3,50 GHz PB 5.73 PB 6.00 LTS (x64)
Un homme doit être poli, mais il doit aussi être libre !
Avatar de l’utilisateur
omega
Messages : 617
Inscription : sam. 26/nov./2011 13:04
Localisation : Alger

Re: [TUTO débutants] les modules

Message par omega »

Bonsoir à tous et merci à Micoute pour le partage, ton programme est magnifique et il m'intéresse beaucoup surtout en relation avec les structures et les bases de données, c'est super. Cependant, j'ai quelques questions importantes à poser (avant que je me décide pour mon nouveau programme commercial version 2018, conformément aux conseils de l'équipe..)
1. Est ce qu'il y a une limite en nombre d'enregistrements (ou en Mo) dans un fichier .Json? Si oui laquelle?
2.

Code : Tout sélectionner

InsertJSONList(JSONValue(#FichierJSON), produits())

3.

Code : Tout sélectionner

SaveJSON(#FichierJSON, FichierJson, #PB_JSON_PrettyPrint)
Quelle est la différence entre (2.) et (3.)?
4. Quelle est le type de bases de données préféré pour un logiciel de gestion commerciale?
Fichier.Data? Fichier.Json? .Sqlite?
Merci
Win7 (x64) 64 bits Pb 5.72
Avatar de l’utilisateur
Micoute
Messages : 2522
Inscription : dim. 02/oct./2011 16:17
Localisation : 35520 La Mézière

Re: [TUTO débutants] les modules

Message par Micoute »

Bonjour à tous,
pour qu'on voit bien la différence avec les modules, j'ai transformé le programme que j'ai posté plus haut en module, sinon à part les DeclareModule, Module et UseModule, je n'ai rien changé:

Code : Tout sélectionner

;Gestion Liste d'achats
; 13 avril 2018
; PB 5.70
; par Micoute

DeclareModule Remplissage
  
  Enumeration	Fichiers
    #FichierJSON
  EndEnumeration
  
  Enumeration Fenetres
    #Fenetre_edition
  EndEnumeration
  
  Enumeration	Gadgets
    #Liste_produits
    #Txt_Magasin
    #Txt_Rayon
    #Txt_Nom_Produit
    #Txt_CP
    #Txt_Ville
    #Str_Magasin
    #Str_Rayon
    #Str_Nom_Produit
    #Btn_Nouveau
    #Btn_Maj
    #Btn_Supprimer
    #Btn_Sauvegarder
    #Btn_Quitter
    #Txt_Nb_Enreg
  EndEnumeration
  
  Enumeration Polices
    #Police
    #Police2
    #Police_Txt
  EndEnumeration
  
  ;Structure d'un produit
  Structure Produit
    Magasin.s
    Rayon.s
    Produit.s
  EndStructure
  
  Global.l Evenement
  
  ;Création d'une liste vierge pour les produits
  Global NewList produits.produit()
  Global$ FichierJson = "D:\Programmation\Donnees\produits_achats.json"
  
  Declare Quitter()
  Declare Charger_produits()
  Declare GestionEvenements()
  Declare Nouveauproduit()
  Declare Selectionproduit()  
  Declare Supprimerproduit()
  Declare Majproduit()
  Declare Sauvegardeproduits()
  
  LoadFont(#Police, "Cambria", 16, #PB_Font_Bold)
  LoadFont(#Police_Txt, "A_Nefel_Botan", 10, #PB_Font_Bold)
  LoadFont(#Police2, "FontAwesome", 18, #PB_Font_Bold)
  
EndDeclareModule

Module Remplissage
  
  Macro TrierListeStruc(_NomListe_, _Options_, _Champ_Structure_)
    ; Cette macro simplifie l'utilisation de la fonction intégrée SortStructuredList().
    SortStructuredList(_NomListe_, _Options_, OffsetOf(_Champ_Structure_), TypeOf(_Champ_Structure_))
  EndMacro
  
  Procedure Quitter()
    CloseWindow(#Fenetre_edition)
    End
  EndProcedure
  
  ;Chargement des produits existants
  Procedure Charger_produits()
    If ReadFile(#FichierJSON, FichierJson)
      CloseFile(#FichierJSON)
      
      ;Lecture du fichier JSON
      LoadJSON(#FichierJSON, FichierJson, #PB_JSON_NoCase)
      
      ;Extraction de la chaine JSON vers la liste chainée produits
      ExtractJSONList(JSONValue(#FichierJSON), produits())
      
      TrierListeStruc(produits(), #PB_Sort_Ascending, produit\Produit)
      TrierListeStruc(produits(), #PB_Sort_Ascending, produit\Rayon)
      TrierListeStruc(produits(), #PB_Sort_Ascending, produit\Magasin)
      
      ;Affichage de la liste des produits
      ForEach(produits())
        With produits()
          AddGadgetItem(#Liste_produits, -1, \Magasin + #LF$ + \Rayon + #LF$ + \Produit)
          SetGadgetItemData(#Liste_produits, CountGadgetItems(#Liste_produits)-1, ListIndex(produits()))
        EndWith                
      Next
      
    EndIf
  EndProcedure
  
  ;Gestionnaire de contrôle de la saisie
  Procedure GestionEvenements()
    Protected Evenement = EventType()
    
    Select Evenement
      Case #PB_EventType_Change
        If Trim(GetGadgetText(#Str_Magasin)) <> ""
          DisableGadget(#Btn_Nouveau, #True)
          DisableGadget(#Btn_Maj, #False)
          DisableGadget(#Btn_Sauvegarder, #False)
        Else
          DisableGadget(#Btn_Nouveau, #False)
          DisableGadget(#Btn_Maj, #True)
          DisableGadget(#Btn_Sauvegarder, #True)
        EndIf         
    EndSelect
    
  EndProcedure
  
  ;Nouveau produit (Remise à zéro des champs de saisie)
  Procedure Nouveauproduit()
    SetWindowData(#Fenetre_edition, 0) ;C'est une création
    
    SetGadgetText(#Str_Magasin, "")
    SetGadgetText(#Str_Rayon, "")
    SetGadgetText(#Str_Nom_Produit, "")
    
    DisableGadget(#Btn_Nouveau, #False)
    DisableGadget(#Btn_Maj, #True)
    DisableGadget(#Btn_Supprimer, #True)
    
    SetGadgetText(#Btn_Maj, Chr($F067))
    SetActiveGadget(#Str_Magasin)
  EndProcedure
  
  ;Un produit est sélectionné dans la liste
  Procedure Selectionproduit()  
    Protected Item = GetGadgetState(#Liste_produits)
    
    If Item <> -1
      SelectElement(produits(), GetGadgetItemData(#Liste_produits, Item))
      With produits()
        SetGadgetText(#Str_Magasin, \Magasin)
        SetGadgetText(#Str_Rayon, \Rayon)
        SetGadgetText(#Str_Nom_Produit, \Produit)
      EndWith  
    EndIf
    
    ;C'est une modification de produit
    SetWindowData(#Fenetre_edition, 1) 
    
    DisableGadget(#Btn_Nouveau, #False)
    DisableGadget(#Btn_Maj, #False)
    DisableGadget(#Btn_Supprimer, #False)
    
    SetGadgetText(#Btn_Maj, Chr($F040))
    SetActiveGadget(#Str_Magasin)
  EndProcedure
  
  ;Suppression d'un produit
  Procedure Supprimerproduit()
    If MessageRequester("Information", "Etes vous sûr de supprimer un produit ?" + #CRLF$ + "cette action est irrémédiable !", #PB_MessageRequester_YesNo) = #PB_MessageRequester_Yes
      SetWindowData(#Fenetre_edition, 3) ;C'est une suppression
      Majproduit()
    EndIf
  EndProcedure
  
  ;Gestionnaire de mise à jour des produits 
  Procedure Majproduit()
    Protected.s Magasin = GetGadgetText(#Str_Magasin)
    Protected.s Rayon = GetGadgetText(#Str_Rayon)
    Protected.s Nom_Produit  = GetGadgetText(#Str_Nom_Produit)
    
    DisableGadget(#Btn_Sauvegarder, 0)
    
    Select GetWindowData(#Fenetre_edition)
      Case 0 ;Création d'un produit
        AddElement(produits())
        With produits()
          \Magasin = Magasin
          \Rayon = Rayon
          \Produit = Nom_Produit
          AddGadgetItem(#Liste_produits, -1, \Magasin + #LF$ + \Rayon + #LF$ + \Produit)
          SetGadgetItemData(#Liste_produits, CountGadgetItems(#Liste_produits)-1, ListIndex(produits()))
        EndWith
        
      Case 1 ;Modification d'un produit
        With produits()
          \Magasin = Magasin
          \Rayon = Rayon
          \Produit = Nom_Produit
          SetGadgetItemText(#Liste_produits, ListIndex(produits()), \Magasin, 0)
          SetGadgetItemText(#Liste_produits, ListIndex(produits()), \Rayon, 1)
          SetGadgetItemText(#Liste_produits, ListIndex(produits()), \Produit, 2)
        EndWith
        Nouveauproduit()
        
      Case 3 ;Suppression d'un produit
        RemoveGadgetItem(#Liste_produits, ListIndex(produits()))
        DeleteElement(produits())
        
        ;Mise à jour des index de liaison ListIconGadget <-> produits()
        ForEach(produits())
          SetGadgetItemData(#Liste_produits, ListIndex(produits()), ListIndex(produits()))
        Next
        
    EndSelect
    
  EndProcedure
  
  ;Sauvegarde automatique des produits à la fermeture de l'application
  Procedure Sauvegardeproduits()
    
    ;Création d'un objet JSON
    CreateJSON(#FichierJSON)
    
    ;Insertion de la liste chainée "produits" dans l'objet JSON
    InsertJSONList(JSONValue(#FichierJSON), produits())
    
    ;Sauvegarde du fichier
    SaveJSON(#FichierJSON, FichierJson, #PB_JSON_PrettyPrint)
    
    MessageRequester("Information", "Le fichier " + #DQUOTE$ + GetFilePart(FichierJson) + #DQUOTE$ + " a été sauvegardé" + #LF$ + #LF$ + "et va se fermer", #PB_MessageRequester_Info)
    
    Quitter()
  EndProcedure
  
EndModule

Procedure Programme_principal()
  UseModule Remplissage
  
  If OpenWindow(#Fenetre_edition, 767, 175, 520, 500, "Base de données", #PB_Window_TitleBar|#PB_Window_ScreenCentered)
    SetWindowColor(#Fenetre_edition, $F8BFB8)
    SetGadgetFont(#PB_Default, FontID(#Police))
    ListIconGadget(#Liste_produits, 10, 10, WindowWidth(#Fenetre_edition)-20, 260, "Rayon", 130, #PB_ListIcon_FullRowSelect|#PB_ListIcon_AlwaysShowSelection|#PB_ListIcon_HeaderDragDrop)
    AddGadgetColumn(#Liste_produits, 1, "Produit", 130)
    AddGadgetColumn(#Liste_produits, 2, "Nom", 220)
    TextGadget(#Txt_Magasin, 10, 280, 140, 25, "Magasin", #PB_Text_Right)
    TextGadget(#Txt_Rayon, 10, 310, 140, 25, "Rayon", #PB_Text_Right)
    TextGadget(#Txt_Nom_Produit, 10, 340, 140, 25, "Nom produit", #PB_Text_Right)
    StringGadget(#Str_Magasin, 160, 280, 350, 25, "")
    StringGadget(#Str_Rayon, 160, 310, 350, 25, "")
    StringGadget(#Str_Nom_Produit, 160, 340, 350, 25, "")
    ButtonGadget(#Btn_Nouveau, 10, 400, 130, 40, "Nouveau")
    ButtonGadget(#Btn_Maj, 200, 400, 130, 40, "Mise à jour")
    ButtonGadget(#Btn_Supprimer, 380, 400, 130, 40, "Supprimer")
    ButtonGadget(#Btn_Sauvegarder, 10, 450, 130, 40, "Sauvegarder")
    ButtonGadget(#Btn_Quitter, 380, 450, 130, 40, "Quitter")
    TextGadget(#Txt_Nb_Enreg, 180, 460, 200, 25, "")
    
    ;Lectures des produits 
    Charger_produits()
    
    For i = #Btn_Nouveau To #Btn_Quitter
      SetGadgetFont(i, FontID(#Police2))
    Next i
    
    SetGadgetText(#Txt_Nb_Enreg, Str(ListSize(produits())) + " enregistrements")
    SetGadgetColor(#Txt_Nb_Enreg, #PB_Gadget_BackColor, GetWindowColor(#Fenetre_edition))
    
    For i = #Txt_Magasin To #Txt_Nom_Produit
      SetGadgetFont(i, FontID(#Police_Txt))
      SetGadgetFont(#Txt_Nb_Enreg, FontID(#Police_Txt))
      SetGadgetColor(i, #PB_Gadget_BackColor, GetWindowColor(#Fenetre_edition))
    Next i
    
    For i = #Str_Magasin To #Str_Nom_Produit
      SetGadgetFont(i, FontID(#Police_Txt))
      SetGadgetColor(i, #PB_Gadget_BackColor, $B8F7F8)
    Next i  
    
    For i = 0 To CountGadgetItems(#Liste_produits) ;ListIconGadget
      If i%2 = 1                                   ; si notre compteur est pair
        SetGadgetItemColor(#Liste_produits, i, #PB_Gadget_FrontColor, $0000FF)
        SetGadgetItemColor(#Liste_produits, i, #PB_Gadget_BackColor, $FFE8FF)
      Else ; sinon, s'il est impair
        SetGadgetItemColor(#Liste_produits, i, #PB_Gadget_FrontColor, $FF0000)
        SetGadgetItemColor(#Liste_produits, i, #PB_Gadget_BackColor, $FFE9E8)
      EndIf  
    Next i
    
    ;Contrôle de la saisie (Le Magasin ou la raison sociale est obligatoire)
    BindGadgetEvent(#Str_Magasin, @GestionEvenements())
    
    ;Mise en place d'un nouveau produit
    BindGadgetEvent(#Btn_Nouveau, @Nouveauproduit()) 
    
    ;Un produit est selectionné dans la liste
    BindGadgetEvent(#Liste_produits, @Selectionproduit())
    
    ;Ajout ou modification d'un produit
    BindGadgetEvent(#Btn_Maj, @Majproduit()) 
    
    ;Supression d'un produit
    BindGadgetEvent(#Btn_Supprimer, @Supprimerproduit()) 
    
    ;Fermeture de l'application et sauvegarde des produits
    BindGadgetEvent(#Btn_Sauvegarder, @Sauvegardeproduits())
    
    ;Quitter le programme sans sauvegarder
    BindEvent(#PB_Event_CloseWindow, @Quitter())
    BindGadgetEvent(#Btn_Quitter, @Quitter())
    
    DisableGadget(#Btn_Sauvegarder, #True)
    ;DisableGadget(#Btn_Nouveau, #False)
    
    Nouveauproduit()
    
    SetActiveGadget(#Str_Magasin)
  EndIf
EndProcedure

Programme_principal()

;- Boucle
Repeat
  Evenement = WaitWindowEvent()
  Select Evenement
      
    Case #PB_Event_Gadget
      Select EventGadget()
        Case #Btn_Quitter
          Quitter()
      EndSelect
      
    Case #PB_Event_CloseWindow
      Select EventWindow()
        Case #Fenetre_edition
          Quitter()
          Break
      EndSelect
  EndSelect
ForEver
Microsoft Windows 10 Famille 64 bits : Carte mère : ASRock 970 Extreme3 R2.0 : Carte Graphique NVIDIA GeForce RTX 3080 : Processeur AMD FX 6300 6 cœurs 12 threads 3,50 GHz PB 5.73 PB 6.00 LTS (x64)
Un homme doit être poli, mais il doit aussi être libre !
Avatar de l’utilisateur
falsam
Messages : 7244
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: [TUTO débutants] les modules

Message par falsam »

@Micoute : je vais faire mon vilain. ^-^

Utiliser un module avec ce type d'application n'a aucun sens.

:idea: Un module est un ensemble cohérents d'outils et de composants éprouvés et réutilisables.

Exemple :
Je code un module 3D que je nomme 3DUltimate.pbi dans lequel je trouve les composants suivants :
- CreateCube()
- CreateTube()
- CreateMateriel()
- etc ...

Ce module aura son propre espace de fonctionnement. Les variables par exemple de ce module ne pourront pas interférer avec des variables de mêmes noms que tu pourras utiliser dans d'autres sources faisant appels à ce module.

■ ... dans d'autres sources faisant appels à ce module.
Voila l’intérêt de notre module : Il peut être utilisé avec n'importe quel source ayant besoin de ce type de fonction.

Code : Tout sélectionner

IncludeFile "3Dultimate.pbi"
UseModule 3D
3D::CreateCube()
C'est tout, c'est simple et facile à lire.
Configuration : Windows 11 Famille 64-bit - PB 6.03 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Avatar de l’utilisateur
falsam
Messages : 7244
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: [TUTO débutants] les modules

Message par falsam »

Une pensée subite : Je pense qu'on pourrait comparer un module à un framework.
Configuration : Windows 11 Famille 64-bit - PB 6.03 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Avatar de l’utilisateur
microdevweb
Messages : 1798
Inscription : mer. 29/juin/2011 14:11
Localisation : Belgique

Re: [TUTO débutants] les modules

Message par microdevweb »

Les modules sont comme les packages de java ou les espace de nom en c,c++,c#.

Il doivent donc être utiliser dans le même état d'esprit.
Windows 10 64 bits PB: 5.70 ; 5.72 LST
Work at Centre Spatial de Liège
Avatar de l’utilisateur
falsam
Messages : 7244
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: [TUTO débutants] les modules

Message par falsam »

Omega a écrit :Quelle est le type de bases de données préféré pour un logiciel de gestion commerciale?
Fichier.Data? Fichier.Json? .Sqlite?Merci
:idea: Mon conseil : JSON bien sur :mrgreen:

P.S. Ceci est une remarque ironique (La modération est prié de laisser ce PS)
Configuration : Windows 11 Famille 64-bit - PB 6.03 x64 - AMD Ryzen 7 - 16 GO RAM
Vidéo NVIDIA GeForce GTX 1650 Ti - Résolution 1920x1080 - Mise à l'échelle 125%
Répondre