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.
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
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.
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 : 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