Search code examples
vb.netms-wordoffice-interopword-interop

MS Word picture replacement with VB.NET, error message for empty clipboard


I'm trying to replace a bookmarked picture in a MS word document so, that my program opens another MS Word file where it gets the replacement picture by a bookmark. For some reason the excecution ends up in the following error message:

System.Runtime.InteropServices.COMException: 'This method or property is not available because the Clipboard is empty or not valid.'

The pictures are bookmarked so that the bookmark range is only the picture itself. The code works fine, when a line break is bookmarked witch the picture. I would like this to work so, that the bookmark range is only the picture.

Heres the what I was trying:

'Button click opens my base document

 Private Sub test123_Click(sender As Object, e As EventArgs) Handles test123.Click

        oWord = CreateObject("Word.Application")
        oWord.Visible = True

        path = "C:\Users\user\basefile\"
        file = Dir(path & "*.docx")
        oDoc = oWord.Documents.Add(path & file)
      

  If Me.checkbox.Checked = False Then

            'Open the source file
            Dim sourceFile As String = "C:\Users\user\sourcefile\source.docx"
            Dim sourceDoc As Word.Document = oWord.Documents.Open(sourceFile)

            'Copy the bookmarked figure from the source file
            Dim sourceBookmark As String = "bkm_src"
            Dim sourceRange As Word.Range = sourceDoc.Bookmarks(sourceBookmark).Range
            sourceRange.CopyAsPicture()

            'Close the source file
            sourceDoc.Close()

            'Replace the bookmarked figure in the destination file with the copied one
            Dim destBookmark As String = "bkm_dest"
            Dim destRange As Word.Range = oDoc.Bookmarks(destBookmark).Range
            destRange.Delete() ' Added a delete method to remove the existing picture
            destRange.PasteSpecial() ' Pasted the copied picture

        End If

Solution

  • How about using FormattedText property instead?

        'Button click opens my base document
    
        Private Sub test123_Click() '(sender As Object, e As EventArgs) Handles test123.Click
    
            Dim oWord As Object
            oWord = CreateObject("Word.Application")
            oWord.Visible = True
            Dim path As String = "C:\Users\user\basefile\"
            Dim file As String = Dir(path & "*.docx")
            Dim oDoc As Object
            oDoc = oWord.Documents.Add(path & file)
    
    
            If Me.checkbox.Checked = False Then
    
                'Open the source file
                Dim sourceFile As String = "C:\Users\user\sourcefile\source.docx"
                Dim sourceDoc As Word.Document = oWord.Documents.Open(sourceFile)
    
                'Copy the bookmarked figure from the source file
                Dim sourceBookmark As String = "bkm_src"
                Dim sourceRange As Word.Range = sourceDoc.Bookmarks(sourceBookmark).Range
                REM this will copy Bookmarks(sourceBookmark).Range NOT the picture range with bookmarked
                'sourceRange.CopyAsPicture()
    
    
                REM move to after copying to destRange, because this will invalidate the sourceRange
                ''Close the source file
                'sourceDoc.Close()
    
                'Replace the bookmarked figure in the destination file with the copied one
                Dim destBookmark As String = "bkm_dest"
                Dim destRange As Word.Range = oDoc.Bookmarks(destBookmark).Range
    
                REM this will invalidate the destRange object and how can you use it with its PasteSpecial method?
                'destRange.Delete() ' Added a delete method to remove the existing picture
                'destRange.PasteSpecial() ' Pasted the copied picture
    
    
                REM use FormattedText property instead
                destRange.FormattedText = sourceRange.FormattedText
                REM If you want to keep the bookmark "bkm_dest", you could add or edit the name of this bookmark to "bkm_dest" replace the new one here, like this:
                'With destRange
                '    With .Bookmarks(1)
                '        REM the property of Name is readonly
                '        '.Name =
                '        REM so delete the new one before and add a bookmark here and name it with "bkm_dest"
                '        .Delete()
                '    End With
                '    .Bookmarks.Add("bkm_dest")
                'End With
    
                'Close the source file
                sourceDoc.Close()
    
            End If
    
        End Sub