Problème avec ComboBoxGadget

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
G-Rom
Messages : 3641
Inscription : dim. 10/janv./2010 5:29

Re: Problème avec ComboBoxGadget

Message par G-Rom »

Le code complet fait plus de 18 000 lignes, c'est un logiciel complet qui est opérationnel depuis plus de 6 ans mais il a été développé sous Pb4
...
Sans aucun problème, j'ai l'habitude de gérer les gros programmes et je sais où aller pour trouver l'adresse de l'erreur
C'est plus de la programmation, mais cela relève de la magie, c'est un forum de magicien qu'il te faut ^^

De toute façon, je vais oublier tout ça puisque personne n'a l'air de me croire ni de me comprendre...
C'est pas une question de te croire ou de te comprendre, c'est ton code qui est faux, exécute le en pas à pas, tu clear ton gadget après l'avoir rempli ( 3 x de suite au passage , dès fois 4 de mémoire... ) , c'est donc bien un problème de TON coté , pas de PB. il faut juste être pragmatique.

Ton logiciel n'est pas bien gros. en 24H tu peu re-codé cela proprement. étudie les codes que je t'ai donner.
boby
Messages : 261
Inscription : jeu. 07/juin/2007 22:54

Re: Problème avec ComboBoxGadget

Message par boby »

Les variables sont déclarées en Global, est ce une erreur ?
Si tu place EnableExplicite au début de ton code, ça veux dire que TOUTES tes variables devront être déclaré, si en ajoutant EnableExplicite, ton code ne compile plus, c'est que tu as des variables non déclarées. Il y a donc dans ton code des variables que tu n'as pas déclaré.
Juste une question: Quelle est l'utilité de EnableExplicite (par rapport aux déclarations en Global) ? J'ai lu l'aide mais je ne vois pas vraiment la différence avec Global.
EnableExplicite n'est pas une façon de déclarer une variable, c'est UNE ligne à placer au début de ton code qui forcera le compiler à vérifier que toutes tes variable on bien été déclaré, si non, il te pointera du doigt quelle variable ne l'est pas.
C'est la première fois que je vois ça, G-Rom aussi m'a conseillé cette méthode (bindevent) je vais essayer de l'appliquer et la comprendre d'abords
Si ton code a été entamé en PB 4.xx, la gestion des events via BindEvent/BindGadgetEvent n'existait pas encore. Tu devrais en effet y jetter un oeuil.
C'est pour éviter les conflits: une variable déclarée en global garde sa valeur dans tout le programme.
Une variable déclarée en static à l'intérieur d'une procédure gardera également sa valeur, sauf qu'elle ne pouras être utilisée QUE à l'intérieur de cette procédure, ça évite donc d'appeler une mauvaise variable involontairement !
C'est quoi un module? (includefile?)
https://www.purebasic.com/french/docume ... odule.html
Pour faire simple, ce qui est compris dans ta section declaremodule est accécible par tout ton programme (même les autres modules).
Tout ce qui n'est PAS déclaré dans ton declaremodule n'est accécible QUE dans ton module. Du coup tu peux avoir 2 modules avec exactement les même nom de variable, elle ne se confondrons pas.
Ca te permet également d'avoir des feuilles de code clair et lisible (Je suis sur un code d'actuelement 2600 lignes, découpé en 15 modules, mon plus gros module fait 300 lignes... Facile comme tout à lire (bien plus que 10K lignes à la chaine).

Pour ce qui est du bug, peut être qu'il y a effectivement quelquechose (et je dit bien peut être) la question n'est pas la, avec des exemples simple, on arrive pas à provoquer ton bug, avec un code plus propre, tu n'aurais probablement plus ce bug.
Dernière modification par boby le mer. 15/août/2018 13:02, modifié 2 fois.
boby
Messages : 261
Inscription : jeu. 07/juin/2007 22:54

Re: Problème avec ComboBoxGadget

Message par boby »

Petit exemple qui montre qu'un module permet de bien séparer ses variable du reste de son code :

Code : Tout sélectionner

DeclareModule Module1
  Global valeur
EndDeclareModule
DeclareModule Module2
  Global valeur
EndDeclareModule

Module Module1
  valeur = 1
  Module2::valeur = 2
EndModule
Module Module2
  Debug valeur
  Debug Module1::valeur
EndModule
(L'idée étant en effet d'avoir une feuille de déclaremodule, puis chaques module dans une feuille de code séparé, le tout appelé via includefile.)
Avatar de l’utilisateur
microdevweb
Messages : 1802
Inscription : mer. 29/juin/2011 14:11
Localisation : Belgique

Re: Problème avec ComboBoxGadget

Message par microdevweb »

J'ai également rélalisé de gros soft en Pb par exemple un gestion compète d'union professionnel (16649 lignes) d'après le compilateur.

Il comprend beaucoup de ligne parce que j'utilise des module (de ma conception) pour l'affichage dans une système de table liée directement à la db (974 lignes) et un Rad qui se charge de gérer automatiquement les fenêtre fiche et table pour les données. Le but étant que ces modules sont facilement réutilisable.

Note: Les fenêtre sont crées avec les dialog

Exemple de création de toutes les fenêtres

Code : Tout sélectionner

