T C
T C

Reputation: 304

Why does pasting a Word table column in VBA result in error 4605 most of the time, then succeed after many attempts?

I'm using a VBA macro to remove irrelevant rows from a table template in Word. My table has around 100 rows to start with. I noticed that table operations in Word VBA are SLOOOOOW on long tables, so I decided to copy/paste the (few) relevant lines into a new table instead, and delete the original table. This way I only need to copy a handful of lines, rather than deleting nearly 100 lines.

I've run into a quirk that I need help to understand.

When I run the code below on my table, it ALWAYS throws an error 4605 on the second row, on Newrow.range.paste. Depending on the sleep duration, the code fails a number of times, to succeed at last. Sleep 500 ms gives 34 fails, 0 ms gives 96 fails, 200 ms gives 66 fails, etc.

    For Each OldRow In TestTbl.Rows
        If Models.Contains(OldRow.Cells(1).Range.Text) Then '(meaning it's relevant to copy)
            Set NewRow = NewTbl.Rows(NewTbl.Rows.Count)
            On Error Resume Next
            Do
                Err.Clear
                OldRow.Range.Copy
                Sleep 500 'ms
                NewRow.Range.Paste
                If Err <> 0 Then
                    Sleep 200 'ms
                    Debug.Print "Failed to paste row " & OldRow.Index & " from TestTbl with error " & Err & " at " & Now()
                End If
            Loop Until Err = 0
            On Error GoTo 0
        End If
    Next OldRow

Can someone here help me figure out how to get a paste of the entire row to work on the first attempt, not after 30 seconds of trying?

This only happens to the first row that fulfills if models.contains(Oldrow...text). Rows after that get pasted without any errors.

Upvotes: 0

Views: 452

Answers (1)

T C
T C

Reputation: 304

thanks for the suggestion. After your input I researched and tried out a way to avoid going via the clipboard altogether. And voila, it works both faster and without bugs...

The relevant code is now:

    For Each OldRow In TestTbl.Rows
        If Models.Contains(OldRow.Cells(1).Range.Text) Then
            Set NewRow = NewTbl.Rows(NewTbl.Rows.Count)
            NewRow.Range.FormattedText = OldRow.Range.FormattedText
        End If
    Next OldRow

This has tested nicely and is used in production now. It manages to copy merged cells, contentcontrols in cells, formatting, everything. Nice.

Upvotes: 1

Related Questions