Entrées de liste à partir de données d'une table dans une boîte de dialogue

Bonjour

Je travaille sur Base. Pour l’exemple, j’ai une table avec un champ ID (int), un champ CASE (string), et un champ PREVIOUS_CASE (int). Ce dernier champ peut être vide ou faire référence à un cas déjà existant, indiquant alors l’ID du cas existant auquel il est lié. Par ex :
ID; CASE; PREVIOUS_CASE
0; cas_1
2; cas_2; 0
3; cas_3

Dans une boîte de dialogue, je veux mettre une boîte de liste, qui liste l’ensemble des entrées de ma table, en affichant uniquement le champ CASE, par ex “cas_1”, “cas_2”, cas_3", etc.
Je ne sais pas comment alimenter cette boîte de liste. Il y a bien une ligne “Entrées de liste” lors de la configuration de la boîte de liste, mais j’ai l’impression qu’il faille rentrer les entrées à la main.
N’existe-t-il pas un moyen, par ex, de rentrer une commande SQL ?
Si non, quelle pourrait être une alternative …?

En plus, dans ma macro d’enregistrement de la boîte de dialogue, j’aimerais pouvoir conserver non pas la valeur renseignée CASE, mais la valeur ID du même enregistrement dans la table.
Par ex, je rentre un nouveau case (“cas_4”). Ce cas est lié au “cas_1”. Dans la liste de la boîte de dialogue, je veux que s’affiche “cas_1”, “cas_2”, cas_3", mais à l’enregistrement de mon cas_4, je veux que la valeur attribuée à PREVIOUS_CASE indique “0” (correspondant à l’ID du cas_1).
Cela est-il envisageable ?

D’avance merci pour votre aide !

Benjamin

[EDIT]

Précisions de la demande en réponse aux questions de @PYS ci-dessous :

  • une table “relation” pourrait être effectivement une solution, je n’y avais pas pensé, merci !
  • je me trompe peut-être, mais j’ai trouvé plus “ergonomique” pour l’utilisateur final de fonctionner comme ça. En fait, j’ai un formulaire “principal”, qui fait appel à plusieurs autres tables (via des boîtes de liste). Depuis ce formulaire principal, on doit pouvoir intégrer de nouvelles données dans ces tables “annexes” (ex un nouveau cas, une nouvelle localité, une nouvelle image, etc.), pour être disponibles dans les listes du formulaire principal. Pour ne pas naviguer de formulaire en formulaire, ou ne pas avoir une page très longue avec beaucoup de sous-formulaires, la solution que j’ai envisagée est les boîtes de dialogue, accessibles via des boutons (actuellement, j’en ai 7 + un bouton “Refresh” du formulaire principal), évitant de “perdre” l’utilisateur dans de trop nombreux formulaires, mais plutôt en le “fixant” sur le formulaire principal.
  • par rapport à me demande ci-dessus, je veux effectivement afficher une valeur dans la liste, et enregistrer une autre (mais complètement associée) car la valeur à enregistrer est un identifiant, donc indigeste pour l’utilisateur final. La valeur affichée, au contraire, correspond à la référence du cas (un peu comme un label), format que l’utilisateur final maîtrise complètement.

Re-bonjour,

J’ai finalement pu trouver une solution à mon premier besoin, en ajoutant quelques lignes glanées sur internet, dans la macro d’ouverture de la boîte de dialogue :

Dim Dlg As Object
Sub OpenDialogNewCase()
Dim previous_case_ref As Object
DialogLibraries.LoadLibrary("Standard")
Dlg = CreateUnoDialog(DialogLibraries.Standard.DialogCaseNew)

'Connection to the database and SQL select command to get the case references (case_ref)'

oDatasource = thisDatabaseDocument.CurrentController
If Not (oDatasource.isConnected()) Then
oDatasource.connect()
End If
oConnection = oDatasource.ActiveConnection()
oSQL_Command = oConnection.createStatement()
stSql = "SELECT ""case_ref"" FROM ""TableCase"""
oResult = oSQL_Command.executeQuery(stSql)

' Transfer of the SQL result set into a string array to be display in the dialog box'
' and add an extra entry for "No link with previous case"'

dim res(0) as string, n as integer
res(0) = "No link with previous case"
n = 1
while oResult.next
redim preserve res(n)
res(n) = oResult.getString(1)
n = n + 1
wend

' Get control of the list box and display all the existing case references'

previous_case_ref = Dlg.getControl("DialogListPreviousCase")
previous_case_ref.addItems(res, 0)

' Display the dialog'

Dlg.Execute()
Dlg.Dispose()
End Sub

(Désolé pour la coloration, je ne comprends pas pourquoi certains blocs sont colorés correctement et d’autres non…)


Pour le second besoin, j’ai rajouté, dans une macro associé à un bouton ‘Save’ de ma boîte de dialogue, les étapes de :

  • récupérer la valeur sélectionnée dans la liste, et modifié la valeur si sélectionné auparavant “No link with previous case” :

      previous_case_ref = Dlg.getControl("DialogListPreviousCase").SelectedItem
      If previous_case_ref = "No link with previous case" Then
      previous_case_ref = ""
      End If
    
  • Trouver l’ID équivalent au case_ref par une requête SQL Select, pour injecter ce résultat dans un nouvel enregistrement, via une autre requête SQL Insert Into (une variable previous_case_ref_int a été définie comme entier pour cela) :

      stSql = "SELECT ""ID"" FROM ""TableCase"" WHERE ""CASE"" = '"+previous_case_ref+"'"
      oResult = oSQL_Command.executeQuery(stSql)
      While oResult.next
      	previous_case_ref_int = oResult.getInt(1)
      Wend
      stSql = "INSERT INTO ""TableCase"" (""CASE"", ""PREVIOUS_CASE"") "
      stSql = stSql & "VALUES ('"+case_ref+"'," & previous_case_ref_int & ")"
      oSQL_Command.executeUpdate(stSql)
    

