With Word and VBA, how can I store RTF text into an array, including the formatting?

     Using Word VBA, I want to preserve in an array a series of brief texts in Rich Text Format and keep the formatting.

      If I were adding a Rich Text Format entry into AutoCorrect, I could use the “AddRichText” method to insert formatted text. Is it possible to do the same for just entries in an array? I fear the answer is “no.”

      If worst comes to worst, I could save the entries in a formatted document and store only the location of the formatted text plus the number of characters in the desired text. Then when I would need a certain text, I could locate to it in the document, copy the text, and paste the information where I needed it. That would be clumsy and slow. I hope someone else can suggest a better solution.

      As always, thanks for any help you can give

      —John Robin
JohnRobinAllenRetired professor of FrenchAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Have you ruled out using AutoText? The AutoText entries themselves could be stored in a globally loaded template (like Normal.dot or any template saved to the Startup folder in Word). I'm not clear on why you want an array, but one dimension of the array could be used to store the names assigned to the AutoText entries, I suppose. I presume you would use code to select the texts you want, then insert the name of the text and invoke the AutoText using the code snippet I hope to remember to attach.

In any event, the AutoText entries themselves can be formatted and you should be able to retain that original formatting upon insertion.
Public Sub InsertAutoText(ByVal psAutoTextName As String)
    On Error GoTo ErrorHandler
    ' (The most likely error is that a matching autotext entry was not found)
    With Selection
        ' First, the name of the AutoText entry is typed directly into the document:
            .TypeText Text:=psAutoTextName
        ' Second, the user presses "F3":
    End With
    Exit Sub
    MsgBox "Error " & Err.Number & ": " & Err.Description
    ' (The most likely error is that a matching autotext entry was not found)

End Sub

Open in new window

