Option Explicit
Private oWd As Object
Private oDO As Object 'msforms.dataobject -- for clipboard access
Private strRTF As String
Private strPlaintext As String
Private Sub Class_Initialize()
Set oWd = CreateObject("word.application")
oWd.DisplayAlerts = 0 '=wdAlertsNone
oWd.documents.Add
Set oDO = CreateObject("new:{1C3B4210-F441-11CE-B9EA-00AA006B1A69}")
End Sub
Private Sub Class_Terminate()
oWd.activedocument.Close False 'no save
oWd.Quit
Set oWd = Nothing
Set oDO = Nothing
End Sub
Public Property Get TextRTF() As Variant
TextRTF = strRTF
End Property
Public Property Let TextRTF(ByVal vNewValue As Variant)
Static oTS As Object
strRTF = vNewValue
On Error Resume Next
'Convert to byte array and place in clipboard
oDO.Clear
oDO.SetText StrConv(strRTF, vbFromUnicode), "Rich Text Format"
oDO.PutInClipboard
'clear out whatever is in the document
oWd.activedocument.Range.Text = vbNullString
'Paste clipboard contents into Word object
oWd.activedocument.Range.Paste
If Err = 0 Then
Else
Err.Clear
AppActivate "Microsoft Office Word"
If Err = 0 Then
SendKeys "{Enter}", True
End If
Err.Clear
End If
'Get the plain text
strPlaintext = oWd.activedocument.Range.Text
End Property
Public Property Get Text() As Variant
Dim boolFoundOne As Boolean
'remove trailing Word paragraph marks or CrLf before returning plain text
Do
boolFoundOne = False
Do While Right(strPlaintext, 1) = vbCr
strPlaintext = Left(strPlaintext, Len(strPlaintext) - 1)
boolFoundOne = True
Loop
'remove any CrLf character pairs
Do While Right(strPlaintext, 2) = vbCrLf
strPlaintext = Left(strPlaintext, Len(strPlaintext) - 2)
boolFoundOne = True
Loop
Loop While boolFoundOne
Text = strPlaintext
End Property
'Public Property Let Text(ByVal vNewValue As Variant)
' Text is a read-only property
'End Property
Note: It is also possible to do this conversion without using the clipboard. In that version of the class, the RTF text was written to a temporary file and then opened with the Word object, interpreting the temporary file content as RTF. While this does work, each conversion takes a couple of seconds. When faced with many thousands of database records to update, I felt that a non-I/O solution would be best. I generally discourage the use of the clipboard because it will interfere with the user's regular work if it involves any copy/paste operations.
Function StringToByteArray(parmString)
Dim OStream
Set oStream = CreateObject("ADODB.Stream")
oStream.Open
oStream.Type = 1 '=adTypeBinary
oStream.WriteText parmString
StringToByteArray = oStream.Read
End Function
Public Sub testRTF_class()
Dim oRTF As New clsRTF2Text
Dim strRTF As String, strResult As String
strRTF = "{\rtf1\ansi\ansicpg1252\deff0\deflang5129{\fonttbl{\f0\fnil\fcharset0 Tahoma;}}\viewkind4\uc1\pard\f0\fs17\par}"
oRTF.TextRTF = strRTF
strResult = oRTF.Text
Debug.Print strResult
End Sub
I am writing this article while solving
this open question with this class.
Public Sub testRTF_Perf()
Dim oRTF As clsRTF2Text
Dim sngstart As Single, strResult As String, lngLoop As Long
sngstart = Timer
Set oRTF = New clsRTF2Text
Debug.Print "Class instantiation", "Elapsed: " & Timer - sngstart
For lngLoop = 1 To 5
sngstart = Timer
oRTF.TextRTF = "{\rtf1\ansi\ansicpg1252\deff0\deflang1033{\fonttbl{\f0\fnil\fcharset0 MS Sans Serif;}}" & _
"{\colortbl ;\red0\green0\blue0;}" & _
"\viewkind4\uc1\pard\cf1\f0\fs20 6/26/07 Number was busy each time tried, LM at home number, but customer never called back to confirm address for returned catalog; confirm if reorder " & lngLoop & "\cf0\fs17" & _
"\par }"
Debug.Print lngLoop, Timer, "Assign TextRTF value", Timer - sngstart
sngstart = Timer
strResult = oRTF.Text
Debug.Print lngLoop, Timer, "Retrieve plaintext value", Timer - sngstart
Debug.Print , strResult
Next
Set oRTF = Nothing
End Sub
Event Elapsed (sec)
Class instantiation 2.34375
(1)Assign TextRTF value 0.3984375
(1)Retrieve plaintext 0
(2)Assign TextRTF value 0.0078125
(2)Retrieve plaintext 0
(3)Assign TextRTF value 0.0078125
(3)Retrieve plaintext 0
(4)Assign TextRTF value 0.0078125
(4)Retrieve plaintext 0
(5)Assign TextRTF value 0.0078125
(5)Retrieve plaintext 0
The original poster in the question reported the ability to process 20 seconds for 10K records (500/second). This performance measurement includes the row retrieval and update time.
Where (RTF_fieldname Is Not Null) and (RTF_fieldname Like "{\rtf*}")
Have a question about something in this article? You can receive help directly from the article author. Sign up for a free trial to get started.
Comments (0)