2 votes

Écriture d'Excel vers Word Boîte de texte Activex

J'ai une application Excel qui collecte des informations via une interface basée sur un formulaire. Elle est utilisée pour ;

  1. Remplir des valeurs dans le classeur
  2. Une procédure permet d'ouvrir un document Word (essentiellement un modèle) et de nommer le fichier selon des règles, basées sur sur la base de certaines données d'entrée. (Bon jusqu'à présent)
  3. L'idée est donc de transférer les informations collectées (à partir de l'application Excel qui pilote ce processus) à le même document Word ouvert et nommé. Plus précisément, j'ai l'intention de remplir un certain nombre de zones de texte ActiveX portant un nom unique avec le document.

    *** C'est là que j'échoue lamentablement.

J'ai activé la "Bibliothèque d'objets Microsoft Word 16.0" sous les références dans l'environnement VBA de MSExcel.

Étant donné que je connais le nom/titre du contrôle de contenu (la boîte de texte ActiveX est un "contrôle de contenu", n'est-ce pas ?) Le code ci-dessous est un exemple simplifié, s'il fonctionne pour l'exemple, je devrais être en mesure de résoudre le problème du document plus large :

Sub trial()
Dim Word As Word.Application
Dim wdDoc As Word.Document
On error resume next
Set Word = New Word.Application
Set wdDoc = Word.Documents.Open("G:\CAPS Management Tool\Customer.docm")
Word.Application.Visible = True
Dim cc As Object
Set cc = ActiveDocument.SelectContentControlsByTitle(txt_PersonName) 'txt_PersonName is the control name
cc.Range.Text = "SUCCESS"  'Run-time error 438
                           'Object does not support property or method
Set cc = ActiveDocument.SelectContentControlsByTitle(txt_Address) 'txt_Address is the control name
cc.Range.Text = "SUCCESS"  'Run-time error 438
                           'Object does not support property or method
End Sub

Quelqu'un peut-il nous aider ? Il y a beaucoup de zones de texte dans le document Word auquel je souhaite me connecter.

Merci d'avance.

1voto

Sheepdog Points 43

OK, j'ai continué à creuser (je n'aime pas accepter la défaite) et j'ai découvert que tout mon postulat était erroné ! Les contrôles ActiveX dans Word sont considérés comme des "InlineShapes" et non comme des "ContentControls". Mais les résultats que je lisais dans les recherches sur Internet m'ont laissé perplexe (je n'ai pas prétendu être l'outil le plus aiguisé de la cabane).

Une fois que je m'en suis rendu compte, j'ai creusé un peu plus pour trouver la réponse (voir ci-dessous).

Donc, d'abord pour lister les 3 contrôles dans mon document (et leur index) avec le Sub suivant

Sub ListActiveXControls()
Dim i As Integer
i = 1
Do Until i > ActiveDocument.InlineShapes.Count
Debug.Print ActiveDocument.InlineShapes(i).OLEFormat.Object.Name & "    Control Index = " & i
i = i + 1
Loop
End Sub

En passant maintenant à EXCEL, j'ai utilisé ce qui suit :

Sub trial()
Dim Word As Word.Application
Dim wdDoc As Word.Document
Set Word = New Word.Application
Set wdDoc = Word.Documents.Open("G:\CAPS Management Tool\Customer.docm")
Word.Application.Visible = True
debug.print "ActiveDocument Name is : " & ActiveDocument.Name 
' Result = Nothing
' Allowing the code to continue without the pause caused the operation to fail
Application.Wait (Now + TimeValue("0:00:10")) ' See text below, would not work without pause
wdDoc.Activate
' Begin set ActiveX control values. In this instance,
' The first line corresponds to 'Textbox1'
ActiveDocument.InlineShapes(1).OLEFormat.Object.Text = "Success"
' The second line corresponds to 'Textbox2'
ActiveDocument.InlineShapes(2).OLEFormat.Object.Text = "Success"
' The third line corresponds to 'ChkBox1'
ActiveDocument.InlineShapes(3).OLEFormat.Object.Value = True
End Sub

Pour une raison quelconque, sans la commande "Attendre", l'opération échoue. S'il n'y a pas de pause, l'ActiveDocument semble être nul, sans que l'on sache pourquoi. Cela se produit avec un document comportant 2 contrôles ActiveX ou 165 contrôles ActiveX et le temps d'attente nécessaire semble être de 10 secondes sur mon PC. 10 secondes sur mon PC. Par ailleurs, la définition de près de 150 valeurs de contrôle n'a pris que quelques secondes, une fois la période d'attente terminée.

Si quelqu'un sait pourquoi le "Wait" est apparemment nécessaire, je serais intéressé de le savoir !

-1voto

PeterT Points 3745

Voici quelques conseils pour vous aider à résoudre ce problème.

  1. Ne pas utiliser On Error Resume Next à moins que vous n'en ayez vraiment besoin. Et lorsque vous l'utilisez, réactivez le rattrapage d'erreurs à l'aide de la commande On Error Goto 0 le plus rapidement possible. Sinon, vous passerez à côté de nombreuses erreurs dans votre code et il sera difficile de savoir ce qui se passe.
  2. Ne pas utiliser le nom Word comme nom de variable. Il est réservé à la Word.Application et ne fera qu'embrouiller le compilateur (et vous).
  3. Les titres des contrôles sont des chaînes de texte, vous devez donc les mettre entre guillemets.
  4. J'ai ajouté un bonus Sub qui vous offre une méthode rapide pour ouvrir une nouvelle instance d'application Word ou pour l'attacher à une instance d'application existante. Vous constaterez (surtout pendant le débogage) qu'il y a des dizaines d'exe Word ouverts et en cours d'exécution.

L'exemple de code ci-dessous décompose également l'affectation de la valeur "SUCCESS" au contrôle en une fonction distincte, à savoir Sub . C'est dans ce court Sub que l'utilisation de On Error Resume Next est appropriée -- et isolée du reste de la logique -- ce qui en limite la portée.

Option Explicit

Sub trial()
    Dim wdApp As Word.Application
    Dim wdDoc As Word.Document
    Set wdApp = AttachToMSWordApplication
    Set wdDoc = wdApp.Documents.Open("C:\Temp\Customer.docm")
    wdApp.Application.Visible = True
    TextToControl wdDoc, "txt_PersonName", "SUCCESS"
    TextToControl wdDoc, "txt_Address", "SUCCESS"
End Sub

Private Sub TextToControl(ByRef doc As Word.Document, _
                          ByVal title As String, _
                          ByVal value As String)
    Dim cc As ContentControl
    On Error Resume Next
    Set cc = doc.SelectContentControlsByTitle(title).Item(1)
    If Not cc Is Nothing Then
        cc.Range.Text = value
    Else
        Debug.Print "ERROR: could not find control titled '" & title & "'"
        '--- you could also raise an error here to be handled by the caller
    End If
End Sub

Public Function AttachToMSWordApplication() As Word.Application
    '--- finds an existing and running instance of MS Word, or starts
    '    the application if one is not already running
    Dim msApp As Word.Application
    On Error Resume Next
    Set msApp = GetObject(, "Word.Application")
    If Err > 0 Then
        '--- we have to start one
        '    an exception will be raised if the application is not installed
        Set msApp = CreateObject("Word.Application")
    End If
    Set AttachToMSWordApplication = msApp
End Function

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X