JohnRobinAllenRetired professor of FrenchAuthor Commented:
     I should have been more explicit about my problem. My program analyzes essays written in a foreign language. It goes through a student essay that has been corrected with comments by a professor. All the comments are generated by AutoText entries and all begin with “[[<< ” and end with “]]”. That enables my program to find the comments inserted in the essay. Each of the currently 108 different possible comments has a certain value that notes the relative importance of the error. Some errors, such as the use of the passive voice, have a zero value. That is not a real grammatical error, but just a stylistic errors the student should try to avoid writing. The average value each error is between 3.5 and 4 points, depending on whether you count zero point errors. The highest value accorded to an error is 10, for something incomprehensible. If what the student wrote is incomprehensible, it usually means that there are at least three words that are wrong.

      My goal is to produce a summary of the comments in a table with three columns. The first column notes the number of times a student made a given error. The second column displays (a) a copy of the text of an error message, with underlining and italics where appropriate, formatting generated by the AutoCorrect entries, and (b) the relative value of the error. The third column gives the total points generated by that error and its frequency: how many times the student made the error times the value of the error.

      The program then sorts the table in descending order of the third column, so the table serves as an aide-mémoire for the student to rank all the student’s errors in descending order of importance, based on how many times the student made the error and the relative importance of the error. The program can then work on those errors to help the student understand each error and practice not making it again.

      The list of errors changes with each essay thus examined, and with each addition or deletion the professor makes to the list of all possible errors noted. I do not know enough about AutoText to judge whether it could automatically duplicate a formatted text automatically in the document that lists all 108 comments and their value.

      I have a (hopefully temporary) kludge: I simply declare that the text of messages in the summary table will not be formatted, will not show underlining and italics. That works beautifully, but it is not the ideal solution.

       My other kludge is what I described earlier: to note the location of a formatted message, then when I need that message, to got to that location, copy the message, and paste it into the table as desired. That works, but it is more complex than what I just described. It involves creating bookmarks to locate back to the table after selecting a text, it involves working out a solution to the fact that a location memorizes is not always exactly where a given text may be found. The correction for the latter is to locate about five spaces before the starting “[[ << ” and then do a search for that string, so that we are sure we are at the start of the comment.

      Any suggestions as to how I can improve all this are more than welcome. For now, I will use the kludge that the table will not show formatting. If I cannot solve the problem in any other way, I will use the second solution, to mark the location of properly formatted text and then copy the text from that location to paste into the table.
      —John Robin
I'll take some time to think about this, but I think the second kludgy answer is actually the one that makes the most sense, at least after my second reading. (Thank you for the detail, by the way. That's a huge help.)

The reason I like the second method is because it's possible to set a bookmark to encompass the entire formatted comment, from the beginning "[[<<" through to the closing "]]".

Off the top of my head, I envision a routine that would search through the document once from the beginning, locating each instance of "[[<<" and creating a bookmark stretching through the next instance of "]]"; the bookmark would be named according to a simple convention, perhaps as simple as "Error_1", "Error_2",...,"Error_n".

After the first pass, the routine would then select each bookmark in turn, by name, and compare the contents to your table (or array, or whatever) of 108 possible comments, and update your scoring array with the number of instances of that particular error. Actually, as I type this, there's no reason not to do this during the first pass, so what the heck, let's do that: As you create each bookmark, compare the comment to your predefined list of 108 comments, increment a counter to indicate how many instances have been found for that particular comment, and name the bookmark accordingly, e.g., "bkmkError[n]_#[t]", where n is the index of the comment itself (1 to 108), and t is the ordinal number of occurrences of that comment. Each time you create a bookmark, you also update an array with the Error[n] and the number [t], so that when your code reaches the end of the document the array contains a single entry for each Error[n] that was found anywhere in the document, with a second dimension recording the total number of occurrences (if you like, you can add a third dimension to track the point value of the error, just to have all the values in one array).

To create your table, then, you simply (sort and then) read your results array, putting the number of occurrences in the first column, the text of the error (copied from the first occurrence of that error, found by searching for the bookmark "bkmkError[n]_#1" and copying the text exactly as written with underscoring and italics) in the second column, and the value in the third.

It's more complicated from a programming point of view, but relatively straightforward. Further, if you're writing the table at the end of a Word document that will be returned to the student in electronic form, you could even provide functionality to jump to or highlight each instance of a given error throughout the document....

Hope this helps. If I can make time today, I'll mock up some code to accomplish this. Good luck.

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
JohnRobinAllenRetired professor of FrenchAuthor Commented:
Comments below. They are too lengthy for this box
JohnRobinAllenRetired professor of FrenchAuthor Commented:
    Thanks for your suggestions. Please do not mock up anything, for with your help the problem appears to be solved. I prefer not to have to go to the document with the list of shortcuts to get a formatted copy of the comment, as that takes time. The formatted shortcut exists in the student’s essay (provided that another query I just posted on EE has solved a problem).

      What I particularly like about your suggestion is the bookmarking of the first occurrence of any comment in the student’s essay, rather than my original suggestion of noting the location by the number of characters it is from the top of the document. When I make a first pass on the document, I have to select the whole of each comment in order to determine whether it is a first occurrence or not. In the latter case, I have to increment the frequency of use of that comment. If it is a first use, then I can bookmark the spot with a BkMark01, Bkmark02, etc, series of marks. The comment is already selected, so I do not have to do that again when I start filling in the table. I then will use another bookmark inside the table that shows the results.

      Here is what I propose. I make a pass through the essay noting for each different bookmark (a) its value, (b) its frequency, (c) its first location in the essay, marked with a series of bookmarks, one for each different error.

      Then I make the 3-column table and have it hold the information for each comment: I bookmark row 1 (not counting the title row), column 2. Call that bookmark “Nirvana.” I put the frequency of the individual comment in column 1. I go to the bookmark for the first comment, copy it, jump to the Nirvana bookmark, paste in the formatted copy of the comment into column 2, and append the value of the comment. Put in column 3, row 1 the product of the value times the frequency, and move the Nirvana bookmark to the next row, middle column.

      Move to the next row and repeat with the second comment. When all the rows have been filled in, delete the Nirvana bookmark and all the BkMark01 … BkMarkxx bookmarks.

      All that is quite similar to my “kludgy” solution, but the beauty of your contribution is that in my original solution I located to the different errors by the using “.start” method to count how characters the start of the comment was from the top of the document. Since I do not know how to locate to a position “x” characters from the top, I had to move the cursor to the top of the document and then “MoveRight” for “x” number of characters. In practice the result was not an accurate measurement, so I was going to locate to about five characters before the comment and then was going to search for the “[[<< ” that marked the start of the comment. Then move my cursor to the end of that mark, turn on extend, and search for the end of the comment. Then shorten the selection so it would not include the closing “]]” marks. I can avoid all that by simply bookmarking each new comment at the moment when, in the first pass, I already have the comment selected.

      Then, with just one command, jump to a bookmark, I locate to what I need to copy and paste.

      Thanks for all your help. I hope my verbosity does not discourage you from continuing to help others.

      Warm regards,

      John Robin

It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Microsoft Word

From novice to tech pro — start learning today.