Connexion ADODB quel provider pour Office 2013 64bits
Bonjour les pros
Je suis confronté à un problème de connexion ADODB sur Excel 2013 version 64 bits
La "base de données" est un fichier excel 2003 ".xls"
Dans ma société nous avons 2 versions d'office installées
- Office 2010 32bits
- Office 2013 64bits
Début du code
' Créer une nouvelle instance ADO
Set Cnn = CreateObject("ADODB.Connection")
' Créer la connexion selon la version d'Excel
Ensuit
Pour Office 2010, pas de soucie j'utilise la connexion
Set Conn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=MaSourceBdD#;Extended Properties='Excel 8.0;HDR=YES';"
Pour office 2013 en revanche je voulais utiliser
Set Conn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=MaSourceBdD#;Extended Properties='Excel 8.0;HDR=YES';"
Mais là, la connexion ne se fait pas
Qui sait ce que je dois faire pour que ça fonctionne ?
Par avance merci
Bonjour Bruno,
Pour ce type de connexion j'utilise plutôt :
Set Cnx = CreateObject("ADODB.Connection")
Cnx.Provider = "MSDASQL"
Cnx.Open "Driver={Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb)};" & _
"DBQ=" & NDF & "; ReadOnly=False;"
dans lequel NDF contient le chemin + le nom du xls à interroger
Ça fonctionne sur toutes les versions d'Office
Pierre
Salut Pierre
Heureux de te voir par ici
Ca marche mieux, mais j'ai toujours un souci lorsque je veux créer ma requète avec ma condition
Ca me renvoit 0 enregistrement !?
Ma constante publique
' Chaine de connextion pour accès en BdD
Public Const sConnect As String = "Provider=MSDASQL;Driver={Microsoft Excel Driver (*.xls, *.xlsx, *.xlsm, *.xlsb)};DBQ=#sPathBdD#;ReadOnly=True"
Mon code de remplissage d'une ListeBox
Sub RemplirLbxCrit(ObjLbx As MSForms.ListBox, sPathBdD As String, sTable As String, sCrit As String, vCrit As String)
Dim sRqt As String, sCond As String, Sql As String
Dim NbField As Integer, NbRecord As Integer
' En cas d'erreur
FlgErrCon = False
On Error GoTo Erreur_Proc
' Vider la combobox en question
If ObjLbx.ListCount > 0 Then ObjLbx.Clear
' Créer une nouvelle instance ADO
Set Cnn = CreateObject("ADODB.Connection")
' Créer la connexion selon la version d'Excel
sConn = Replace(sConnect, "#sPathBdD#", sPathBdD, Compare:=vbTextCompare)
' Ouvrir la connexion
Cnn.Open sConn
' En cas d'erreur utliser
If FlgErrCon = True Then
MsgBox "Impossible de se connecter à la base de données!", vbCritical, "OUPS..."
End
End If
' Préparer la requête
If InStr(1, sTable, " ") > 0 Then
Sql = "SELECT * FROM ['" & sTable & "$']"
Else
Sql = "SELECT * FROM [" & sTable & "$]"
End If
' Définir la condition
If InStr(1, vCrit, "*") > 0 Then
' COndition en SQL = WHERE (DESIGNATION_TACHES Like '%BTA%')
sCond = "WHERE (" & sCrit & " Like '" & Replace(vCrit, "*", "%") & "');"
Else
sCond = "WHERE (" & sCrit & "=""" & vCrit & """);"
End If
' Créer la syntaxe de la requête
sRqt = Sql & " " & sCond
' Créer un nouveau Recordset et l'ouvrir
Set Rs = CreateObject("ADODB.Recordset")
Rs.Open sRqt, Cnn, CursorType
' Nombre de champ
NbField = Rs.Fields.Count - 1
' Pour chaque enregistrement
For NbRecord = 0 To Rs.RecordCount - 1
' Ajouter les champs au combobox
ObjLbx.AddItem Rs(2)
ObjLbx.List(ObjLbx.ListCount - 1, 1) = Rs(3)
ObjLbx.List(ObjLbx.ListCount - 1, 2) = Rs(4)
' Passer à l'enregistrement suivant
Rs.MoveNext
Next NbRecord
' Fermeture du recordset
Rs.Close: Set Rs = Nothing
' Fermeture de la Bdd
Cnn.Close: Set Cnn = Nothing
Exit Sub
Erreur_Proc:
LogError Err, "Sub RemplirLbxCrit(ObjLx" & ObjLbx.Name & ", sPathBdD=" & sPathBdD & ", sTable=" & sTable & ", sCrit=" & sCrit & ", vCrit=" & vCrit & ")"
FlgErrCon = True ' Mettre le FLAG d'erreur de connexion à vrai
Resume Next
End Sub
A+
Tu peux peut être faire plus simple, du genre :
Rs.Open sRqt, Cnn, CursorType ' j'utilise plutôt Rs.Open sRqt, Cnn, adOpenStatic
If Not Rs.RecordCount = 0 Then
Rs.MoveFirst
ObjLbx.List = Rs.GetRows
end if
(et avant tu aura sélectionné uniquement les champs qui vont bien : SELECT champs1, champs2 FROM ...)
Pierre
RE
Je ne peux pas utiliser cette méthode, car je dois impérativement filtrer mes enregistrements
Ce sont une liste de tâches en fonction d'un type de travail
pierrep56 a écrit :Tu peux peut être faire plus simple, du genre :
Rs.Open sRqt, Cnn, CursorType ' j'utilise plutôt Rs.Open sRqt, Cnn, adOpenStatic If Not Rs.RecordCount = 0 Then Rs.MoveFirst ObjLbx.List = Rs.GetRows end if
(et avant tu aura sélectionné uniquement les champs qui vont bien : SELECT champs1, champs2 FROM ...)
Pierre
A+
Re,
pierrep56 a écrit :Ben, tu les filtres directos dans ta requête!?
Et bien c'est justement ce que je fais dans mon code
...
' Préparer la requête
If InStr(1, sTable, " ") > 0 Then
Sql = "SELECT * FROM ['" & sTable & "$']"
Else
Sql = "SELECT * FROM [" & sTable & "$]"
End If
' Définir la condition
If InStr(1, vCrit, "*") > 0 Then
' COndition en SQL = WHERE (DESIGNATION_TACHES Like '%BTA%')
sCond = "WHERE (" & sCrit & " Like '" & Replace(vCrit, "*", "%") & "');"
Else
sCond = "WHERE (" & sCrit & "=""" & vCrit & """);"
End If
' Créer la syntaxe de la requête
sRqt = Sql & " " & sCond
' Créer un nouveau Recordset et l'ouvrir
Set Rs = CreateObject("ADODB.Recordset")
Rs.Open sRqt, Cnn, CursorType
...
Voil a quoi ressemble mon SQL
SELECT * FROM ['RX SIMPLE$'] WHERE (TYPE_TRAVAUX="TRAVAUX AERIEN SUR EXISTANT");
Sans le "WHERE" j'ai bien tous les enregistrements
Mais aucun enregistrement est retourné alors que j'en avais avant
A+
Je ne sais pas si ça répondra à ta question, mais regarde cet exemple simplex de mise en œuvre d'un requêteur pour alimenter des combo en cascade, avec un seul "constructeur" de requête
Ça te donnera peut être des idées
A noter :
* qu'il suffit d'adapter uniquement le driver pour pouvoir interroger des bases Access, FoxPro, dBase, MySql, Sql Server, AS400, ...
* que le requêteur accepte les SELECT, INSERT, UPDATE (et DELETE hors fichier excel)
* que le requêteur renvoie une valeur qui est = au nb de lignes trouvées ou = -1 en cas d'erreur (pour pouvoir tester)
Pierre
PS : sinon autre exemple pus complet
PS2 de 17h53 : après relecture de ton code essaie les simples quotes : sCond = "WHERE " & sCrit & "='" & vCrit & "'"
Bonjour,
Fais un
début.print rs(0).name
je n vois ps la notion de prise en compte du header dns ta collection, mais el même temps je métrise pas trop le 64bits!
Bonjour,
Fais un
début.print rs(0).name
je n vois ps la notion de prise en compte du header dns ta collection, mais el même temps je métrise pas trop le 64bits!
Ah, je vois, avec un intitulé contenant une apostrophe il faut "échapper" l'apostrophe.
Pour ça, je me suis fait une 'tite fonction :
Function Esc(S As String) As String
Esc = Replace(S, "'", "''")
End Function
et tu l'apelles tout simplement :
sCond = "WHERE " & sCrit & "='" & Esc(vCrit) & "'"
Re,
Décidément, je n'y arrive pas, même avec la fonction "Esc"
Si je choisi "Monteur", il n'y a pas d'apostrophe, et bien n'est retourné !?
Merci pour le temps qu tu me consacres
A+
Salut Bruno,
Effectivement, j'ai déjà vu un soucis de compatibilité avec ADODB sous Office 64 bits.
Ceci dit, il faut vraiment une raison valable pour rester sous Office 64 bits, qui n'a d'intérêt que si on travaille avec des très-très-très gros fichier (genre fichier Word d'une encyclopédie de 40 000 pages)
J'avais fait passer tous les PC (une dizaine de postes seulement) d'un client sous Office 32 bits sans déranger sa gestion courante (administratif, compta, appli métier, mais avec beaucoup de données).
Peux-tu passer sous Office32bits?
Pierre
Salut Pierre
pierrep56 a écrit :Salut Bruno,
Effectivement, j'ai déjà vu un soucis de compatibilité avec ADODB sous Office 64 bits.
Ceci dit, il faut vraiment une raison valable pour rester sous Office 64 bits, qui n'a d'intérêt que si on travaille avec des très-très-très gros fichier (genre fichier Word d'une encyclopédie de 40 000 pages)
J'avais fait passer tous les PC (une dizaine de postes seulement) d'un client sous Office 32 bits sans déranger sa gestion courante (administratif, compta, appli métier, mais avec beaucoup de données).
Peux-tu passer sous Office32bits?
Pierre
Malheureusement pas vraiment
Je suis dans un gros groupe et c'est la DSI qui a décidé de déployer les versions 64bits d'Office
Je leur ai bien indiqué que même Microsoft le déconseille, mais que veux-tu c'est le pot de terre contre le pot en acier trempé
A+
Bonjour PierreP56 bonjour à tous,
Un grand MERCI Pierre pour la syntaxe du provider MSDASQL
En revanche j'ai dù la modifier ainsi, en mettant le DSN et non le Driver
"Provider=MSDASQL;DSN=Excel Files;DBQ=#sPathBdD#;ReadOnly=True;HDR=Yes';"
Merci à Klin89, de m'avoir donné un lien en MP ou le problème est expliqué
Pour ceux qui savent lire l'anglais
The solution to this cryptic error is to install the Microsoft Access Runtime https://www.microsoft.com/en-us/download/details.aspx?id=39358. This tool enables you to share Access databases with users that do not have Access installed, but also installs the missing component not provided by the Click to Run Installation.
Pour moi le problème est résolu
Bonjour à tous,
Petit ajout à la discussion, car cela ne fonctionnait pas sur les versions Office 2013 32bits
J'ai donc ajouté une compilation conditionnelle
' Chaine de connexion pour accès à la BdD
' En fonction de la version Excel 32/64 bits
#If Win64 Then
' Version 64bits
Public Const sConnect As String = "Provider=MSDASQL;DSN=Excel Files;DBQ=#sPathBdD#;ReadOnly=True;HDR=Yes';"
#Else
' Version 32bits
Public Const sConnect As String = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=#sPathBdD#;Extended Properties='Excel 8.0;HDR=Yes'"
#End If
En tout cas ça marche nickel maintenant