Cela semble fonctionner très bien lorsqu’on rentre un nouveau cas qui est lié à un autre.

Cependant, si le nouveau cas rentré n’est lié à aucun autre, l’enregistrement se fait, mais est “faux” car il renseigne la valeur 0 dans le champ PREVIOUS_CASE, alors qu’il devrait y avoir une case vide (ou NULL).
Comment cela pourrait être résolu ?

Merci d’avance pour toute aide !

Benjamin


[EDIT]

Il semblerait qu’une solution vienne de la déclaration de la variable previous_case_ref_int dans la macro (cf. aussi forum anglais). Celle-ci était déclarée en INTEGER, ce qui fait (j’imagine…) que n’était pas reconnu “NULL”, qui était alors retranscrit en 0 (comme tout autre chaîne de caractère) dans la variable previous_case_ref_int, et en ricochet dans la table CASE via la commande SQL.

Déclarer la variable previous_case_ref_int en STRING n’a pas fonctionné.

Par contre, déclarer previous_case_ref_int en VARIANT permet de considérer à la fois des valeurs de nombres entiers et de chaînes de caractères. Ensuite, l’exécution de la commande SQL semble gérer la conversion du VARIANT vers le type de la table (en l’occurrence, dans mon cas, SMALLINT).
Et en ayant testé, le choix “No link with previous case” dans ma boîte de dialogue résulte bien, d’une part, en absence d’erreur dans la macro (et donc dans l’exécution du SQL INSERT INTO), et d’autre part, en une absence de valeur dans le champ PREVIOUS_CASE de ma table CASE

À noter: une absence de valeur, et non un affichage de “NULL”. Cependant, une requête SQL

select * from "CASE" where "PREVIOUS_CASE" is null

renvoie correctement les enregistrements pour lesquels l’option “No link with previous case” avait été choisie.

Ainsi, le bout de macro suivant permet de faire ce que je souhaitais (cf. 2nde puce ci-dessus) :

DIM previous_case_ref_int AS VARIANT
stSql = "SELECT ""ID"" FROM ""TableCase"" WHERE ""CASE"" = '"+previous_case_ref+"'"
oResult = oSQL_Command.executeQuery(stSql)
If oResult.next Then
    previous_case_ref_int = oResult.getInt(1)
Else
    previous_case_ref_int = "NULL"
End If
stSql = "INSERT INTO ""TableCase"" (""CASE"", ""PREVIOUS_CASE"") "
stSql = stSql & "VALUES ('"+case_ref+"'," & previous_case_ref_int & ")"
oSQL_Command.executeUpdate(stSql)

Précision: par rapport à précédemment, la déclaration en VARIANT a été ajoutée, et le While … Wend remplacé par une boucle If … Then … Else … End If.

Bonjour

Tu aurais dû éditer ta première question pour la compléter, plutôt qu’utiliser la fonction Ajouter une réponse. Étant marquée comme ayant obtenu une réponse, cette question m’avait échappé…

Sur le fond je ne comprends pas un certain nombre de choses :

  • pourquoi ne pas créer une table “relation” pour gérer précédent/suivant ?
  • pourquoi ne pas utiliser des formulaires au lieu des dialogues ?
  • les contrôles de liste permettent d’afficher une valeur et d’en enregistrer une autre (la valeur référentielle)

Pour terminer avec la valeur 0 dans le champ PREVIOUS_CASE, le champ ne serait-il pas simplement défini avec cette valeur par défaut ?

Merci d’utiliser de préférence l’ajout de commentaire pour répondre, voire l’édition de ta question si tu souhaites joindre un fichier (un exemple de base permettrait aux bénévoles qui tentent d’aider d’éviter de créer de toute pièces une bdd).

Pour ce qui concerne la coloration sur ce site, les lignes de code commentées avec la quote doivent également finir avec une quote (j’ai procédé à la modification dans ta question). Ceci n’est pas nécessaire avec les lignes commentées par le mot-clé REM.

Je me permets de te suggérer la lecture du guide Base qui comprend vraiment l’essentiel et un peu plus…

Cordialement

Bonjour,

Merci pour tous ces conseils, précisions, et adaptations du code ! Bien noté pour la coloration des commentaires, et la préparation d’un fichier exemple pour la prochaine fois.

Pour répondre aux questions, j’ai édité mon premier post.

Également, pour la valeur 0, j’ai consacré un post dédié sur le forum anglais, en ajoutant un fichier joint avec un exemple de table, pour montrer comment cela est déclaré (pas demandé de valeur par défaut…). Je viendrai indiquer également la solution ici si quelque chose apparaît.

J’ai déjà parcouru quelques sections du guide Base, mais il serait effectivement bon pour moi de le reprendre plus sérieusement…

Cordialement.