question

PeterKarlstromMidrange avatar image
0 Votes"
PeterKarlstromMidrange asked ·

Replace text with URL in Word document using Open XML

Hello
I have problems with a project where I want to replace som tagged text in a Word document with a clickable URL.
The sample code below uses a word document which contains the text [Webpage].
Here is the code with the problem:

 Imports DocumentFormat.OpenXml
 Imports DocumentFormat.OpenXml.Packaging
    
 Public Class Form1
     Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    
         MsgBox(processDocument("C:\temp\testdoc.docx", "[Webpage]", "Google", "https://www.google.com"), MsgBoxStyle.ApplicationModal + vbOKOnly, "Text replace test")
    
     End Sub
    
     Private Function processDocument(ByVal tDocFilename As String, ByVal tagText As String, ByVal replText As String, ByVal replURL As String) As String
    
    
         Using doc As WordprocessingDocument = WordprocessingDocument.Open(tDocFilename, True)
             Dim mainPart As DocumentFormat.OpenXml.Packaging.MainDocumentPart = doc.MainDocumentPart
    
             Dim textPLaceList As IEnumerable(Of Wordprocessing.Text) = mainPart.Document.Descendants(Of Wordprocessing.Text)()
    
             Try
                 For Each textPlaceHolder As Wordprocessing.Text In textPLaceList
                     Dim parent = textPlaceHolder.Parent
                     If (TypeOf parent Is Wordprocessing.Run) Then
                         If textPlaceHolder.Text.Contains("[") And textPlaceHolder.Text.Contains("]") Then
                             Dim tmpHyperlink As New DocumentFormat.OpenXml.Wordprocessing.Hyperlink
                             tmpHyperlink.Anchor = replText
                             tmpHyperlink.DocLocation = replURL
                             tmpHyperlink.InsertBefore(Of Wordprocessing.Hyperlink)(tmpHyperlink, textPlaceHolder.Parent)
                             textPlaceHolder.Remove()
                             Exit For
                         End If
                     End If
                 Next
                 processDocument = "OK"
             Catch ex As Exception
                 processDocument = "Could not replace text in document (" & ex.Message & ")"
             End Try
    
         End Using
    
     End Function
    
 End Class

When I try to use InsertBefor or InsertAfter I get an error telling me that the "state" och the object is incorrect.
What does that mean?

Regards Peter Karlström

office-addins-dev
· 4
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

@PeterKarlstromMidrange
As this issue is more realted to Open XML, I would modify the tag to be "office-addins-dev" which is the tag of Open XML Format SDK on Q&A forum.


0 Votes 0 ·

Hello Emily
Unfortunately, Open XML has nothing to do with Addins in Office, so I think Microsoft Q&A has no room for this type of questions.
I think Microsoft don't want to take responsibility for the Open XML Office format in this forum.

Regards
Peter

0 Votes 0 ·
MikeBowen-1599 avatar image MikeBowen-1599 PeterKarlstromMidrange ·

Hi Peter,

@emilyhua-msft has the correct forum for Open XML Format SDK questions on the Q&A forum for coding questions, I was unaware that this was the new forum for Open XML Format Questions. StackOverflow is also a good option to find answers to your questions as @JohnKorchok wrote.

If you find issues or bugs with the Open XML SDK itself please post them to the Open XML SDK issues page, so they can be addressed by the developers working on the Open XML SDK.

Best Regards,
Mike


0 Votes 0 ·
Show more comments
PeterKarlstromMidrange avatar image
0 Votes"
PeterKarlstromMidrange answered ·

After a tip from cheong00 I discovered I had approached this task in the wrong way.

