[VS2005][ODBC][comprends rien...]

Bonjour à tous,

Dans mon auto-formation permise par le relâchement temporaire des projets internes du client chez qui je bosse actuellement, je me suis heurté à un souci bien pénible sous Visual Studio 2005 (team edition, mais on s’en cogne).

Pour faire simple, je n’arrive pas à comprendre comment faire pour que le DataGridView situé dans ma fenêtre principale d’appli mette à jour les modifications.

Pour faire détaillé, ma fenêtre comprends un objet ODBCConnection correctement initialisé, un DataGridView et un BindingSource.

J’ai récupéré dans l’aide une fonction retournant un DataTable permettant de remplir le DataGridView automatiquement (cf la fonction et son appel plus bas) et tout fonctionne au niveau de l’affichage.

Maintenant, je n’arrive pas une fois les données modifiées à appliquer les modifications en base de données.

C’'est une application toute bête de définition des droits qui ne tape que sur une table (sans primary key, je sais c’est une horreur, mais un champs peut servir de discriminant).

Autres détails, le ODBCConnection et le DataTable sont déclarés au niveau de l’objet, pas de la procédure. Il n’y a pas de souci de portée, donc.

Alors, voici déjà la petite fonction retournant le DataTable (merci l’aide MSDN) :

private DataTable GetData(string sqlCommand) { try { OdbcCommand loComm = new OdbcCommand(sqlCommand, ioCnx); OdbcDataAdapter loAdapt = new OdbcDataAdapter(); loAdapt.SelectCommand = loComm; DataTable loTable = new DataTable(); loTable.Locale = System.Globalization.CultureInfo.InvariantCulture; loAdapt.Fill(loTable); return loTable; } catch (Exception e) { MessageBox.Show(string.Concat("Erreur lors du chargement de la requête :\n", e.Message), "Erreur SQL", MessageBoxButtons.OK, MessageBoxIcon.Error); return null; } }

Et son appel

ioTable = GetData(string.Concat("SELECT NOM_USER, DROIT1, DROIT2 FROM UTILISATEURS", lsFiltre)); bsUtil.DataSource = ioTable; if (bsUtil.DataSource == null) { SetStatus("Erreur lors du chargement, vérifiez le filtre"); return; } dgUtilisateurs.DataSource = bsUtil; dgUtilisateurs.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.DisplayedCellsExceptHeaders; dgUtilisateurs.BorderStyle = BorderStyle.Fixed3D; dgUtilisateurs.EditMode = DataGridViewEditMode.EditOnEnter;

Pour la fonction de mise à jour, j’ai essayé de tripatouiller les fonctions CommitEdit(), EndEdit(), AcceptChanges() respectivement du DataGridView, du BindingSource et du DataTable mais aucune modification n’a été apportée à la table.

J’imagine qu’il faut définir sur quelle colonne lancer la commande d’update mais je n’ai pas trouvé comment y arriver, quelqu’un peut m’aider please ?

Merci du temps passé à lire et encore plus du temps passé à répondre si vous savez :P.

Je posterais demain quand j’aurais dix minutes…

J’attends ça avec impatience, merci :stuck_out_tongue:

Je continue mes recherches pendant ce temps…

edit : mais que ça n’empêche pas les autres de répondre, si vous voulez !

Petit up désespéré, si quelqu’un m’entends, à l’aide ! :stuck_out_tongue:

Ha merde completement oublié, desole :stuck_out_tongue:
La j’ai trop pas le temps aujourd’hui… Il y a des articles sympa sur MSDN cela dit, je sais pas si t’as vu?

http://msdn2.microsoft.com/en-us/library/4esb49b4.aspx
http://msdn2.microsoft.com/en-us/library/0…97z(VS.80).aspx
http://msdn2.microsoft.com/en-us/library/m…767(VS.80).aspx

http://msdn.microsoft.com/library/default…rms11162004.asp
(Part 1/2/3)
http://www.codeproject.com/cs/database/DataGridView2Db.asp

Yes, j’y suis arrivé !

Il faut en fait passer par l’objet OdbcDataAdapter.
Je l’ai donc redéfini en objet privé de la fenêtre pour qu’il soit accessible à l’ensemble des procédures puis j’ai défini sa propriété UpdateCommand en lui balançant la requête SQL d’UPDATE.
Une fois ceci fait, j’ai ajouté les paramètres à mettre à jour (un à un, ce qui est un peu longuet et pas très élégant mais bon, on s’en fout, pour l’instant ça marche) et il suffit dans la fonction de mise à jour d’exécuter la fonction Update() en lui fournissant le datatable déjà défini avant.

Ce qui donne dans la fonction de chargement du tableau l’ajout de ces lignes :

OdbcCommand loCmd = new OdbcCommand("UPDATE UTILISATEURS SET DROIT1 = ?, DROIT2 = ? WHERE NOM_UTIL = ?", ioCnx); ioAdapt.UpdateCommand = loCmd; ioAdapt.UpdateCommand.Parameters.Add("@DROIT1", OdbcType.VarChar, 1, "DROIT1"); ioAdapt.UpdateCommand.Parameters.Add("@DROIT2", OdbcType.VarChar, 1, "DROIT2"); ioAdapt.UpdateCommand.Parameters.Add("@NOM_UTIL", OdbcType.VarChar, 32, "NOM_UTIL");

et dans la fonction d’enregistrement la ligne

Merci pour les liens GloP, ça m’a mis sur la voie.

J’imagine qu’il existe des solutions bien plus élégantes et moins génératrice de code (j’imagine que si la primary key avait été définie, j’aurais pu modifier une propriété du genre d’auto génération des paramètres ou un truc comme ça) mais là ça fonctionne et c’est l’essentiel !