[VBA] Manipuler un SQL Server sans risque
Même si la plateforme VBA a plus de 20ans et qu’elle n’a pas bougé depuis, il n’en reste pas moins simple de manipuler des données de SQL Server à partir de macros VBA.
Premières choses :
- Oubliez DAO. Utiliser ADO. Cela fait un paquet d’années qu’ADO à gagner le grand combat qui l’opposait à DAO. Je ne reviendrai pas sur ce sujet qui a fait couler beaucoup d’encre par le passé. Aujourd’hui si vous voulez une solution qui marche partout et sur un Office récent, c’est ADO.
- Oubliez l’idée de « protéger » les chaines de caractères. (ex : il y a une simple cote, donc je dois en mettre deux…)
- Oubliez l’idée de « coder » les caractères spéciaux. (ex : Office n’aimerait pas les accentuations, « à é è ç …»)
Ensuite, on ajoute une référence à ADO. Pensez à regarder si toutes les machines ciblées on le même Office et les mêmes composants ADO de déployer. Si ce n’est pas le cas, on peut toujours utiliser une version inférieure (2.8, 2.6…). Ou alors, on peut télécharger les derniers MDAC pour avoir un composant ADO récent.
Coter code, avec ADO, on peut utiliser des objets commande et paramètre. :
- Dans la commande SQL, chaque paramètre est représenté par un point d’interrogation « ? »
- Les paramètres doivent être ajoutés dans l’ordre de leur présence dans la commande SQL (les noms ne sont là que pour faire propre).
- Les paramètres sont créés via l’objet commandes.
- Les valeurs fournies à chaque paramètre doivent avoir un type défini. C’est ce qui fait qu’il n’y a pas besoin de torturer ses données avant de les utiliser avec SQL Server.
- Les objets ADO, son tous dans un namespace ADODB. Si un type n’est pas préfixé par « ADODB. » il ne provient pas d’ADO (danger !)
Un code valant toujours mieux que de longues explications, voici un exemple d’update suivi d’un exemple de select (le résultat est manipulable avec les fameux Recordset et ses EOF,BOF,…).
Update
' ------------------------------
' Update de la table avec monText en fonction d’un Id
' ------------------------------ Dim connection As New ADODB.connection
Dim command As New ADODB.command
' Ouverture de la connexion
connection.Open connectionString
' Préparation de la commande SQL
command.ActiveConnection = connection
command.CommandText = "UPDATE MaTable SET MonText =? WHERE Id=?"
command.CommandType = adCmdText
' Ajout des paramètres dans l'ordre de la requète SQL
command.Parameters.Append command.CreateParameter("MonText ", adLongVarChar, adParamInput, Len(monText), monText)
command.Parameters.Append command.CreateParameter("Id", adChar, adParamInput, 12, id)
' Execution
command.Execute
' Fermeture
connection.Close
Select
' ------------------------------
' Lecture de monText en fonction d’un Id
' ------------------------------
Dim connection As New ADODB.connection
Dim command As New ADODB.command
Dim recordset As ADODB.recordset
Dim monText As String
' Ouverture de la connexion
connection.Open connectionString
' Préparation de la commande SQL
command.ActiveConnection = connection
command.CommandText = "SELECT MonText FROM MaTable WHERE Id=?"
command.CommandType = adCmdText
' Ajout des paramètres dans l'ordre de la requète SQL
command.Parameters.Append command.CreateParameter("Id", adChar, adParamInput, 12, id)
Set recordset = command.Execute()
' Lecture, sans tests de EOF et BOF pour vérifier qu'il y a un enregistrement
monText = recordset("MonText").Value
connection.Close