Si vous avez un jour tenté de lier un source de données MS Access, requête ou table, à Excel, vous avez sûrement été confronté à l’interprétation aléatoire des champs mémo.
Aléatoire ? Pas tant que ça. Il faut savoir que pour réaliser un export à partir du menu DONNEES EXTERNES / Exporter Excel, MS Access ne se base non pas sur la structure du champ mais sur le contenu des premières lignes. Si dans ces premières lignes il rencontre un contenu de plus de 255 caractères il considère ce champ comme mémo (texte long)… et là tout va bien.
Dans le cas contraire, il tronquera tout le reste à 255 caractères qui est la limite du format Texte Court, anciennement Texte. Adieu vos 32 000 caractères suivant !
Info : Un champ Texte Long, anciennement Mémo, de la base de données
Jet (Ms ACCESS) et d'une capacité de 65 535 caractères exactement.
Une cellule MS EXCEL en contient tout au plus 32 767.
Il en manquera toujours un peu.
On peut donc oublier l’export CSV ou depuis la commande MS Access, à part faire un tri sur le nombre de caractères de votre champ mémo, si techniquement cela ne pose aucun problème fonctionnellement cela peut ne pas convenir. On ne sera jamais sûr d’avoir la totalité du contenu.
Heureusement, il existe un méthode, certes un peu plus complexe mais également plus efficace. Il s’agit de l’automation. Autrement dit, piloter Excel depuis Access. Il existe une méthode de copie de recordset disponible avec VBA Excel.
CopyFromRecordset
Cette méthode est disponible dans Excel sans ajout de bibliothèque (Références) car il faut le savoir, Excel est un consommateur de Recordset à ses heures.
Voici le code commenté :
Function fInsertInSheet(ByVal strPath As String, ByVal strFeuille As String, rst As Recordset2) As Boolean '----------------------------------------------------------------- ' Procedure : fInsertInSheet ' Author : Fabrice CONSTANS (MVP) ' Date : 21/01/2014 ' Purpose : Insère un ou plusieurs enregistrements issu de RST ' dans la feuille excel strFeuille du fichier strPath ' utilise fFieldFormated() et ADODB ' Parameters: strPath = chemin+nom du fichier Xls au format 12.0 ' strFeuille = la feuille dans laquelle insérer l'enrg ' rst = le recordset contenant les données à insérer ' Return : Boolean renvoi vrai si insertion réussie '----------------------------------------------------------------- 'Ecrit le recordset transmis dans la feuille indiquée Dim strSql As String Dim i As Long Dim l As Long 'Late Binding Dim oExcel As Object ' Excel application Dim oFeuille As Object ' la feuille Dim oWork As Object ' le workbook Dim boolStateDisplayAlerts As Boolean Dim boolStateAskToUpdateLinks As Boolean On Error GoTo Errsub Set oExcel = CreateObject("Excel.Application") oExcel.Visible = False 'enregistre l'état boolStateDisplayAlerts = oExcel.DisplayAlerts boolStateAskToUpdateLinks = oExcel.AskToUpdateLinks 'met en mode silentieux oExcel.AskToUpdateLinks = False oExcel.DisplayAlerts = False Set oWork = oExcel.Workbooks.Open(strPath) ' ouvre le classeur Set oFeuille = oWork.Sheets(strFeuille) ' active la feuille 'xlByRows, xlPrevious l = 1 'insertion en ligne 1 oFeuille.Cells(l, 1).CopyFromRecordset rst 'copie recordset oExcel.Windows(1).Visible = True oWork.Save 'on le sauve 'remet à l'état d'origine oExcel.DisplayAlerts = boolStateDisplayAlerts oExcel.AskToUpdateLinks = boolStateAskToUpdateLinks oExcel.Visible = True oExcel.Quit Set oFeuille = Nothing ' vide les objets xls Set oWork = Nothing Set oExcel = Nothing fInsertInSheet = True 'ça c'est bien passé ! Exitsub: On Error GoTo 0 Exit Function Errsub: fInsertInSheet = False 'il y a un problème 'mettre ici une gestion d'erreur ou un msg End Function
Conclusion
Voilà un code pas si mystérieux où l’on ouvre un recordset coté Access pour le copier dans la feuille Excel. Plus d’informations sur le LateBinding.
Bonne utilisation !