Alimenter TreeView depuis une base de données

Vous débutez et vous avez besoin d'aide ? N'hésitez pas à poser vos questions
pls
Messages : 21
Inscription : mer. 26/févr./2020 17:21

Alimenter TreeView depuis une base de données

Message par pls »

Bonjour,

Nouveau sur le forum et débutant en PUREBASIC, j'aurai besoin de vos conseils.

J'ai une BDD Oracle avec 2 tables.

Table1 : liste des applications
Table2 : liste des tables de l'application qui référence la table 1 par un code.

Je souhaite créer un treeview qui me permette d'avoir la liste des applis que je peux déplier pour avoir la liste des tables que contient l'application.

app1
table1
table1
app2
table1
table2
table3

Pas de soucis pour me connecter à Oracle avec ODBC par contre je bute sur la mise en œuvre.
J'ai fait quelques essais et j'arrive bien a alimenter le 1er niveau du treeview je ne vois pas comment ajouter le second (je ne peux pas utiliser le même DBID).
De plus, j'aimerai quand le clique sur une appli ou une table dans le treeview, afficher le reste des information des applis ou table.

Merci de vos précieux conseils.

Code : Tout sélectionner

UseODBCDatabase()

#DBID = 0
#TREE1 = 1

If Not OpenDatabase(#DBID, "DW_CARTO", "XJKDSJDQMFK", "XJKDSJDQMFK")
  MessageRequester("BDD","PB COnnexion " + DatabaseError(),#PB_MessageRequester_Warning)
EndIf

reqApp.s = "Select code_app, lib_app from carto_application"
reqEnt.s = "Select code_entite, nom_entite from carto_entite"+
           " where fk_code_app = "+codeApp

If Not DatabaseQuery(#DBID, reqApp)
  MessageRequester("Sql Error",reqApp+Chr(10)+DatabaseError(),#PB_MessageRequester_Error)
EndIf

If OpenWindow(0, 0, 0, 800, 600, "Carto", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  TreeGadget(#TREE1, 10, 10, 300, 580) 
  If DatabaseQuery(#DBID, reqApp)
    While NextDatabaseRow(#DBID)
      AddGadgetItem(#TREE1, -1, GetDatabaseString(#DBID,DatabaseColumnIndex(#DBID,"LIB_APP")),0,0)
    Wend
  EndIf
  Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf
Debug #DBID

CloseDatabase(#DBID)
Marc56
Messages : 2199
Inscription : sam. 08/févr./2014 15:19

Re: Alimenter TreeView depuis une base de données

Message par Marc56 »

Bonjour,

Pour décaler donc créer une branche il faut mettre en cinquième paramètre de getgadgetitem un numéro supérieur à celui de la ligne précèdente

Pour récupérer le numéro de l'element sélectionné il faut utiliser Getgadgetstate

:wink:
pls
Messages : 21
Inscription : mer. 26/févr./2020 17:21

Re: Alimenter TreeView depuis une base de données

Message par pls »

Bonjour,

Merci pour ta réponse rapide.
Top pour le Getgadgetstate, ça va bien m'aider et le positionnement dans le treeview, ça marche impeccable :)

J'ai quand même un truc qui me fait bizarre, j'ai du ouvrir 2 fois ma DBB car comme je lance 2 requêtes différentes, j'adresse 2 curseurs différents.
Ça vous parait normal ? Il y a peut être un moyen moins biscornu ? Une requête unique sur les 2 tables ?

Merci,
Philippe.

Code : Tout sélectionner

reqApp.s = "Select code_app, lib_app from carto_application order by lib_app"

If Not DatabaseQuery(#DBID, reqApp)
  MessageRequester("Sql Error",reqApp+Chr(10)+DatabaseError(),#PB_MessageRequester_Error)
EndIf

If OpenWindow(0, 0, 0, 1024, 780, "Carto", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  TreeGadget(#TREE1, 10, 10, 300, 760) 
  If DatabaseQuery(#DBID, reqApp)
    While NextDatabaseRow(#DBID)
      codeApp = GetDatabaseLong(#DBID,DatabaseColumnIndex(#DBID,"CODE_APP"))
      AddGadgetItem(#TREE1, -1, GetDatabaseString(#DBID,DatabaseColumnIndex(#DBID,"LIB_APP")),0,0)
      OpenDatabase(#DBID1, "DW_CARTO", "DW", "DW")
      If DatabaseQuery(#DBID1, "Select code_entite, nom_entite from carto_entite where fk_code_app = "+codeApp+
                               " order by nom_entite")
        While NextDatabaseRow(#DBID1)
          AddGadgetItem(#TREE1, -1, GetDatabaseString(#DBID1,DatabaseColumnIndex(#DBID1,"NOM_ENTITE")),0,1)
        Wend
      EndIf 
      CloseDatabase(#DBID1)
    Wend
  EndIf
  Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf

CloseDatabase(#DBID)
Marc56
Messages : 2199
Inscription : sam. 08/févr./2014 15:19

Re: Alimenter TreeView depuis une base de données

Message par Marc56 »

Bonjour,
J'ai quand même un truc qui me fait bizarre, j'ai du ouvrir 2 fois ma DBB car comme je lance 2 requêtes différentes, j'adresse 2 curseurs différents.
Ça vous parait normal ? Il y a peut être un moyen moins biscornu ? Une requête unique sur les 2 tables ?
Oui, pourquoi ne pas faire une jointure ?

Car en plus, tel que tu l'as écrit, tu ré-ouvres et referme la connexion à chaque ligne.
Un appel à FinishDatabaseQuery() après lecture de la dernière ligne (NextDatabaseRow) permet de libérer la ressource et exécuter une autre requête donc remet le curseur au début.

Code : Tout sélectionner

[...]    
While NextDatabaseRow(#DBID)
[...]
      OpenDatabase(#DBID1, "DW_CARTO", "DW", "DW")
[...]
:wink:
pls
Messages : 21
Inscription : mer. 26/févr./2020 17:21

Re: Alimenter TreeView depuis une base de données

Message par pls »

Merci beaucoup pour tes précieux conseils.
Marc56
Messages : 2199
Inscription : sam. 08/févr./2014 15:19

Re: Alimenter TreeView depuis une base de données

Message par Marc56 »

Je n'ai que des connaissances de base en SQL et pas du tout en Oracle, mais je suppose que quelque chose comme ceci devrait te permettre d'interroger les deux tables en une seule.
(Pas sûr pour la syntaxe alias de tables)

À faire vérifier par un spécialiste...

Code : Tout sélectionner

Code$ = GetGadgetText(...)

; Select code_app, lib_app from carto_application order by lib_app
; Select code_entite, nom_entite from carto_entite where nom_entite = "+codeApp+" order by nom_entite"

SQL$ = "SELECT                     " +
       "    A.code_app,            " +
       "    A.lib_app,             " +
       "    E.code_entite,         " +
       "    E.nom_entite           " +
       "FROM                       " +
       "    carto_application A,   " +
       "    carto_entite E         " +
       "WHERE                      " +
       "    E.nom_entite =       A." +
       Code$                         +
       "ORDER BY                   " +
       "    A.lib_app,             " +
       "    E.nom_entite           "

Debug SQL$
Note au passage, comment PB te permet de formater le code bien lisiblement (Il n'existe pas de caractère de rupture de ligne, mais on peut couper après un + ou une , (sauf dans les chaines de caractères))
CTRL+A suivi de CTRL+I reformate tout le code automatiquement.

:wink:
pls
Messages : 21
Inscription : mer. 26/févr./2020 17:21

Re: Alimenter TreeView depuis une base de données

Message par pls »

Effectivement, la requête est OK

Code : Tout sélectionner

reqSql = " Select app.code_app, app.lib_app, ent.code_entite, ent.nom_entite"+
         " From carto_entite ent, carto_application app"+
         " where app.code_app = ent.fk_code_app (+)"
Et me donne le bon résultat :

Code : Tout sélectionner

CODE_APP  LIB_APP	CODE_ENT	LIB_ENT
29			APP1		939			T1
299			APP1		940			T2
299			APP1		941			T3
39			APP2		1296			T1
39			APP2		1297			T2
39			APP2		1298			T3
C'est plutôt dans l'alimentation du treeview que ca coince ;)

Petit complément, j'ai récupéré le code de FALSAM (sqlLite Explorer) et après quelques adaptations, ça fonctionne.

Code : Tout sélectionner

;Affichage de la liste des Application et de leurs entités
Procedure DataBaseListTable()
  Protected ReqSql.s, Appli.s, Buffer.s , Dim Applis.s(0), n
  ;Extraction de la liste des Applications
  ReqSql="Select * From carto_application order by lib_app"
  If DatabaseQuery(#Database, ReqSQL) 
    While NextDatabaseRow(#Database)
      If Len(GetDatabaseString(#Database,0)) > 0
        Applis(n) = GetDatabaseString(#Database,1)
        n+1 : ReDim Applis(n)
      EndIf 
    Wend
    For n = 0 To ArraySize(Applis()) -1
      AddGadgetItem(#ListApplis, -1, Applis(n))
      ReqSql = " Select * From carto_entite, carto_application "+
               " where carto_entite.fk_code_app = carto_application.code_app "+
               " and carto_application.lib_app = '"+Applis(n)+"' order by nom_entite;"
      If DatabaseQuery(#Database, ReqSql)
        While NextDatabaseRow(#Database)
          AddGadgetItem(#ListApplis, -1, GetDatabaseString(#Database,2), 0, 1)
        Wend
      EndIf
    Next
  EndIf
EndProcedure
Répondre