Procedure MakeForm()
    ;{ pays
    paysFic=FicForm::New("pays","Nouveau pays","Edition d'une pays")
    paysFic\AddGadget("nom")
    paysFic\SetSize(300,0,0,0)
    
    paysTab=TabForm::New("pays","Liste des pays",300,600,paysFic)
    paysTab\AddColumn("nom",1,TabForm::#ShearchOn)
    paysTab\SetOrder("pays.nom")
    ;}
    ;{ Localités
    localiteFic=FicForm::New("localite","Nouvelle localité","Edition d'une loclaité")
    localiteFic\AddGadget("id_pays",0,paysTab)
    localiteFic\AddGadget("nom")
    localiteFic\AddGadget("code")
    localiteFic\SetSize(300,0,0,0)
    
    localiteTab=TabForm::New("localite","Liste des localités",800,600,localiteFic)
    localiteTab\AddColumn("id_pays",0.5,TabForm::#FiltersOn)
    localiteTab\AddColumn("nom",0.5,TabForm::#ShearchOn)
    localiteTab\SetOrder("pays.nom,localite.nom")
    ;}
    ;{ Catégories
    categorieFic=FicForm::New("categorie","Nouvelle catégorie","Edition d'une catégorie")
    categorieFic\AddGadget("nom")
    categorieFic\SetSize(300,0,0,0)
    
    categorieTab=TabForm::New("categorie","Liste des catégories",300,600,categorieFic)
    categorieTab\AddColumn("nom",1,TabForm::#ShearchOn)
    categorieTab\SetOrder("categorie.nom")
    ;}
    ;{ membre
    membreFic=FicForm::New("membre","Nouveau membre","Edition d'une membre",2)
    membreFic\AddGadget("id_categorie",2,categorieTab)
    membreFic\AddGadget("numero")
    membreFic\AddGadget("nom")
    membreFic\AddGadget("adresse",2)
    membreFic\AddGadget("id_localite",2,localiteTab)
    membreFic\AddGadget("actifOn",2)
    membreFic\AddGadget("email",2)
    membreFic\AddGadget("telephone")
    membreFic\AddGadget("gsm")
    membreFic\AddGadget("note",2)
    membreFic\SetSize(400,0,0,0)
    membreFic\AddCallback(@EventOpenMembreFic(),FicForm::#AfterOpen)
    
    membreTab=TabForm::New("membre","Liste des membres",800,600,membreFic)
    membreTab\AddColumn("id_categorie",0.3,TabForm::#FiltersOn)
    membreTab\AddColumn("numero",0.15,TabForm::#ShearchOn|TabForm::#AlignToRight)
    membreTab\AddColumn("nom",0.55,TabForm::#ShearchOn)
    membreTab\SetOrder("membre.numero")
    ;}
    ;{ communes
    communeFic=FicForm::New("commune","Nouvelle commune","Edition d'une commune",2)
    communeFic\AddGadget("nom",2)
    communeFic\AddGadget("adresse",2)
    communeFic\AddGadget("id_localite",2,localiteTab)
    communeFic\AddGadget("contact",2)
    communeFic\AddGadget("telephone")
    communeFic\AddGadget("gsm")
    communeFic\AddGadget("email",2)
    communeFic\AddGadget("entete",2)
    communeFic\AddGadget("grilleRetour",2)
    communeFic\AddGadget("note",2)
    communeFic\SetSize(400,0,0,0)
    
    communeTab=TabForm::New("commune","Liste des communes",800,600,communeFic)
    communeTab\AddColumn("id_localite",0.5,TabForm::#FiltersOn)
    communeTab\AddColumn("nom",0.5,TabForm::#ShearchOn)
    communeTab\SetOrder("localite.nom,commune.nom")
    ;}
    ;{ emplacement
    EmplacementFic=FicForm::New("emplacement","Nouvelle emplacement","Edition d'un emplacement",2)
    EmplacementFic\AddGadget("id_commune",2,communeTab)
    EmplacementFic\AddGadget("id_jour",2)
    EmplacementFic\SetOrderClauseLinkedColumn("ORDER BY id")
    EmplacementFic\AddGadget("nom",2)
    EmplacementFic\AddGadget("prix",2)
    EmplacementFic\AddGadget("occasionnel")
    EmplacementFic\AddGadget("actifOn")
    EmplacementFic\AddGadget("note",2)
    EmplacementFic\SetSize(300,0,0,0)
    EmplacementFic\AddCallback(@EventOpenEmplacementFic(),FicForm::#AfterOpen)
    
    EmplacementTab=TabForm::New("emplacement","Liste des emplacements",800,600,EmplacementFic)
    EmplacementTab\AddColumn("id_commune",0.4,TabForm::#FiltersOn)
    EmplacementTab\AddColumn("nom",0.4,TabForm::#ShearchOn)
    EmplacementTab\AddColumn("prix",0.15,TabForm::#AlignToRight)
    EmplacementTab\SetOrder("commune.nom,emplacement.nom")
    ;}
    ;{ cotisation
    CotisationFic=FicForm::New("cotisation","Nouvelle cotisation","Edition d'une cotisation")
    CotisationFic\SetSize(400,0,0,0)
    CotisationFic\AddGadget("nom")
    CotisationFic\AddGadget("id_categorie",0,categorieTab)
    CotisationFic\AddGadget("id_mois")
    CotisationFic\AddGadget("id_annee")
    CotisationFic\AddGadget("montant")
    
    CotisationTab=TabForm::New("cotisation","Liste des cotisations",800,600,CotisationFic)
    CotisationTab\AddColumn("nom",0.2)
    CotisationTab\AddColumn("id_mois",0.2)
    CotisationTab\AddColumn("id_annee",0.2)
    CotisationTab\AddColumn("id_categorie",0.2)
    CotisationTab\AddColumn("montant",0.2,TabForm::#AlignToRight)
    ;}
    ;{ Sortie de caisse
    SortieFic=FicForm::New("sortie_caisse","Nouvelle sortie","Edition d'une sortie")
    SortieFic\AddGadget("date")
    SortieFic\AddGadget("beneficiaire")
    SortieFic\AddGadget("montant")
    SortieFic\AddGadget("note")
    SortieFic\SetSize(300,0,0,0)
    SortieFic\AddCallback(@ValideSortieCaisse(),FicForm::#BeforeValide)
    
    SortieTab=TabForm::New("sortie_caisse","Liste des sorties de caisse",800,600,SortieFic)
    SortieTab\AddColumn("date",0.3)
    SortieTab\AddColumn("beneficiaire",0.4,TabForm::#ShearchOn)
    SortieTab\AddColumn("montant",0.3,TabForm::#AlignToRight)
    ;}
    
  EndProcedure
Image

Image

Image

Le soft est réaliser de façon modulaire et mon plus gros fichier ne comprend moins de 1000 lignes.

Au point de vue du main je n'est aucune variable globale. Les seul variable global que j'utilise sont interne à un module et tu verra ci-dessous qu'il est tout petit.

Main

Code : Tout sélectionner

;*************************************************************************************************************************************************
; AUTHOR       : Bielen Pierre
; PROJECT NAME : UDF
; VERSION      : 5.46
;-* Version history
;{ Version 5.1
; ADD: Solde initial des membres
; ADD: Saisie d'une encaisse
;}
;{ Version 5.41
; ADD: To preferences --> Solde de caisse
; 
;}
;{ Version 5.43
; BUGS FIXED
;}
;{ Version 5.46
; UTILITAIRE DE SUPPRESSION DE FACTURE VIDE
;}
;}
;*************************************************************************************************************************************************
;-* RAD include
IncludePath "C:\Users\microdevweb\OneDrive\PB projet\RAD"
XIncludeFile "DB.pbi"
XIncludeFile "TBL.pbi"
XIncludeFile "RAD.pbi"
XIncludeFile "FicForm.pbi"
XIncludeFile "TabForm.pbi"
; Gestion de caisse
IncludePath "C:\Users\microdevweb\OneDrive\PB projet\UDF_5_47\caisse_management"
XIncludeFile "Membre_caisse.pbi"
;-* PROJECT include
IncludePath "C:\Users\microdevweb\OneDrive\PB projet\UDF_5_47"
XIncludeFile "PRINT_PREVIEW.pbi"
XIncludeFile "prj.pbi"
XIncludeFile "preferences.pbi"
XIncludeFile "Backup.pbi"
XIncludeFile "Form.pbi"
XIncludeFile "PrintGrille.pbi"
XIncludeFile "seance.pbi"
XIncludeFile "placement.pbi"
XIncludeFile "FacAuto.pbi"
XIncludeFile "LgnFacFic.pbi"
XIncludeFile "FactureFic.pbi"
XIncludeFile "FacPrint.pbi"
XIncludeFile "ImpFacture.pbi"
XIncludeFile "FacForm.pbi"
XIncludeFile "lettre_commune.pbi"
XIncludeFile "MultiAdd.pbi"
XIncludeFile "SOMMES_DUES.pbi"
XIncludeFile "CAISSE.pbi"
XIncludeFile "SOLDE_CAISSE.pbi"
XIncludeFile "DIFF_CAISSE.pbi"
XIncludeFile "DeleteEmptyFac.pbi"
XIncludeFile "deplaceLignesFacture.pbi"
XIncludeFile "RenuFac.pbi"


IncludePath "C:\Users\microdevweb\OneDrive\PB projet\UDF_5_47\caisse_management"
XIncludeFile "caisse_tab.pbi"

IncludePath "C:\Users\microdevweb\OneDrive\PB projet\UDF_5_47"
XIncludeFile "MainForm.pbi"
;- Génération de la base de données
prj::MakeDb()
;- Génération des fenêtres
form::MakeForm()
;- Lecture des préférences
prj::LitPreferences()
;- Génération de la mise en page des factures
FacPrint::Load()
; Mise à jour de version
prj::UpdateVersion()
;- Ouverture de la fenêtre principale
MainForm::Open()

Repeat
  WaitWindowEvent()
ForEver 


Mon avis est que plus le soft est gros et plus il doit être structuré. Et j'avoue que si devais refaire ce soft je le ferais de manière complètement différente en séparant le moteur (model) de l'interface utilisateur.

Code de la gestion auto des fenêtres fiches

Code : Tout sélectionner

; *******************************************************************************************************************************************************
; AUTHOR        : MicrodevWeb
; PROJECT NAME  : RAD
; CLASS NAME    : FicForm
; VERSION       : 1
; REQUIERED     : PB 5.60
; *******************************************************************************************************************************************************
DeclareModule FicForm
  ;======================================================================================================================================================
  ;-* PUBLIC CONSTANTE
  ; -----------------------------------------------------------------------------------------------------------------------------------------------------
  EnumerationBinary 
    #ModeEdit
  EndEnumeration
  EnumerationBinary 
    #GadgetHide
  EndEnumeration
  EnumerationBinary
    #BeforeValide
    #AfterValide
    #BeforeOpen
    #AfterOpen
    #BeforeClose
    #AfterClose
  EndEnumeration
  ;}-----------------------------------------------------------------------------------------------------------------------------------------------------
  ;======================================================================================================================================================
  ;-* PUBLIC INTERFACE
  ; -----------------------------------------------------------------------------------------------------------------------------------------------------
  
  ;}-----------------------------------------------------------------------------------------------------------------------------------------------------
  ;======================================================================================================================================================
  ;-* PUBLIC PROTOTYPES
  ; -----------------------------------------------------------------------------------------------------------------------------------------------------
  Declare New(TableName.s,TitleNew.s,TitleEdit.s,NumberColumn=1)
  ;}-----------------------------------------------------------------------------------------------------------------------------------------------------
EndDeclareModule
Module FicForm
  EnableExplicit
  UseSQLiteDatabase()
  ;======================================================================================================================================================
  ;-* PRIVATE macro
  ; -----------------------------------------------------------------------------------------------------------------------------------------------------
  Macro mError(FunctionName,Message,ValReturn)
    MessageRequester("FormFic Error ("+FunctionName+")",Message,#PB_MessageRequester_Error)
    ProcedureReturn ValReturn
  EndMacro
  ;}-----------------------------------------------------------------------------------------------------------------------------------------------------
  ;======================================================================================================================================================
  ;-* PRIVATE CONSTANTE
  ; -----------------------------------------------------------------------------------------------------------------------------------------------------
  ;}-----------------------------------------------------------------------------------------------------------------------------------------------------
  ;======================================================================================================================================================
  ;-* PRIVATE STRUCTURES
  ; -----------------------------------------------------------------------------------------------------------------------------------------------------
  Structure sGadget
    name.s
    NumberColumnMerged.l
    NumberDecimal.l
    *TabForm.RAD::_TabForm
    flag.l
    Value.s
    OrderClause.s
  EndStructure
  Structure sLinkedData
    columnId.s
    columnLinked.s
    TableLinked.s
    IdLink.s
    StrangerColumn.s
  EndStructure
  Structure sCallback
    *callBack
    flag.l
  EndStructure
  Structure sFic
    *VPROC
    IdForm.l
    FormFlag.l
    Flag.l
    List myGadget.sGadget()
    List myLinkedData.sLinkedData()
    NumberColumn.l
    TitleNew.s
    TitleEdit.s
    minWidth.l
    minHeight.l
    maxHeight.l
    maxWidth.l
    motherWindow.l
    *callBack
    List myCallBack.sCallback()
    TableName.s
    CurrentRecord.l
    *From
    x.l
    y.l
  EndStructure
  ;}-----------------------------------------------------------------------------------------------------------------------------------------------------
  ;======================================================================================================================================================
  ;-* PRIVATE VARIABLES
  ; -----------------------------------------------------------------------------------------------------------------------------------------------------
  Global Font=LoadFont(#PB_Any,"Arial",11,#PB_Font_HighQuality)
  Global *gCurrentForm=-1,*gCurrentGadget=-1
  ;}-----------------------------------------------------------------------------------------------------------------------------------------------------
  ;======================================================================================================================================================
  ;-* PRIVATE PROTOTYPES
  ; -----------------------------------------------------------------------------------------------------------------------------------------------------
  Declare FillCombo(*This.sFic)
  Declare SelectedComboById(*This.sFic,idRec)
  Declare UpdateLinkedData(*This.sFic,id)
  Declare CallCallback(*This.sFic,flag.l)
  ;}-----------------------------------------------------------------------------------------------------------------------------------------------------
  ;======================================================================================================================================================
  ;-* PRIVATE FUNCTIONS
  ; -----------------------------------------------------------------------------------------------------------------------------------------------------
  Procedure.s GetFormFlag(*This.sFic)
    Protected txt.s
    With *This
      If \FormFlag&#PB_Window_SystemMenu=#PB_Window_SystemMenu
        If txt<>""
          txt+"|"
        EndIf
        txt+"#PB_Window_SystemMenu"
      EndIf
      If \FormFlag&#PB_Window_ScreenCentered=#PB_Window_ScreenCentered
        If txt<>""
          txt+"|"
        EndIf
        txt+"#PB_Window_ScreenCentered"
      EndIf
      If \FormFlag&#PB_Window_Maximize=#PB_Window_Maximize
        If txt<>""
          txt+"|"
        EndIf
        txt+"#PB_Window_Maximize"
      EndIf
      If \FormFlag&#PB_Window_Minimize=#PB_Window_Minimize
        If txt<>""
          txt+"|"
        EndIf
        txt+"#PB_Window_Minimize"
      EndIf
      If \FormFlag&#PB_Window_MinimizeGadget=#PB_Window_MinimizeGadget
        If txt<>""
          txt+"|"
        EndIf
        txt+"#PB_Window_MinimizeGadget"
      EndIf 
      If \FormFlag&#PB_Window_MaximizeGadget=#PB_Window_MaximizeGadget
        If txt<>""
          txt+"|"
        EndIf
        txt+"#PB_Window_MaximizeGadget"
      EndIf 
      If \FormFlag&#PB_Window_SizeGadget=#PB_Window_SizeGadget
        If txt<>""
          txt+"|"
        EndIf
        txt+"#PB_Window_SizeGadget"
      EndIf 
      If \FormFlag&#PB_Window_SizeGadget=#PB_Window_SizeGadget
        If txt<>""
          txt+"|"
        EndIf
        txt+"#PB_Window_SizeGadget"
      EndIf
      If \FormFlag&#PB_Window_WindowCentered=#PB_Window_WindowCentered
        If txt<>""
          txt+"|"
        EndIf
        txt+"#PB_Window_WindowCentered"
      EndIf
      If \FormFlag&#PB_Window_Invisible=#PB_Window_Invisible
        If txt<>""
          txt+"|"
        EndIf
        txt+"#PB_Window_Invisible"
      EndIf
      If \FormFlag&#PB_Window_BorderLess=#PB_Window_BorderLess
        If txt<>""
          txt+"|"
        EndIf
        txt+"#PB_Window_BorderLess"
      EndIf
      If \FormFlag&#PB_Window_TitleBar=#PB_Window_TitleBar
        If txt<>""
          txt+"|"
        EndIf
        txt+"#PB_Window_TitleBar"
      EndIf
      If \FormFlag&#PB_Window_NoGadgets=#PB_Window_NoGadgets
        If txt<>""
          txt+"|"
        EndIf
        txt+"#PB_Window_NoGadgets"
      EndIf
      If \FormFlag&#PB_Window_NoActivate=#PB_Window_NoActivate
        If txt<>""
          txt+"|"
        EndIf
        txt+"#PB_Window_NoActivate"
      EndIf
      If \FormFlag&#PB_Window_Invisible=#PB_Window_Invisible
        If txt<>""
          txt+"|"
        EndIf
        txt+"#PB_Window_Invisible"
      EndIf
      If \motherWindow<>-1
        If txt<>""
          txt+"|"
        EndIf
        txt+"#PB_Window_WindowCentered"
      Else
        txt+"#PB_Window_ScreenCentered"
      EndIf
    EndWith
    ProcedureReturn  txt
  EndProcedure
  Procedure.s MakeXml(*This.sFic)
    Protected myXml.s,n,title.s,k
    With *This  
      myXml="<window name='"+\TableName+"'"
      If \minWidth
        myXml+" width='"+\minWidth+"'"
      Else
        myXml+" width='auto'"
      EndIf
      If \minHeight
        myXml+" height='"+\minHeight+"'"
      Else
        myXml+" height='auto'"
      EndIf
      If \maxWidth
        myXml+" maxwidth='"+\maxWidth+"'" 
      EndIf
      If \maxHeight
        myXml+" maxheight ='"+\maxheight +"'" 
      EndIf
      If \Flag & #ModeEdit
        title=\TitleEdit
      Else
        title=\TitleNew
      EndIf
      myXml+" text="+Chr(34)+title+Chr(34)
      myXml+" flags='"+GetFormFlag(*This)+"'>"
      myXml+Chr(10)
      myXml+"<vbox expand='yes'>"
      myXml+Chr(10)
      ForEach \myGadget()
        If Not \myGadget()\flag & #GadgetHide
          k+1
          If n>=\NumberColumn
            n=0
          EndIf
          n+1
          If n=1
            myXml+"<gridbox columns='"+\NumberColumn+"'>"
            myXml+Chr(10)
          EndIf
          myXml+"<vbox expand='yes'"
          If \myGadget()\NumberColumnMerged
            myXml+" colspan='"+\myGadget()\NumberColumnMerged+"'"
            n+\myGadget()\NumberColumnMerged-1
          EndIf
          myXml+">"+Chr(10)
          myXml+"<text name='LB__"+\myGadget()\name+"' text="+Chr(34)+DB::GetLabelColumn(\TableName,\myGadget()\name)+Chr(34)+"/>"+Chr(10)
          Select DB::GetTypeOfColumn(\TableName,\myGadget()\name)
            Case DB::#Type_Text,DB::#Type_Phone,DB::#Type_Email,DB::#Type_Euro,DB::#Type_Float,DB::#Type_Percentage
              myXml+"<string name='"+\myGadget()\name+"'/>"+Chr(10)  
            Case DB::#Type_Integer
              myXml+"<string name='"+\myGadget()\name+"' flags='#PB_String_Numeric'/>"+Chr(10)  
            Case DB::#Type_Note
              myXml+"<editor name='"+\myGadget()\name+"' height='60'/>"+Chr(10)  
            Case DB::#Type_Link
              If \myGadget()\TabForm<>-1
                myXml+"<hbox expand='item:1'>"+Chr(10)
                myXml+"<combobox name='"+\myGadget()\name+"'/>"+Chr(10)
                myXml+"<button name='BTSEL_"+\myGadget()\name+"' width='30' text='...' />"+Chr(10)
                myXml+"</hbox>"+Chr(10)
              Else
                myXml+"<combobox name='"+\myGadget()\name+"'/>"+Chr(10)
              EndIf
            Case DB::#Type_Date
              myXml+"<date name='"+\myGadget()\name+"' text='%dd-%mm-%yyyy'/>"+Chr(10)  
            Case DB::#Type_Checkbox
              myXml+"<checkbox name='"+\myGadget()\name+"'/>"+Chr(10) 
          EndSelect
          myXml+"</vbox>"+Chr(10)
          If n>=\NumberColumn Or k=ListSize(\myGadget())
            myXml+"</gridbox>"+Chr(10)
          EndIf
        EndIf
      Next
      myXml+"<hbox expand='no'>"+Chr(10)
      myXml+"<button name='bt_validate' text='Valider' />"+Chr(10)
      myXml+"<button name='bt_chancel' text='Annuler'  />"+Chr(10)
      myXml+"</hbox>"
      myXml+"</vbox>"+Chr(10)
      myXml+"</window>"
;             CreateFile(0,"teste.xml")
;             WriteString(0,myXml)
;             CloseFile(0)
      ProcedureReturn myXml
    EndWith
  EndProcedure
  Procedure SelectMyForm()
    Protected *Form=GetWindowData(EventWindow())
    ProcedureReturn *Form
  EndProcedure
  Procedure RefreshCombo(id)
    Protected *This.sFic
    Protected idG
    If *gCurrentForm=-1 Or *gCurrentGadget=-1
      ProcedureReturn 
    EndIf
    *This=*gCurrentForm
    With *This
      SetActiveWindow(DialogWindow(\IdForm))
      ChangeCurrentElement(\myGadget(),*gCurrentGadget)
      FillCombo(*This)
      SelectedComboById(*This,id)
      If NextElement(\myGadget())
        idG=DialogGadget(\IdForm,\myGadget()\name)
        SetActiveGadget(idG)
      EndIf
      *gCurrentGadget=-1
      *gCurrentForm=-1
    EndWith
  EndProcedure
  Procedure EventSelect()
    Protected *This.sFic=SelectMyForm()
    Protected *id,idForm
    With *This
      *gCurrentForm=*This
      *id=GetGadgetData(EventGadget())
      idForm=DialogWindow(\IdForm)
      *gCurrentGadget=*id
      ChangeCurrentElement(\myGadget(),*id)
      \myGadget()\TabForm\Open(idForm,RAD::#SelectMode,@RefreshCombo())
    EndWith
  EndProcedure
  Procedure EventMask()
    Protected *This.sFic=SelectMyForm()
    With *This
      ChangeCurrentElement(\myGadget(),GetGadgetData(EventGadget()))
      Select DB::GetTypeOfColumn(\TableName,\myGadget()\name)
        Case DB::#Type_Percentage
          RAD::MaskingString(EventGadget(),4,2," %")
        Case DB::#Type_Euro
          RAD::MaskingString(EventGadget(),4,2," €")
        Case DB::#Type_Float
          RAD::MaskingString(EventGadget(),4,2)
        Case DB::#Type_Phone
          RAD::MaskingString(EventGadget(),5)
      EndSelect
    EndWith
  EndProcedure
  Procedure Exit()
    Protected *This.sFic=SelectMyForm()
    With *This
      CallCallback(*This,#BeforeClose)
      CloseWindow(DialogWindow(\IdForm))
      FreeDialog(\IdForm)
      If \motherWindow<>-1
        DisableWindow(\motherWindow,#False)
        SetActiveWindow(\motherWindow)
      EndIf
      CallCallback(*This,#AfterClose)
      CloseDatabase(#PB_All)
    EndWith
  EndProcedure
  Procedure SelectMyList()
    Protected *This.sFic=SelectMyForm()
    With *This
      
    EndWith
  EndProcedure
  Procedure VerifNotNull(*This.sFic)
    Protected idG
    With *This
      ForEach \myGadget()
        If IsGadget(DialogGadget(\IdForm,"LB__"+\myGadget()\name))
          SetGadgetColor(DialogGadget(\IdForm,"LB__"+\myGadget()\name),#PB_Gadget_FrontColor,#PB_Default)
        EndIf
      Next
      ForEach \myGadget()
        If Not \myGadget()\flag & #GadgetHide
          idG=DialogGadget(\IdForm,\myGadget()\name)
          If DB::GetFlagOfColumn(\TableName,\myGadget()\name) & DB::#Not_Null
            Select DB::GetTypeOfColumn(\TableName,\myGadget()\name)
              Case DB::#Type_Text,DB::#Type_Note,DB::#Type_Phone
                If GetGadgetText(DialogGadget(\IdForm,\myGadget()\name))=""
                  SetGadgetColor(DialogGadget(\IdForm,"LB__"+\myGadget()\name),#PB_Gadget_FrontColor,$0000FF)
                  SetActiveGadget(DialogGadget(\IdForm,\myGadget()\name))
                  ProcedureReturn #False
                EndIf
              Case DB::#Type_Link
                If GetGadgetItemData(idG,GetGadgetState(idG))=-1
                  SetGadgetColor(DialogGadget(\IdForm,"LB__"+\myGadget()\name),#PB_Gadget_FrontColor,$0000FF)
                  SetActiveGadget(idG)
                  ProcedureReturn #False
                EndIf
              Case DB::#Type_Integer
                If Val(GetGadgetText(idG))=0
                  SetGadgetColor(DialogGadget(\IdForm,"LB__"+\myGadget()\name),#PB_Gadget_FrontColor,$0000FF)
                  SetActiveGadget(idG)
                  ProcedureReturn #False
                EndIf
            EndSelect
          EndIf
        EndIf
      Next
    EndWith
    ProcedureReturn #True
  EndProcedure
  Procedure AddRecord(*This.sFic)
    Protected req1.s,req2.s,req.s,n,tmp.s,id,idDb
    With *This
      req="INSERT INTO "+\TableName
      req1=" ("
      req2=" VALUES ("
      ForEach \myGadget()
        req1+\myGadget()\name+","
        If Not \myGadget()\flag & #GadgetHide
          Select DB::GetTypeOfColumn(\TableName,\myGadget()\name)
            Case DB::#Type_Text,DB::#Type_Note,DB::#Type_Phone,DB::#Type_Email
              req2+Chr(34)+GetGadgetText(DialogGadget(\IdForm,\myGadget()\name))+Chr(34)+","
            Case DB::#Type_Link
              req2+Str(GetGadgetItemData(DialogGadget(\IdForm,\myGadget()\name),GetGadgetState(DialogGadget(\IdForm,\myGadget()\name))))+","
            Case DB::#Type_Euro
              tmp=GetGadgetText(DialogGadget(\IdForm,\myGadget()\name))
              tmp=RemoveString(tmp,"€")
              tmp=RemoveString(tmp," ")
              req2+tmp+","
            Case DB::#Type_Percentage
              tmp=GetGadgetText(DialogGadget(\IdForm,\myGadget()\name))
              tmp=RemoveString(tmp,"%")
              tmp=RemoveString(tmp," ")
              req2+tmp+","
            Case DB::#Type_Date
              req2+Chr(34)+FormatDate("%yyyy%mm%dd",GetGadgetState(DialogGadget(\IdForm,\myGadget()\name)))+Chr(34)+","
            Case DB::#Type_Integer
              req2+Str(Val(GetGadgetText(DialogGadget(\IdForm,\myGadget()\name))))+","
            Case DB::#Type_Checkbox
              req2+Str(GetGadgetState(DialogGadget(\IdForm,\myGadget()\name)))+","
          EndSelect
        Else
          req2+\myGadget()\Value+","
        EndIf
      Next
      req1=Left(req1,Len(req1)-1)+")"
      req2=Left(req2,Len(req2)-1)+")"
      req+req1+req2
      DB::Update(req)
      ; Si il y a des liaison on les met à jour
      If ListSize(\myLinkedData())
        ; Charge le dernier id du record
        req="SELECT "+DB::GetIdTableName(\TableName)+
            " FROM "+\TableName+
            " ORDER BY "+DB::GetIdTableName(\TableName)+" DESC"
        idDb=DB::Query(req)
        If FirstDatabaseRow(idDb)
          id=GetDatabaseLong(idDb,0)
          CloseDatabase(idDb)
          UpdateLinkedData(*This,id)
        EndIf
      EndIf
    EndWith
  EndProcedure
  Procedure DoublonCompositeKey(*This.sFic)
    Protected NewList myCompositeKey.s()
    Protected req.s,i,IdG,n,IdDb,current.s
    With *This
      DB::GetCompositeKey(\TableName,myCompositeKey())
      If Not ListSize(myCompositeKey())
        ProcedureReturn #False       
      EndIf
      ForEach myCompositeKey()
        req="SELECT * FROM "+\TableName
        n=CountString(myCompositeKey(),Chr(10))
        For i=1 To n+1
          If i=1
            req+" WHERE "
          Else
            req+" AND "
          EndIf
          current=StringField(myCompositeKey(),i,Chr(10))
          ForEach \myGadget()
            If \myGadget()\name=current
              Break
            EndIf
          Next 
          IdG=DialogGadget(\IdForm,\myGadget()\name)
          Select DB::GetTypeOfColumn(\TableName,\myGadget()\name)
            Case DB::#Type_Link
              req+\myGadget()\name+" = "+Str(GetGadgetItemData(IdG,GetGadgetState(IdG)))
            Case DB::#Type_Text,DB::#Type_Note,DB::#Type_Phone,DB::#Type_Email
              req+\myGadget()\name+" = "+Chr(34)+GetGadgetText(IdG)+Chr(34)
          EndSelect
        Next
        If \Flag & #ModeEdit
          req+" AND "+DB::GetIdTableName(\TableName)+"!="+Str(\CurrentRecord)
        EndIf
        IdDb=DB::Query(req)
        If Not IdDb
          If IsDatabase(IdDb)
            CloseDatabase(IdDb)
          EndIf
          ProcedureReturn #True
        EndIf
        If FirstDatabaseRow(IdDb)
          CloseDatabase(IdDb)
          ProcedureReturn #True
        EndIf
        CloseDatabase(IdDb)
      Next
      ProcedureReturn #False
    EndWith
  EndProcedure
  Procedure Doublon(*This.sFic)
    Protected req.s,idDb,Title.s,tmp.s
    With *This  
      ForEach \myGadget()
        If IsGadget(DialogGadget(\IdForm,"LB__"+\myGadget()\name))
          SetGadgetColor(DialogGadget(\IdForm,"LB__"+\myGadget()\name),#PB_Gadget_FrontColor,#PB_Default)
        EndIf
      Next
      ForEach \myGadget()
        If Not \myGadget()\flag & #GadgetHide
          If DB::GetFlagOfColumn(\TableName,\myGadget()\name) & DB::#Unique
            req="SELECT * FROM "+\TableName+" WHERE "+\myGadget()\name+"="
            Select DB::GetTypeOfColumn(\TableName,\myGadget()\name)
              Case DB::#Type_Text,DB::#Type_Note,DB::#Type_Phone,DB::#Type_Email
                req+Chr(34)+GetGadgetText(DialogGadget(\IdForm,\myGadget()\name))+Chr(34)
              Case DB::#Type_Percentage
                tmp=GetGadgetText(DialogGadget(\IdForm,\myGadget()\name))
                tmp=RemoveString(tmp,"%")
                tmp=RemoveString(tmp," ")
                req+tmp 
              Case DB::#Type_Euro
                tmp=GetGadgetText(DialogGadget(\IdForm,\myGadget()\name))
                tmp=RemoveString(tmp,"€")
                tmp=RemoveString(tmp," ")
                req+tmp  
              Case DB::#Type_Integer
                req+GetGadgetText(DialogGadget(\IdForm,\myGadget()\name))
              Case DB::#Type_Checkbox
                req+Str(GetGadgetState(DialogGadget(\IdForm,\myGadget()\name)))
            EndSelect
            If \Flag&#ModeEdit
              req+" AND "+DB::GetIdTableName(\TableName)+" !="+Str(\CurrentRecord)
            EndIf
            idDb=DB::Query(req)
            If Not idDb
              CloseDatabase(idDb)
            EndIf
            If FirstDatabaseRow(idDb)
              SetGadgetColor(DialogGadget(\IdForm,"LB__"+\myGadget()\name),#PB_Gadget_FrontColor,$0000FF)
              SetActiveGadget(DialogGadget(\IdForm,\myGadget()\name))
              CloseDatabase(idDb)
              MessageRequester("Erreur doublon","Ce champ existe déjà!",#PB_MessageRequester_Warning)
              ProcedureReturn #True
            EndIf
            CloseDatabase(idDb)
          EndIf
        EndIf
      Next
      If DoublonCompositeKey(*This)
        If \Flag & #ModeEdit
          Title=\TitleEdit
        Else
          Title=\TitleNew
        EndIf
        MessageRequester(Title,"Un enregistrement similaire existe déjà...",#PB_MessageRequester_Warning)
        ProcedureReturn #True
      EndIf
      ProcedureReturn #False
    EndWith
  EndProcedure
  Procedure UpdateRecord(*This.sFic)
    Protected req.s,values.s,idG,tmp.s
    With *This
      req="UPDATE "+\TableName+" SET "
      ForEach \myGadget()
        idG=DialogGadget(\IdForm,\myGadget()\name)
        values+\myGadget()\name+"="
        If Not \myGadget()\flag & #GadgetHide
          Select DB::GetTypeOfColumn(\TableName,\myGadget()\name)
            Case DB::#Type_Text,DB::#Type_Note,DB::#Type_Phone,DB::#Type_Email
              values+Chr(34)+GetGadgetText(idG)+Chr(34)+","
            Case DB::#Type_Link  
              values+Str(GetGadgetItemData(idG,GetGadgetState(idG)))+","
            Case DB::#Type_Euro
              tmp=GetGadgetText(idG)
              tmp=RemoveString(tmp,"€")
              tmp=RemoveString(tmp," ")
              values+tmp+","
            Case DB::#Type_Percentage
              tmp=GetGadgetText(idG)
              tmp=RemoveString(tmp,"%")
              tmp=RemoveString(tmp," ")
              values+tmp+","
            Case DB::#Type_Date
              values+Chr(34)+FormatDate("%yyyy%mm%dd",GetGadgetState(DialogGadget(\IdForm,\myGadget()\name)))+Chr(34)+"," 
            Case DB::#Type_Integer
              values+GetGadgetText(idG)+","
            Case DB::#Type_Checkbox
              values+Str(GetGadgetState(DialogGadget(\IdForm,\myGadget()\name)))+","
          EndSelect
        Else
          values+\myGadget()\Value+","
        EndIf
      Next
      values=Left(values,Len(values)-1)
      req+values+
          " WHERE "+DB::GetIdTableName(\TableName)+
          " = "+Str(\CurrentRecord)
      DB::Update(req)
    EndWith
  EndProcedure
  Procedure EventValidate()
    Protected *This.sFic=SelectMyForm()
    With *This
      If Not CallCallback(*This,#BeforeValide)
        ProcedureReturn 
      EndIf 
      If Not VerifNotNull(*This)
        ProcedureReturn 
      EndIf
      If Doublon(*This)
        ProcedureReturn 
      EndIf
      If \Flag & #ModeEdit
        UpdateRecord(*This)
      Else
        AddRecord(*This)
      EndIf
      If \callBack
        CallFunctionFast(\callBack,\From,\CurrentRecord)
        Exit()
      EndIf
      If CallCallback(*This,#AfterValide)
        ProcedureReturn 
      EndIf 
    EndWith
  EndProcedure
  Procedure DisableValidateByReturn()
    Protected *This.sFic=SelectMyForm()
    With *This
      
    EndWith
  EndProcedure
  Procedure SelectedComboById(*This.sFic,idRec)
    Protected n,i,id
    With *This
      id=DialogGadget(\IdForm,\myGadget()\name)
      n=CountGadgetItems(id)
      For i=0 To n-1
        If GetGadgetItemData(id,i)=idRec
          SetGadgetState(id,i)
          ProcedureReturn 
        EndIf
      Next
    EndWith
  EndProcedure
  Procedure FillGadget(*This.sFic)
    Protected req.s,idDb,n,Idg,YY,MM,DD
    req="SELECT "
    With *This
      ForEach \myGadget()
        req+\myGadget()\name+","
      Next
      req=Left(req,Len(req)-1)
      req+" FROM "+\TableName+
          " WHERE "+DB::GetIdTableName(\TableName)+
          " = "+Str(\CurrentRecord)
      idDb=DB::Query(req)
      If Not idDb
        If IsDatabase(idDb)
          CloseDatabase(idDb)
        EndIf
        ProcedureReturn 
      EndIf
      If Not FirstDatabaseRow(idDb)
        CloseDatabase(idDb)
        mError("FillGadget","Can't open this record "+Str(\CurrentRecord),#False)
      EndIf
      n=0
      ForEach \myGadget()
        If Not \myGadget()\flag & #GadgetHide
          idg=DialogGadget(\IdForm,\myGadget()\name)
          Select DB::GetTypeOfColumn(\TableName,\myGadget()\name)
            Case DB::#Type_Link
              SelectedComboById(*This,GetDatabaseLong(idDb,n))
            Case DB::#Type_Text,DB::#Type_Note,DB::#Type_Phone,DB::#Type_Email
              SetGadgetText(idg,GetDatabaseString(idDb,n))
            Case DB::#Type_Percentage
              SetGadgetText(idg,FormatNumber(GetDatabaseFloat(idDb,n),2,"."," ")+" %")
            Case DB::#Type_Euro
              SetGadgetText(idg,FormatNumber(GetDatabaseFloat(idDb,n),2,"."," ")+" €")
            Case DB::#Type_Integer
              SetGadgetText(idg,Str(GetDatabaseLong(idDb,n)))
            Case DB::#Type_Date
              YY=Val(Left(GetDatabaseString(idDb,n),4))
              MM=Val(Mid(GetDatabaseString(idDb,n),5,2))
              DD=Val(Right(GetDatabaseString(idDb,n),2))
              SetGadgetState(idg,Date(YY,MM,DD,0,0,0))
            Case DB::#Type_Checkbox
              SetGadgetState(idg,GetDatabaseLong(idDb,n))
          EndSelect
        EndIf
        n+1
      Next
      CloseDatabase(idDb)
      ProcedureReturn #True
    EndWith
  EndProcedure
  Procedure FillCombo(*This.sFic)
    Protected req.s,idDb,n,txt.s,y,m,d
    With *This
      req="SELECT "+DB::GetLinkedColumn(\TableName,\myGadget()\name)
      req+","+DB::GetColumnDisplayed(\TableName,\myGadget()\name)
      req+" FROM "+DB::GetLinkedTable(\TableName,\myGadget()\name)
      If \myGadget()\OrderClause=""
        req+" ORDER BY "+DB::GetColumnDisplayed(\TableName,\myGadget()\name)
      Else
        req+" "+\myGadget()\OrderClause
      EndIf
      idDb=DB::Query(req)
      If Not idDb
        CloseDatabase(idDb)
        ProcedureReturn 
      EndIf
      ClearGadgetItems(DialogGadget(\IdForm,\myGadget()\name))
      AddGadgetItem(DialogGadget(\IdForm,\myGadget()\name),-1,"Aucune sélection")
      SetGadgetItemData(DialogGadget(\IdForm,\myGadget()\name),n,-1)
      While NextDatabaseRow(idDb)
        n+1
        Select DB::GetTypeOfColumn(DB::GetLinkedTable(\TableName,\myGadget()\name),DB::GetColumnDisplayed(\TableName,\myGadget()\name))
          Case DB::#Type_Text,DB::#Type_Note,DB::#Type_Email,DB::#Type_Phone
            txt=GetDatabaseString(idDb,1)
          Case DB::#Type_Euro
            txt=FormatNumber(GetDatabaseFloat(idDb,1),2,"."," ")+" €"
          Case DB::#Type_Percentage
            txt=FormatNumber(GetDatabaseFloat(idDb,1),2,"."," ")+" %"
          Case DB::#Type_Integer
            txt=FormatNumber(GetDatabaseFloat(idDb,1),0,"."," ")
          Case DB::#Type_Float
            txt=FormatNumber(GetDatabaseFloat(idDb,1),0,"."," ") 
          Case DB::#Type_Double
            txt=FormatNumber(GetDatabaseDouble(idDb,1),0,"."," ") 
          Case DB::#Type_Date
            y=Val(Left(GetDatabaseString(idDb,1),4))
            m=Val(Mid(GetDatabaseString(idDb,1),5,2))
            d=Val(Mid(GetDatabaseString(idDb,1),8,2))
            txt=FormatDate("%dd-%MM-%YYYY",Date(y,m,d,0,0,0))
        EndSelect
        AddGadgetItem(DialogGadget(\IdForm,\myGadget()\name),-1,txt)
        SetGadgetItemData(DialogGadget(\IdForm,\myGadget()\name),n,GetDatabaseLong(idDb,0))
      Wend
      CloseDatabase(idDb)
      SetGadgetState(DialogGadget(\IdForm,\myGadget()\name),0)
    EndWith
  EndProcedure
  Procedure UpdateLinkedData(*This.sFic,id)
    Protected req.s,value.s,idDb,idG
    With *This
      ForEach \myLinkedData()
        idG=DialogGadget(\IdForm,\myLinkedData()\columnId)
        If IsGadget(idG)
          req="SELECT "+\myLinkedData()\StrangerColumn+
              " FROM "+\myLinkedData()\TableLinked+
              " WHERE "+DB::GetIdTableName(\myLinkedData()\TableLinked)+
              " = "+Str(GetGadgetItemData(idG,GetGadgetState(idG)))
          idDb=DB::Query(req)
          If FirstDatabaseRow(idDb)
            Select DatabaseColumnType(idDb,0)
              Case #PB_Database_Long  
                value=Str(GetDatabaseLong(idDb,0))
              Case #PB_Database_String
                value=GetDatabaseString(idDb,0)
              Case #PB_Database_Float 
                value=StrF(GetDatabaseFloat(idDb,0))
              Case #PB_Database_Double
                value=StrD(GetDatabaseDouble(idDb,0))
            EndSelect
          EndIf
          CloseDatabase(idDb)
          req="UPDATE "+\TableName+" SET "+
              \myLinkedData()\columnLinked+" = "+value+
              " WHERE "+DB::GetIdTableName(\TableName)+" = "+Str(id)
          DB::Update(req)
        EndIf
      Next
    EndWith
  EndProcedure
  Procedure CallCallback(*This.sFic,flag.l)
    With *This
      ForEach \myCallBack()
        If \myCallBack()\flag & flag
          ProcedureReturn CallFunctionFast(\myCallBack()\callBack)
        EndIf
      Next
      ProcedureReturn #True
    EndWith
  EndProcedure
  ;}-----------------------------------------------------------------------------------------------------------------------------------------------------
  ;======================================================================================================================================================
  ;-* PUBLIC FUNCTIONS
  ; -----------------------------------------------------------------------------------------------------------------------------------------------------
  Procedure New(TableName.s,TitleNew.s,TitleEdit.s,NumberColumn=1)
    Protected *Fic.sFic=AllocateStructure(sFic)
    With *Fic
      \TableName=TableName
      \TitleNew=TitleNew
      \TitleEdit=TitleEdit
      \NumberColumn=NumberColumn
      \FormFlag=#PB_Window_SizeGadget|#PB_Window_SystemMenu
      \VPROC=?VPROC
      ProcedureReturn *Fic
    EndWith
  EndProcedure
  Procedure Open(*This.sFic,MotherWindow=-1,*From=0,*Callback=0,flag.l=0,CurrentRecord=0)
    Protected xml.s,myXml
    With *This
;       CallCallback(*This,#BeforeOpen)
      \motherWindow=MotherWindow
      \Flag=flag
      \callBack=*Callback
      \From=*From
      \CurrentRecord=CurrentRecord
      SetGadgetFont(#PB_Default,FontID(Font))
      xml=MakeXml(*This)
      myXml=CatchXML(#PB_Any, @xml, StringByteLength(xml), 0,#PB_UTF8)
      If Not myXml Or XMLStatus(myXml) <> #PB_XML_Success
        mError("Open",XMLError(myXml)+" line "+Str(XMLErrorLine(myXml)),#False)
      EndIf
      \IdForm=CreateDialog(#PB_Any)
      If Not \IdForm
        mError("Open","Can't create dialog",#False)
      EndIf
      If \motherWindow<>-1
        DisableWindow(\motherWindow,#True)
        If Not OpenXMLDialog(\IdForm,myXml,\TableName,\x,\y,0,0,WindowID(\motherWindow))
          mError("Open","Can't open dialog",#False)
        EndIf
      Else
        If Not OpenXMLDialog(\IdForm,myXml,\TableName,\x,\y)
          mError("Open","Can't open dialog",#False)
        EndIf
      EndIf
      FreeXML(myXml)
      SetWindowData(DialogWindow(\IdForm),*This)
      ; Memorise l'index des gadgets et gestion des événement
      ForEach \myGadget()
        If Not \myGadget()\flag & #GadgetHide
          Select DB::GetTypeOfColumn(\TableName,\myGadget()\name)
            Case DB::#Type_Link
              SetGadgetData(DialogGadget(\IdForm,\myGadget()\name),@\myGadget())
              If \myGadget()\TabForm <>-1
                SetGadgetData(DialogGadget(\IdForm,"BTSEL_"+\myGadget()\name),@\myGadget())
                BindGadgetEvent(DialogGadget(\IdForm,"BTSEL_"+\myGadget()\name),@EventSelect())
                ; Remplisage du combo
              EndIf
              FillCombo(*This)
            Case DB::#Type_Euro,DB::#Type_Percentage,DB::#Type_Float,DB::#Type_Double,DB::#Type_Phone
              SetGadgetData(DialogGadget(\IdForm,\myGadget()\name),@\myGadget())
              BindGadgetEvent(DialogGadget(\IdForm,\myGadget()\name),@EventMask())
            Case DB::#Type_Date
              
            Default
              SetGadgetData(DialogGadget(\IdForm,\myGadget()\name),@\myGadget())
          EndSelect
        EndIf
      Next
      BindGadgetEvent(DialogGadget(\IdForm,"bt_validate"),@EventValidate())
      BindGadgetEvent(DialogGadget(\IdForm,"bt_chancel"),@Exit())
      BindEvent(#PB_Event_CloseWindow,@Exit(),DialogWindow(\IdForm))
      ; Ajout des raccourcis clavier
      AddKeyboardShortcut(DialogWindow(\IdForm),#PB_Shortcut_Return,0)
      AddKeyboardShortcut(DialogWindow(\IdForm),#PB_Shortcut_Escape,1)
      BindEvent(#PB_Event_Menu,@EventValidate(),DialogWindow(\IdForm),0)
      BindEvent(#PB_Event_Menu,@Exit(),DialogWindow(\IdForm),1)
      BindEvent(#PB_Event_ActivateWindow ,@SelectMyList(),DialogWindow(\IdForm))
      ; Gestion de la désactivation du rac clavier pour EditGadget
      BindEvent(#PB_Event_Gadget,@DisableValidateByReturn(),DialogWindow(\IdForm))
      If \Flag & #ModeEdit
        FillGadget(*This)
      EndIf
      ; Se placer sur le première élément
      FirstElement(\myGadget())
      SetActiveGadget(DialogGadget(\IdForm,\myGadget()\name))
      CallCallback(*This,#AfterOpen)
    EndWith
  EndProcedure
  Procedure AddGadget(*This.sFic,Name.s,MergedColumn=0,TabForm=-1,Flag.l=0)
    With *This
      AddElement(\myGadget())
      \myGadget()\name=Name
      \myGadget()\NumberColumnMerged=MergedColumn
      \myGadget()\TabForm=TabForm
      \myGadget()\flag=Flag
    EndWith
  EndProcedure
  Procedure SetSize(*This.sFic,minWidth,minHeight,maxWidth,maxHeight)
    With *This
      \minWidth=minWidth
      \minHeight=minHeight
      \maxHeight=maxHeight
      \maxWidth=maxWidth
    EndWith
  EndProcedure
  Procedure GetGadgetId(*This.sFic,GadgetName.s)
    With *This
      ForEach \myGadget() 
        If \myGadget()\name=GadgetName.s
          ProcedureReturn DialogGadget(\IdForm,\myGadget()\name)
        EndIf
      Next
      ProcedureReturn -1
    EndWith
  EndProcedure
  Procedure SetGadgetValue(*This.sFic,GadgetName.s,Value.s)
    With *This
      ForEach \myGadget()
        If \myGadget()\name=GadgetName
          If Not \myGadget()\flag & #GadgetHide
            mError("SetGadgetValue","This function is only available for hided gadget",#False)
          EndIf
          \myGadget()\Value=Value
        EndIf
      Next
      ProcedureReturn #False
    EndWith
  EndProcedure
  Procedure AddLinkedData(*This.sFic,columnId.s,columnLinked.s,TableLinked.s,StrangerColumn.s)
    With *This
      AddElement(\myLinkedData())
      \myLinkedData()\columnId=columnId
      \myLinkedData()\columnLinked=columnLinked
      \myLinkedData()\TableLinked=TableLinked
      \myLinkedData()\StrangerColumn=StrangerColumn
    EndWith
  EndProcedure
  Procedure Free(*This.sFic)
    ClearStructure(*This,sFic)
  EndProcedure
  Procedure AddCallback(*This.sFic,*CallBack,flag.l)
    With *This
      AddElement(\myCallBack())
      \myCallBack()\callBack=*CallBack
      \myCallBack()\flag=flag
    EndWith
  EndProcedure
  Procedure GetmyFlag(*This.sFic)
    With *This
      ProcedureReturn \Flag
    EndWith
  EndProcedure
  Procedure SetOrderClauseLinkedColumn(*This.sFic,Clause.s)
    With *This
      \myGadget()\OrderClause=Clause
    EndWith
  EndProcedure
  ;}-----------------------------------------------------------------------------------------------------------------------------------------------------
  DataSection
    VPROC:
    Data.i @Open()
    Data.i @AddGadget()
    Data.i @SetSize()
    Data.i @GetGadgetId()
    Data.i @SetGadgetValue()
    Data.i @AddLinkedData()
    Data.i @Free()
    Data.i @AddCallback()
    Data.i @GetmyFlag()
    Data.i @SetOrderClauseLinkedColumn()
  EndDataSection
EndModule
Windows 10 64 bits PB: 5.70 ; 5.72 LST
Work at Centre Spatial de Liège
Avatar de l’utilisateur
omega
Messages : 633
Inscription : sam. 26/nov./2011 13:04
Localisation : Alger

Re: Problème avec ComboBoxGadget

Message par omega »

Bonsoir à tous et merci beaucoup pour toutes ces leçons utiles ! Avant de refaire mon code conformément à vos conseils méthodologiques, je dois passer un bon moment à lire et à comprendre car certaines méthodes-syntaxes sont toutes nouvelles pour moi, il faudra donc me familiariser d'abords avec ces termes avant de refaire complètement mon code. Cependant, j'ai une question importante à poser (si vous permettez) : y a t-il une possibilité d'utiliser BindGadgetEvent avec un comboboxgadget? Un exemple de code me sera d'une grande utilité. (Je remarque que BindGadgetEvent est utilisé surtout avec les boutons dans les différents exemples précédents et même dans l'aide Pb.)
Je veux juste savoir ce que l'utilisateur a fait dans ce combobox (est-ce une sélection? Est-ce une saisie? etc...)
Encore une fois, merci.
Win7 (x64) 64 bits Pb 5.72
G-Rom
Messages : 3641
Inscription : dim. 10/janv./2010 5:29

Re: Problème avec ComboBoxGadget

Message par G-Rom »

oui, lis la doc & regarde mon snippet plus haut.
code plus haut a écrit :BindGadgetEvent(\gadget[#COMBO_LISTE_2], @SelectioneProduit(), #PB_EventType_Change )
boby
Messages : 261
Inscription : jeu. 07/juin/2007 22:54

Re: Problème avec ComboBoxGadget

Message par boby »

Avatar de l’utilisateur
omega
Messages : 633
Inscription : sam. 26/nov./2011 13:04
Localisation : Alger

Re: Problème avec ComboBoxGadget

Message par omega »

Oui, c'est vrai, il y a aussi le code de Microdevweb, de G-Rom et de Boby aussi...
Merci à toute l'équipe
RV dans quelques jours pour présenter mon nouveau code plus structuré et plus aéré.. pendant ce temps, je vais sûrement vous embêter avec mes nombreuses questions surtout sur les nouveaux termes que j'ai jamais utilisés (structures, modules, bindevent etc...)
En attendant, je vous remercie encore et...
Bonne continuation
Win7 (x64) 64 bits Pb 5.72
Avatar de l’utilisateur
microdevweb
Messages : 1802
Inscription : mer. 29/juin/2011 14:11
Localisation : Belgique

Re: Problème avec ComboBoxGadget

Message par microdevweb »

A mon sens découpe sur une simple feuille de papier, les fonctionnalités de ton logiciel , exemple fiche client, liste client, facture, fenêtre principal etc.. En partant de cela tu pourra faire un module pour chaque fonctionnalité. Ce qui sera nettement plus simple à maintenir et plus évolutif.

Les modules équivalent au espace de nom du c. Personnellement je fais toujours un module pour les ordre de la base de donnée (query, update) car dans l’hypothèse ou il faudrait changé par exemple passer de Sqlite à PostgresSql il suffis de ne changer que la fonction du module sans toucher au reste du code qui utilise les dites requêtes.
Windows 10 64 bits PB: 5.70 ; 5.72 LST
Work at Centre Spatial de Liège
Avatar de l’utilisateur
omega
Messages : 633
Inscription : sam. 26/nov./2011 13:04
Localisation : Alger

Re: Problème avec ComboBoxGadget

Message par omega »

Bonjour Microdevweb

Regardes ce qui m'attend: je dois prévoir les fonctions communes suivantes (Création, modification, suppression, affichage sur grid et impression) pour chacune des tables suivantes:
table des clients, table des fournisseurs,table des produits,table des réceptions,table des livraisons, table des factures,mouvements de caisse,mouvements bancaires,versements clients, versements fournisseurs, etc....

Pour chaque cas ci dessus, il y aura les procédures suivantes:
Proc valider(), Proc Supprimer, Proc Afficher, proc Imprimer

La proc Valider() sera toujours composée de (dans l'ordre):
1. Récupération des valeurs des champs de saisie (GetGadgetText())
2. Test de validité de chaque valeur
3. Si pas d'erreur de saisie, alors:
a) Mise à jour (Ajouter ou modifier) l'enregistrement
b) Mise à jour du contenu du Grid (Grid=ListIconGadget)
c) Initialisation des champs de saisie
SINON (c'est à dire en ca d'erreur de saisie):
Afficher message d'erreur
4. Fin de procédure Valider
Fin de procédure

La proc Supprimer() sera toujours composée de (dans l'ordre):
1. Récupération des valeurs des champs de saisie (GetGadgetText())
2. Voir si l'enregistrement à supprimer existe
3. S'il existe:
a) Message de confirmation de la suppression (avant de supprimer réellement)
b) Si la réponse de l"utilisateur est OUI
c) Suppression de l'enregistrement
d) Initialisation des champs de saisie
e) Maj du contenu du Grid
SINON ():
Afficher message d'erreur ()
4. Fin de procédure Supprimer
Fin de procédure

Pour les autres procédure, il n'y a aucun test à faire on affiche le contenu de la table sur grid ou on imprime.

Je suppose que je dois faire chacune de ces fonctions sous forme de module?
Qu'en penses tu?

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

Re: Problème avec ComboBoxGadget

Message par Micoute »

Bonjour omega, j'aurais aimé avoir a programmer un tel programme de gestion.
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 6.20 LTS (x64)
Un homme doit être poli, mais il doit aussi être libre !
Avatar de l’utilisateur
omega
Messages : 633
Inscription : sam. 26/nov./2011 13:04
Localisation : Alger

Re: Problème avec ComboBoxGadget

Message par omega »

Bonjour Micoute,
j'aurais aimé avoir a programmer un tel programme de gestion.
C'est sérieux ? je ne pense pas avoir compris ce que tu voulais dire...
Win7 (x64) 64 bits Pb 5.72
Avatar de l’utilisateur
Ar-S
Messages : 9539
Inscription : dim. 09/oct./2005 16:51
Contact :

Re: Problème avec ComboBoxGadget

Message par Ar-S »

Micoute a écrit :Bonjour omega, j'aurais aimé avoir a programmer un tel programme de gestion.
Rien ne t'empêche de le faire...
Les Auto entrepreneurs dont je fais parti serait preneur avec un soft propre et mieux concu que les soft "Ciel" par exemple.
~~~~Règles du forum ~~~~
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
Avatar de l’utilisateur
falsam
Messages : 7317
Inscription : dim. 22/août/2010 15:24
Localisation : IDF (Yvelines)
Contact :

Re: Problème avec ComboBoxGadget

Message par falsam »

Omega a écrit :]Je suppose que je dois faire chacune de ces fonctions sous forme de module?
Excactement. Un module par fonction.

C'est le principe que tu appliques à tes bases de données : Une base par table !!!

Non mais sérieux : C'est du n'importe quoi cette discussion qui démontre ta méconnaissance des bases de données et des modules voir même ta méconnaissance en gestion de projet de développement informatique. :twisted:

Quand on travaille pour des clients on ne peut pas se permettre ce genre de chose.
Configuration : Windows 11 Famille 64-bit - PB 6.20 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 : 2583
Inscription : dim. 02/oct./2011 16:17
Localisation : 35520 La Mézière

Re: Problème avec ComboBoxGadget

Message par Micoute »

Ar-S a écrit :
Micoute a écrit :Bonjour omega, j'aurais aimé avoir a programmer un tel programme de gestion.
Rien ne t'empêche de le faire...
Les Auto entrepreneurs dont je fais parti seraient preneurs avec un soft propre et mieux concu que les soft "Ciel" par exemple.
Bonjour Ar-s, donne-moi un cahier des charges et je te le réalise gratos, j'adore m'occuper l'esprit en programmant des logiciels.

Attention, je ne sais pas tout faire, mais ne sommes-nous pas sur un forum d'entraide à la programmation en PureBasic ?
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 6.20 LTS (x64)
Un homme doit être poli, mais il doit aussi être libre !
Verrouillé