Problème d'actualisation de formulaire

Salut.

J’ai toujours quelques difficultés avec Base ; présentement, je m’emmêle les pinceaux avec « Commit », « Reload » et « Refresh ».

Petite base exemple :

test_base.odb (55.2 KB)

En fonction de ce que j’ai pu trouver, j’ai bricolé cette macro afin qu’à partir d’une table de valeurs par défaut comprenant 2 colonnes et 1 ligne, les 2 valeurs soient copiées dans les cellules correspondantes du formulaire de saisie (champs de table) de factures (afin d’éviter une saisie manuelle qui peut s’avérer vite fastidieuse).

Sub InsertionAnneeMois()

	Dim Context As Object
	Dim Database As Object
	Dim Connection As Object
	Dim Statement As Object
	Dim strSQL As String
	Dim oForm As Object
	Dim oDate As Object
	
	Context = CreateUnoService("com.sun.star.sdb.DatabaseContext")
	Database = Context.GetByName("test_base")
	Connection = Database.GetConnection("","")
	Statement = Connection.CreateStatement()

	strSQL = "INSERT INTO T_FACTURES (FAC_ANNEE, MOI_ID) SELECT VDE_ANNEE, VDE_MOIS FROM T_VALEURS_DEFAUT"
	Statement.ExecuteUpdate(strSQL)

	Connection.Close()
	
	oForm = ThisComponent.DrawPage.Forms.GetByName("frmFacturation")
	oForm.Reload()
	oForm.Last()
	
End Sub

La macro plante au niveau de Statement.ExecuteUpdate(strSQL), indiquant que je cherche à insérer une valeur NULL dans un champ NOT NULL. Je pense qu’il s’agit d’une question de « rafraîchissement » du formulaire qui s’effectue avant que toutes les données soient saisies.

Mode opératoire actuel :

  1. Bouton « Nouvel enregistrement » (voir macro correspondante).
  2. Bouton « Insérer année et mois ».

L’idéal serait d’exécuter les deux macros en un seul bouton.

Je vous remercie par avance.

Bonjour @Primus

Le message te donne le nom du champ concerné SAL_ID et en effet tu l’as défini en Entrée requise : Oui

Cordialement

C’est normal que l’entrée du salarié soit requise. Mais même si je sélectionne d’abord ledit salarié, j’ai le message d’erreur quand j’exécute la macro.

Bien sûr car la modification n’est pas enregistrée…

Au lieu d’insérer un enregistrement tu devrais modifier la valeur des contrôles. Par exemple pour insérer le texte 2022 dans l’année et sélectionner le mois d’avril :

dim oCtrl
oCtrl = oEvt.source.model.parent.getByName("txtFacAnnee")
oCtrl.Text = "2022"
oCtrl = oEvt.source.model.parent.getByName("lstMoiId")
oCtrl.selectedItems() = array(3)

C’est donc un problème d’actualisation des données qui devrait être fait avant l’insertion des deux valeurs et que je ne sais pas résoudre. Je précise que dans une autre base, lorsque l’insertion se fait dans un sous-formulaire, cette macro fonctionne parfaitement.

Ta proposition ne me convient pas. Chaque début de mois, lorsqu’on saisit les factures concernant le mois précédent, ça obligerait l’utilisateur a modifier la macro. Et dans ce cas, il serait plus simple de s’en passer et d’indiquer des valeurs par défaut (en éditant le formulaire) dans les champs correspondant.

Tu n’as pas compris ma proposition. Je n’ai donné que le code qui permet de mettre à jour les contrôles. J’ai supposé que tu savais rechercher les valeurs dans la table pour remplacer dans mon exemple les valeurs fixes (2022 et avril). Puisque cela semble poser problème voir ci-dessous le codage complété.

sub InsertionAnneeMois(oEvt)

dim oConnexion as object, oRequete as object, oResult as object, oCtrl as object
dim sSQL as string

oConnexion = oEvt.source.model.parent.ActiveConnection

sSQL = "SELECT VDE_ANNEE, VDE_MOIS FROM T_VALEURS_DEFAUT"
oRequete = oConnexion.createStatement()
oResult = oRequete.executeQuery(sSQL)
oResult.next

oCtrl = oEvt.source.model.parent.parent.getByName("txtFacDate")
oCtrl.Date = CDateToUnoDate(Date())
oCtrl.commit
oCtrl = oEvt.source.model.parent.parent.getByName("txtFacAnnee")
oCtrl.Text = oResult.columns.getByName("VDE_ANNEE").string
oCtrl.commit
oCtrl = oEvt.source.model.parent.parent.getByName("lstMoiId")
oCtrl.selectedItems() = array(oResult.columns.getByName("VDE_MOIS").double - 1)
oCtrl.commit

end sub

Autre proposition d’amélioration, dans la base jointe j’ai créé un nouveau bouton “Insertion nouvel enregistrement” qui utilise l’action de même nom (au lieu de lancer ta macro). Ceci est nettement plus rapide.

test_base.odb (56,1 Ko)

Non, je n’avais pas compris ça (j’ai du mal à percuter pour tout ce qui est programmation) mais là évidemment, ça fonctionne et je te remercie. J’ai ajouté ça dans ta macro :

Dim oForm As Object
    oForm = ThisComponent.Drawpage.Forms.getByName("frmFacturation")
    oForm.FetchSize = 5000
    oForm.moveToInsertRow()

Ce qui permet ainsi de faire la chose en un seul clic.

Et j’avais encore un truc qui ne fonctionne pas : l’actualisation du total lorsque le sous-total de chaque ligne se met à jour. J’ai tenté ça :

Sub ActualiserTotal()

	Dim oForm As Object
	Dim oSubForm As Object
	Dim oTotal As Object
  
    oForm = ThisComponent.Drawpage.Forms.getByName("frmFacturation")
    oSubForm = oForm.getByName("frmFacturationTotal")
    oTotal = oSubForm.GetByName("txtFacTot")
	oTotal.Commit
    
End Sub

Mais rien à faire (actuellement attribuée à “Après l’actualisation” de la colonne FAC_STOT dans le sous-formulaire étant donné que je navigue dedans par tabulation).

Il faut :

  • associer la macro à l’événement Après l’action d’enregistrement du sous-formulaire frmFacturationSub.
  • modifier la macro comme ci-dessous
Sub ActualiserTotal()

	Dim oForm As Object
	Dim oSubForm As Object

    oForm = ThisComponent.Drawpage.Forms.getByName("frmFacturation")
    oSubForm = oForm.getByName("frmFacturationTotal")
    oSubForm.reload
    
End Sub

Alors c’est parfait. Juste une dernière chose. Supposons que pour la macro on doive extraire dans une table la valeur d’un champ cette fois-ci de type date pour l’insérer automatiquement ; cette ligne s’écrierait comment ?

oCtrl.Text = oResult.columns.getByName("CHAMP_DATE").string

Édit : j’ai trouvé.

oCtrl.Date = oResult.columns.getByName("CHAMP_DATE").Date

Merci pour tout. :slightly_smiling_face: