Ouvrir un champ OLE Access via VB

Résolu
jplausanne Messages postés 12 Date d'inscription mercredi 17 décembre 2008 Statut Membre Dernière intervention 1 juillet 2012 - 31 janv. 2009 à 09:28
PCPT Messages postés 13272 Date d'inscription lundi 13 décembre 2004 Statut Membre Dernière intervention 3 février 2018 - 1 févr. 2009 à 19:57
Bonjour,

J'ai une base de données Access avec une table contenant un champ OLE dans lequel est introduit (directement par l'utilisateur) (Click Droit, Inserer objet etc...) dans documents Word ou Excel.
Je ne trouve pas le moyen d'ouvrir ces documents depuis VB après avoir accéder à l'enregistrement qui contient ce document .
Par exemple, un des documents Word (introduit dans le champ OLE) doit servir pour un publipostage. Le publiposte fonctionne si le document est externe (on l'appelle alors avec son chemin complet ex: C:\temp\.... ) mais comment accéder à un document stocké dans la bd Access dans un champ OLE (donc l'ouvrir pour ce traitement...).
Pas mal cherché sur le Net... rien trouvé!
Si quelqu'un a une idée... merci d'avance!

19 réponses

PCPT Messages postés 13272 Date d'inscription lundi 13 décembre 2004 Statut Membre Dernière intervention 3 février 2018 47
31 janv. 2009 à 11:49
"dlookup" ? c'est du vb.net çà?....


Vous êtes ici : Thèmes / [forum-VB-NET-VB-2005_40.aspx VB.NET et VB 2005] / [theme-DIVERS_221.aspx Divers] /
1
PCPT Messages postés 13272 Date d'inscription lundi 13 décembre 2004 Statut Membre Dernière intervention 3 février 2018 47
31 janv. 2009 à 10:13
salut,
tu le charges dans un tableau de bytes
après.., çà dépend de ce que ton champ contient
génériquement il te suffit d'écrire ton tableau dans un fichier et de lancer ce fichier par shellexecute
0
jplausanne Messages postés 12 Date d'inscription mercredi 17 décembre 2008 Statut Membre Dernière intervention 1 juillet 2012
31 janv. 2009 à 11:15
Salut et merci pour ta réponse, je continue à m’arracher les cheveux… Je ne suis absolument pas familier avec les tableaux de bytes : je peux bien-sûr chercher mais si tu as des idées…<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /??>





 





Pour le moment, j’en suis là. Je retrouve l’enregistrement contenant le document Word à utiliser pour le publipostage selon différent critères :





 





 





WordDoc = DLookup(Nom du champ OLE, Nom de la table, strfiltre)





 





Et là je ne sais plus quoi faire…. Si j’affiche le contenu de Worddoc je vois des caractères ésotériques… j’imagine que c’est bien le document Word. Mais je ne vois toujours pas comment l’ouvrir ou le traiter (par exemple le sauver sur le disque etc…) ?
0
jplausanne Messages postés 12 Date d'inscription mercredi 17 décembre 2008 Statut Membre Dernière intervention 1 juillet 2012
31 janv. 2009 à 12:29
non non ce n'est pas du vb.net c'est vb 6.3
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
PCPT Messages postés 13272 Date d'inscription lundi 13 décembre 2004 Statut Membre Dernière intervention 3 février 2018 47
31 janv. 2009 à 13:41
ok, sujet déplacé vers VBA

après avoir récupéré ton enregistrement dans une variable abArr() as byte (à toi de trouver en vba acces, je ne sais pas)

récupération chemin TEMP :
http://www.codyx.org/snippet_recuperer-chemin-temp_772.aspx#2291


écriture du tableau dans un fichier temp :
http://www.codyx.org/snippet_enregistrer-tableau-bytes-dans-fichier_5.aspx#1367


çà va te donner :
dim sFile as string
sFile = GetTempPath & "fic.dat"
CreateFileFromBytes sfile, abarr







ensuite tu le visualises :
http://www.codyx.org/snippet_ouvrir-document-lancer-executable_25.aspx#1548


donc
StartProcess sfile




et une petite suppression ensuite :
kill sfile

aucun code, tout est déjà à ta dispo
++


Prenez un instant pour répondre à [sujet-SONDAGE-POP3-POUR-CS_769706.aspx ce sondage] svp 
0
jplausanne Messages postés 12 Date d'inscription mercredi 17 décembre 2008 Statut Membre Dernière intervention 1 juillet 2012
31 janv. 2009 à 15:57
Merci encore infiniment… Je n’aurais pas pensé à cela, je m’attendais à une commande toute simple permettant de lire directement l’objet OLE dans VB depuis l’enregistrement.<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /??>





 





Tout ce qui m’a dit fonctionne : le fichier est bien créé mais il contient des choses illisibles du style (quand il s’affiche dans Word):





�15;�1C;-[1]            �14;ÿÿÿÿDocumentWord.Document.8[1]Word.Document.8bÐÏ�11;ࡱá><hr align="left" width="33%" size="1" />þÿ            �6;[1]þÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿýÿÿÿ
















Par contre si je fais l’opération sur un autre champ (texte) du même enregistrement cela marche : Le texte est bien sauvegardé tel quel dans le fichier.





 





Cela doit donc être la façon dont je récupère le contenu du champ OLE (document Word) qui est fausse et pourtant je n’en vois pas 36 hormis le bon vieux Dlookup (Tout ceci se fait dans un modue Access)! Donc j’investigue encore, nous ne sommes pas loin.





 




Merci encore en tous cas !!!
0
LIBRE_MAX Messages postés 1402 Date d'inscription mardi 1 mai 2007 Statut Membre Dernière intervention 7 octobre 2012 6
31 janv. 2009 à 16:40
Bonjour,
tu peux accèder à ton doc à partir d' un objet Ole en définissant ses propriétés DataSource et DataField.
<hr />

[] Ce qui va sans dire. va mieux en le disant.

<hr />
0
LIBRE_MAX Messages postés 1402 Date d'inscription mardi 1 mai 2007 Statut Membre Dernière intervention 7 octobre 2012 6
31 janv. 2009 à 16:47
Ne pas oublier de configurer


OleTypeAllowed=1-Embedded


Voir aussi la propriété AutoActivate.





<hr />




[] Ce qui va sans dire. va mieux en le disant.


<hr />
0
jplausanne Messages postés 12 Date d'inscription mercredi 17 décembre 2008 Statut Membre Dernière intervention 1 juillet 2012
31 janv. 2009 à 17:11
Merci pour ta réponse… plus ça va plus je m’y perds. La solution qui m’a été proposée avant semble OK mais il semble que l’objet OLE soit récupéré comme du binaire et non comme un document Word.<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /??>







Déjà que VB et moi on n'est pas vraiment copains, je ne comprends pas qu’il soit si difficile de travailler sur un objet OLE stocké dans la base.







Tes propositions


DataSource
, DataField

, OleTypeAllowed=1-Embedded sont certainement intéressantes et, comme elles ne me disent rien à ce stade, je vais chercher. Je ne vois comment tout cela s’articule et s’utilise !












Snif ! je veux simplement ouvrir ce document OLE, depuis un module Access, et éventuellement le copier ailleurs sur le disque pour faire un publiposte avec des données Access (ce publipostage fonctionne bien avec un fichier word sur le disque qu'il suffit de référencer avec son chemin) ! D’autant que si je crée une requête bête comme chou pour accéder à cet objet : je le vois et il suffit de cliquer dessus pour qu’il s’ouvre dans Word.
0
LIBRE_MAX Messages postés 1402 Date d'inscription mardi 1 mai 2007 Statut Membre Dernière intervention 7 octobre 2012 6
31 janv. 2009 à 17:48
Commences par poser un objet Ole sur un formulaire et regardes ce qui se passe.
<hr />

[] Ce qui va sans dire. va mieux en le disant.

<hr />
0
PCPT Messages postés 13272 Date d'inscription lundi 13 décembre 2004 Statut Membre Dernière intervention 3 février 2018 47
31 janv. 2009 à 17:52
sFile = GetTempPath & "fic.doc"
maintenant (je me répète) çà vient en effet de ta lecture du champ....

ne faisant pas de VBA, je ne peux t'aider
en VB6 tu aurais une piste ici : http://faq.vb.free.fr/index.php?question=127
0
PCPT Messages postés 13272 Date d'inscription lundi 13 décembre 2004 Statut Membre Dernière intervention 3 février 2018 47
31 janv. 2009 à 18:03
bon aller un effort, google es-tu là?

[tadaaaaaaaaaa]
http://officesystemaccess.seneque.net/objets_ole.htm
0
jplausanne Messages postés 12 Date d'inscription mercredi 17 décembre 2008 Statut Membre Dernière intervention 1 juillet 2012
1 févr. 2009 à 08:45
c'est déjà fait... mais dans un formulaire c'est facile puisque toute l'interface est là. Le problème que j'ai est hors formulaire. en gros l'utillisateur choisi les personnes à qui le publipostage doit être adressé (dans un formulaire) et clique sur un bouton pour lancer celui-ci. C'est là où j'ai le problème: je recherche (selon des critères) l'enregistrement qui contient le document Word (champ OLE) à utliser pour le publipostage....je le trouve... mais je reste incapable de l'ouvrir dans un module Access
0
jplausanne Messages postés 12 Date d'inscription mercredi 17 décembre 2008 Statut Membre Dernière intervention 1 juillet 2012
1 févr. 2009 à 08:48
Merci PCPT pour toutes ces infos... je dois faire le tri devant cette multitude d'instructions... beaucoup reste liées aux formulaires mais dans mon cas, je n'ai pas de formulaire: c'est une recherche directe dans la base de données afin d'ouvrir un maudit document Word!
0
PCPT Messages postés 13272 Date d'inscription lundi 13 décembre 2004 Statut Membre Dernière intervention 3 février 2018 47
1 févr. 2009 à 09:26
t'énerve pas

[../auteur/JPLAUSANNE/1555805.aspx jplausanne]

, on a compris ^^

en access (base de données) OLE c'est du BLOB... du BINARY
mon tout premier code donné doit donc fonctionner à partir du moment où le tableau de bytes est valide

le lien vb6 ci-dessus indique comment faire avec une image (binary), donc avec un type STREAM ADO. aucune idée si en VBA-access tu as accès à ces méthodes sans ajouter de références (ADO, ADOX)

le dernier lien quant à lui est spécifique à VBA, avec divers exemples ne correspondant pas forcément tous, mais çà peut donner des idées

au pire des cas - APRèS RECHERCHES ET MULTIPLES TESTS!!! - tu peux héberger ton projet (cijoint.fr) et indiquer comment arriver à ton blocage. indique précisément la marche à suivre, je jetterai un oeil (access 2000 et access 2007 à dispo)

bon courage


Prenez un instant pour répondre à [sujet-SONDAGE-POP3-POUR-CS_769706.aspx ce sondage] svp 
0
jplausanne Messages postés 12 Date d'inscription mercredi 17 décembre 2008 Statut Membre Dernière intervention 1 juillet 2012
1 févr. 2009 à 10:01
Je ne m'énerve pas PCPT... j'ai simplement frôlé la depression nerveuse.... mais je viens de trouver (beaucoup grace à toi et tes idées de chemin d'accès, de copie de fichier...!)

La réponse est là:
http://www.tech-archive.net/Archive/VB/microsoft.public.vb.general.discussion/2005-10/msg01640.html

en fait, l'engregistrement OLE récupéré ainsi à un header qu'il faut traiter/éliminer pour lire et copier le document. Ca marche!!!!

Le seul problème, certainement mineur, qui me reste est la connexion à la db, ici dans cet exemple:
cnn.Open "Provider=Microsoft.Jet.OLEDB.4.0;" & _ 
"Data Source=e:\My Documents\db1 XP.mdb;" & _ 
"Jet OLEDB:Engine Type=4;"

Si je remplace la bd par ma base de données. le système me dit qu'elle est déjà ouverte (ce qui est vrai puisque je développe dedans...), j'ai donc ouvert une copie de ma bd (sous un autre nom juste pour faire le test) et ça marche. Si tu as une idée pour adapter le code ci-dessus à la bd en cours

quoiqu'il en soit merci infiniment pour tous tes "trucs" et astuces. Quant au traitement des champs OLE c'est complètement délirant... Je suis aussi contre (mieux vaut stocker les chemins des documents que les documents eux-mêmes) il s'agit d'une application d'une bonne dizaine d'années que j'ai reprise.
0
PCPT Messages postés 13272 Date d'inscription lundi 13 décembre 2004 Statut Membre Dernière intervention 3 février 2018 47
1 févr. 2009 à 11:27
umm...

pas testé mais çà devrait fonctionner comme çà (dans un module) :






Private Type 
PT

    Width       As Integer
    Height      As Integer
End Type

Private Type OBJECTHEADER
    Signature   As Integer
    HeaderSize  As Integer
    ObjectType  As Long
    NameLen     As Integer
    ClassLen    As Integer
    NameOffset  As Integer
    ObjectSize  As PT
    OleInfo     As String * 256
End Type

Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (lpvDest As Any, lpvSource As Any, ByVal cbCopy As Long)
Private Declare Function GetTempPath Lib "kernel32" Alias "GetTempPathA" (ByVal nBufferLength As Long, ByVal lpBuffer As String) As Long
Private Declare Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" (ByVal hwnd As Long, ByVal lpOperation As String, ByVal lpFile As String, ByVal lpParameters As String, ByVal lpDirectory As String, ByVal nShowCmd As Long) As
Long

'   adaptation depuis
http://www.tech-archive.net/Archive/VB/microsoft.public.vb.general.discussion/2005-10/msg01640.html
Function GetOLEWordDoc2File(ByRef vLookUpResult As Variant, ByVal sExt
As String) As String
    Dim abArr()          As Byte
    Dim sDest            As String
    Dim ObjHeader        As OBJECTHEADER
    Dim ObjectOffset     As Long
    Dim Buffer           As String
    Dim i                As Long
    Dim FileOffset       As Long
    Dim FileHeaderOffset As Integer
    Dim FileStream()     As Byte
    
    
'   tableau
de bytes
    On Local Error GoTo Err_Handler
    abArr = vLookUpResult
    On Error GoTo 0

'   chemin
d'extraction
    sDest = GetTempDirectory & "ExtractionOLE_" & Format$(Now, "MMDDHHNNSS") & ".doc"

    'Copy the first 19
bytes into a variable of the defined type OBJECTHEADER
'   copie le header du champ
    CopyMemory ObjHeader, abArr(0), 19

    'Determine where the
header ends
'   position de la fin du
header
    ObjectOffset = ObjHeader.HeaderSize +
1

    'Grab enough
bytes after the OLE header to get file header
'  
récypère le header string du fichier sans le header du ole
    Buffer = ""
    For i = ObjectOffset To ObjectOffset + 512
        Buffer = Buffer & Chr$(abArr(i))
    Next i
    
    'Make sure the class
of the object is Word Document
'   le header
informe bien d'un doc word?
    If Mid$(Buffer, 12, 13) = "Word.Document" Then

'       récupère la
position de la fin de la première partie du header
        FileHeaderOffset = InStr(Buffer, "ÐÏ")
        If FileHeaderOffset > 0 Then
            'Calculate the
beginning of the document
'           fin du
header => début du document
            FileOffset = ObjectOffset + FileHeaderOffset - 1
            
            'Move
document into its own array
'           2e tableau
dans le header parasite
            ReDim FileStream(UBound(abArr) -
FileOffset)
            CopyMemory FileStream(0), abArr(FileOffset), UBound(abArr) - FileOffset +
1

            'Document file path
'           enregistrement du tableau dans le doc
temp
            Call CreateFileFromBytes(sDest,
FileStream)
            
'          
retour
            GetOLEWordDoc2File = sDest
        End If
    End If

Err_Handler:
    Erase FileStream
    Erase abArr
End Function

'
'
'http://www.codyx.org/snippet_recuperer-chemin-temp_772.aspx#2291
Private Function GetTempDirectory() As String
    Dim sBuffer As String
    sBuffer = String$(260, vbNullChar)
    If GetTempPath(Len(sBuffer), sBuffer) Then
'      
enlève  les  NULL
        GetTempDirectory = LeftB$(sBuffer, InStrB(1, sBuffer,
vbNullChar))
    Else
        GetTempDirectory = Environ$("TEMP")
    End If
'   ajoute le slash
    If Not (RightB$(GetTempDirectory, 2) = "") Then GetTempDirectory = GetTempDirectory & ""
End Function
'
'
'http://www.codyx.org/snippet_enregistrer-tableau-bytes-dans-fichier_5.aspx#1367
Private Sub CreateFileFromBytes(ByVal sPath As String, ByRef aBytes() As Byte)
    Dim FF As Integer
    FF = FreeFile
    Open sPath For Binary As #FF
        Put #FF, , aBytes
    Close #FF
End Sub
'
'
'http://www.codyx.org/snippet_ouvrir-document-lancer-executable_25.aspx#1548
Public Sub StartProcess(ByVal sFile As String, Optional ByVal sParameters As String =
vbNullString)
    ShellExecute 0&, "open", sFile, sParameters, vbNullString, 1&
End Sub





<small>
[../code.aspx?ID=39466 Coloration VB6, VBA,
VBS]
</small>








et l'appel se fait alors comme çà :






Private Sub 
test()

    Dim sPathRet As String
    sPathRet = GetOLEWordDoc2File(DLookup("[Nom du champ OLE]", "[Nom de la table]", strfiltre))

    If Len(sPathRet) Then
        StartProcess sPathRet
        DoEvents
        'Kill
sPathRet
    Else
        MsgBox "Erreur lors de l'extraction du
champ OLE", vbExclamation
    End If
End Sub





<small>
[../code.aspx?ID=39466 Coloration VB6, VBA,
VBS]
</small>






qu'est-ce que çà donne
0
jplausanne Messages postés 12 Date d'inscription mercredi 17 décembre 2008 Statut Membre Dernière intervention 1 juillet 2012
1 févr. 2009 à 16:07
Chapeau bas ! Je viens de tester : c’est parfait (encore mieux car peut-être plus paramétrable – pour moi en tous cas !).<?xml:namespace prefix o ns "urn:schemas-microsoft-com:office:office" /??>





Deux remarques vraiment insignifiantes :





Il manque dans Test() :






Dim  Strfiltre as String






Et le deuxième argument/paramètre dans l’appel à GetOLEWordDoc2File





 





On y est arrivé, je sors donc de ma dépression nerveuse : Merci mille fois et à la prochaine (vais chercher quelque chose de plus tordu encore )!
0
PCPT Messages postés 13272 Date d'inscription lundi 13 décembre 2004 Statut Membre Dernière intervention 3 février 2018 47
1 févr. 2009 à 19:57
ravi qu'on en soit venu à bout ^^

ps :
pour strfiltre c'est normal puisque j'ai presque juste copié/collé ton dlookup, et que je n'ai aucune idée du genre d'exemple de filtre à mettre

pour le 2e argument il est à supprimer directement depuis la fonction, j'étais parti sur autre chose...
donc juste :


Function 
GetOLEWordDoc2File(
ByRef 
vLookUpResult
As Variant
)
As String





rappel : je n'ai pas pu tester ;)

bravo aussi à toi pour avoir trouvé "le lien parfait" ^^
++
0
Rejoignez-nous