This is how it should be done:

 Imports DocumentFormat.OpenXml
 Imports DocumentFormat.OpenXml.Wordprocessing
 Imports DocumentFormat.OpenXml.Packaging
    
 Public Class Form1
     Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    
         MsgBox(processDocument("C:\temp\testdoc.docx", "[Webpage]", "Google", "https://www.google.com"), MsgBoxStyle.ApplicationModal + vbOKOnly, "Text replace test")
    
     End Sub
    
     Private Function processDocument(ByVal tDocFilename As String, ByVal tagText As String, ByVal replText As String, ByVal replURL As String) As String
    
         Using doc As WordprocessingDocument = WordprocessingDocument.Open(tDocFilename, True)
             Dim mainPart As DocumentFormat.OpenXml.Packaging.MainDocumentPart = doc.MainDocumentPart
    
             Dim textPLaceList As IEnumerable(Of Wordprocessing.Text) = mainPart.Document.Descendants(Of Wordprocessing.Text)()
    
             Try
                 For Each textPlaceHolder As Wordprocessing.Text In textPLaceList
                     Dim parent As Wordprocessing.Paragraph = textPlaceHolder.Parent.Parent
                     If (TypeOf parent Is Wordprocessing.Paragraph) Then
                         If textPlaceHolder.Text.Contains("[") And textPlaceHolder.Text.Contains("]") Then
                             Dim newParagraph As Paragraph = getURLParagraph(mainPart, replText, replURL)
                             parent.Parent.InsertBefore(Of Wordprocessing.Paragraph)(newParagraph, parent)
                             textPlaceHolder.Remove()
                             Exit For
                         End If
                     End If
                 Next
                 processDocument = "OK"
             Catch ex As Exception
                 processDocument = "Could not replace text in document (" & ex.Message & ")"
             End Try
    
         End Using
    
     End Function
    
     Private Function getURLParagraph(ByVal mainPart As MainDocumentPart, ByVal urlLabel As String, ByVal urlText As String) As Paragraph
    
         Dim urlExists As Boolean
         Dim hRelation As HyperlinkRelationship = Nothing
    
         Dim uri As System.Uri = New Uri(urlText)
    
         For Each hRel As HyperlinkRelationship In mainPart.HyperlinkRelationships
             If (hRel.Uri = uri) Then
                 urlExists = True
                 hRelation = hRel
                 Exit For
             End If
         Next
    
         Dim relationshipId As String
         If Not urlExists Then
             Dim rel As HyperlinkRelationship = mainPart.AddHyperlinkRelationship(uri, True)
             relationshipId = rel.Id
         Else
             relationshipId = hRelation.Id
         End If
    
         Dim newParagraph As Paragraph = New Paragraph(New Hyperlink(New ProofError() With {
         .Type = ProofingErrorValues.GrammarStart
     }, New Run(New RunProperties(New RunStyle() With {
         .Val = “Hyperlnk”}), New Text(urlLabel))) With {
         .History = OnOffValue.FromBoolean(True),
         .Id = relationshipId
     })
         Return newParagraph
    
     End Function
 End Class

Hope this is of some help to others.

Regards
Peter Karlström

·
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

JohnKorchok avatar image
0 Votes"
JohnKorchok answered ·

I believe you're referring to Open XML, not Open XMP. You'll get better answers on Stack Overflow that you will here.

· 3 ·
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Hello
I have a paid Microsoft Support subscription, and they have closed the Open XML forums redirecting them here, so I will not primary go to another community.

Regards

0 Votes 0 ·
MikeBowen-1599 avatar image MikeBowen-1599 PeterKarlstromMidrange ·

Hi @PeterKarlstromMidrange ,
I can help you with this, but @JohnKorchok is correct, this is the wrong forum for issues with the Open XML SDK. The OOXML SDK is an open-source project hosted on GitHub, so in order to support the community and keep issues with the OOXML SDK in one place, please post your issue on the OOXML SDK Issues Page and we’ll continue the conversation there.
Best Regards,

Mike Bowen
Escalation Engineer - Microsoft Open Specifications


0 Votes 0 ·

Hello Mike

As you can see in my post this is rather a question about coding help than an issue with Open XML.

But I still wonder why my priority forum support service (Visual Studio Enterprise subscription) disappeared from Technet and vanished into nothing. This was already paid for!!!

The lack of support for developing for the Microsoft Office platform is frustrating.

//Peter

0 Votes 0 ·
cheong00 avatar image
0 Votes"
cheong00 answered ·

When textPlaceHolder.Parent is a Run, .InsertBefore/InsertAfter will fail. (Note that although I link to an issue page of OpenXML SDK, this is the limitation of Word format and I think you know too as I see your code is also trying to evade that)

See if replacing textPlaceHolder.Parent in the second parameter with parent.Parent will help.


· 1 ·
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Hello and thank you for your reply.

I tried different calls in this row and suddenly it worked.
But, the created hyperlink in the document was not what I was locking for.

I'm working with a new solution which I will share in this thread as sonn as its working.

Regards

0 Votes 0 ·