Manipulating a string while keeping format of substrings - vba

I wanted to create a string that is the result of concatenating the character "A" to the last 3 characters of an existing string "JKLXYZ". In this string the "Y" is blue, the rest is automatic colour. The result to obtain is "AXYZ" with the "Y" still in blue.
I wanted to write :
Dim myString as String
myString = "A" & right(myString,3)
Two questions I would appreciate help with :
How do I get the original string from the Word document into the myString variable while keeping its formatting = the "Y" in blue ?
Assuming that I have been able to get into myString the original string with the "Y" in blue, how do I avoid the concatenation and/or the RIGHT function to destroy the format (the "Y" should still be in blue)
Thanks very much.

I crafted some macro. (note: I am not a VBA export!):
Sub Macro1()
'
'
Dim myString As String
Dim myColor As Double
myColor = -738131969
' Find something in myColor
Selection.Find.ClearFormatting
Selection.Find.Font.Color = myColor
Selection.Find.Execute
' Select the word with the character in myColor
Selection.MoveLeft Unit:=wdWord, Count:=1
Selection.MoveRight Unit:=wdWord, Count:=1, Extend:=wdExtend
' check if the selected word contains "XYZ"
If InStr(1, Selection.Text, "XYZ") > 0 Then
myString = Selection.Text
myString = "A" & Right(myString, 3)
' Insert the text after the current selection
Selection.InsertAfter Text:=" " & myString
Selection.MoveRight Unit:=wdWord, Count:=1
' Change the color of the "Y" to myColor
Selection.MoveLeft Unit:=wdCharacter, Count:=2
Selection.MoveRight Unit:=wdCharacter, Count:=1, Extend:=wdExtend
Selection.Font.TextColor = myColor
End If
End Sub
NOTE: The changed string will be inserted after the found piece of text.

Related

Change the case of a Range text and type it

Possible scenario, let say we created a Range Object containing the following line:
Speculative BUY, FV: EGP19.59
Now I want to split the Range Object into two parts by ", " as delimiter so that the given Range will change into two Ranges containing "Speculative BUY" and ", FV: EGP19.59" (Two separate range).
Now I need to change the case of only the first range containing "Speculative BUY" into "Speculative Buy" using:
.Case = wdTitleWord
Previously I am using .Find to change the Ranges in the following code (this is not complete code as it is only changing the Range R, not splitting it into two):
Sub Range_into_Ranges()
selection.EndKey Unit:=wdLine
selection.MoveUp Unit:=wdParagraph, COUNT:=1, Extend:=wdExtend
Dim R, F As Word.Range
Set R = selection.Range
Set F = R.Duplicate
With F.Find
.Text = ", "
.Forward = True
.Wrap = wdFindStop
.Execute
End With
If F.Find.Found Then
R.SetRange Start:=R.Start, _
End:=F.Start
R.Case = wdTitleWord
Else
End If
End Sub
Note: There may be other ways of producing the same results. you are free to advice me another simple code.
You can assign a case to a Range using the WdCharacterCase enumeration. For title case:
R.Case = wdTitleWord
Put into the context of your sample code, something like as follows. I did some tweaking:
My version assumes you want to work with the paragraph where the selection currently is, which is why I commented out your first two lines
In VBA you need to declare the data type of every variable, otherwise it's a Variant. So: Dim R As Word.Range
VBA provides the Split function to divide up a string according to a delimiter. I use this to get the term to search, so that you can get the Range directly
I found when setting Title Case on text that has ALL CAPS that it doesn't reduce upper case to lower case. But first applying lower case, then title case, does work.
Sample code
Sub Range_into_Ranges()
' Selection.EndKey Unit:=wdLine
' Selection.MoveUp Unit:=wdParagraph, Count:=1, Extend:=wdExtend
Dim R As word.Range, F As word.Range
Dim sTerm As String, bFound As Boolean
Set R = Selection.Paragraphs(1).Range
R.MoveEnd wdCharacter, -1 'Trim off the paragraph mark
sTerm = R.Text
sTerm = Split(sTerm, ",")(0)
Set F = R.Duplicate
With F.Find
.Text = sTerm
.Forward = True
.wrap = wdFindStop
bFound = .Execute
End With
If bFound Then
F.Case = wdLowerCase
F.Case = wdTitleWord
Else
End If
End Sub

Word VBA - select in the table from given word to the end of paragraph but not entire cell

Trying to select and mark with red the specified text beginning from "Depend" to the end of the cell, but not the entire cell.
Sample of code:
With Selection
Set obj_Tbl = .Tables(1)
.Tables(1).Columns(2).Select ' Why so stupid? there is the conditional formatting
For Each obj_Row In obj_Tbl.Rows
With obj_Row.Cells(3)
If InStr(1, obj_Row.Cells(3), "Depend") > 0 Then
obj_Row.Cells(3).Range.Characters(InStr(1, obj_Row.Cells(3), "Depend")).Select
Selection.EndKey Unit:=wdLine, Extend:=wdExtend
Selection.MoveLeft Unit:=wdCharacter, Count:=1, Extend:=wdExtend
Selection.Font.Color = RGB(192, 0, 0)
End If
End With
Next
End With
This works fine when the "Depend" is written in one row. But if the text looks like
Depends from Something
Too Long to Be Shown In One Line
I have the trouble with selection which selects only one row.
Selection.EndOf Unit:=wdParagraph 'selects the entire cell
Selection.EndKey Unit:=wdParagraph 'is not supported
You can use MoveRight and calculate the units to move right from Length of the Cell - Your Current Position.
Sub Test()
Dim count As Long
With Selection
Set obj_Tbl = .Tables(1)
.Tables(1).Columns(2).Select
For Each obj_Row In obj_Tbl.Rows
With obj_Row.Cells(3)
If InStr(1, obj_Row.Cells(3), "Depend") > 0 Then
obj_Row.Cells(3).Range.Characters(InStr(1, obj_Row.Cells(3), "Depend")).Select
count = Len(obj_Row.Cells(3).Range) - InStr(1, obj_Row.Cells(3), "Depend")
Selection.MoveRight Unit:=wdCharacter, count:=count - 2, Extend:=wdExtend
Selection.Font.Color = RGB(192, 0, 0)
End If
End With
Next
End With
End Sub

Selecting first alphabet in a word document

Example -
"Let this be the test sentence" , Suppose this line is selected , I need a Word macro to select only the first alphabet , that is 'L' and then format it in which ever way I want...
I am unable to get the macro to select only the first alphabet from the selected line.
I have tried this -
`'Selection.HomeKey Unit:=wdLine
Selection.MoveDown Unit:=wdLine, Count:=1
Selection.Expand wdLine
MsgBox (Selection.Text)`
Can somebody please give me an answer to this
I assume you mean the first character in the selection?
MsgBox Selection.Characters(1)
Or, to use it to make that character bold:
Dim firstChar As Word.Range
Set firstChar = Selection.Characters(1)
firstChar.Bold = True
Option Explicit
Sub main()
Dim firstAlphabet As Range
Selection.SetRange Start:=0, End:=1 '<--| collapse Selection to its first character
Set firstAlphabet = Selection.Range
' now use 'firstAlphabet ' range for your formatting
End Sub

Macro in Word to Underline each paragraph in document less than X characters long

I have a word doc of several pages. There are many lines in the document that are short headings, then the carriage return, then a descriptive paragraph. Not front page news.
eg
Condition Subsequent
A condition subsequent is often used in a legal context as a marker bringing an end to one's legal rights or duties. A condition subsequent may be either an event or a state of affairs that must either (1) occur or (2) fail to continue to occur.
This sort of thing goes on down to the bitter end of the long document, with over 100 headings - that need to be underlined!
I have used this code to look for all lines less than 100 characters to underline, which works, but if the last line of a paragraph is less than 100 characters that also gets underlined, which I dont want:
Sub Underline_Header()
Dim numOfLines As Integer
numOfLines = ActiveDocument.BuiltInDocumentProperties("NUMBER OF LINES")
Selection.HomeKey Unit:=wdStory
For x1 = 1 To numOfLines
Selection.HomeKey Unit:=wdLine
Selection.EndKey Unit:=wdLine, Extend:=wdExtend
char_count = Len(Selection.Range.Text)
If char_count < 100 Then
Selection.Font.Underline = True
End If
Selection.MoveDown Unit:=wdLine, Count:=1
Next x1
End Sub
But when I try this (below) to look for paragraphs and count the number of characters in the paragraph, Word throws an error at the two lines highlighted below:
Sub Underline_Header()
Dim numOfParagraphs As Integer
numOfParagraphs = ActiveDocument.BuiltInDocumentProperties("NUMBER OF PARAGRAPHS")
Selection.HomeKey Unit:=wdStory
For x1 = 1 To numOfParagraphs
*>>Selection.HomeKey Unit:=wdParagraph
>>Selection.EndKey Unit:=wdParagraph, Extend:=wdExtend*
char_count = Len(Selection.Range.Text)
If char_count < 100 Then
Selection.Font.Underline = True
End If
Selection.MoveDown Unit:=wdParagraph, Count:=1
Next x1
End Sub
EDIT SOLUTION FOUND
For posterity ...
This code finds all paragraphs with less than 100 characters (assumes a heading) and underlines them:
Sub Underline_Header()
Dim numOfParagraphs As Integer
numOfParagraphs = ActiveDocument.BuiltInDocumentProperties("NUMBER OF PARAGRAPHS")
Selection.HomeKey Unit:=wdStory
For x1 = 1 To numOfParagraphs
Selection.Paragraphs(1).Range.Select
char_count = Len(Selection.Paragraphs(1).Range)
If char_count < 100 Then
Selection.Font.Underline = True
End If
Selection.MoveDown Unit:=wdParagraph, Count:=1
Next x1
End Sub
fwiw

Insert text before and after selection and set style of new text

I can insert text before and after the selection using:
Selection.InsertBefore "start"
Selection.InsertAfter "end"
But I have no control over the style of the inserted text. How can I set the new, inserted text to a specific style (and leave the original selected text as it is)?
Below are two separate code to handle Insert After and Insert Before. Once you insert the text then depending on where is it inserted you have to select the inserted text and then change the style.
Sub InsertAfter()
Dim wrd As String
Dim rng As Range
wrd = "End"
Set rng = Selection.Range
rng.InsertAfter wrd
'~~> Remove selection. This will move the cursor at end of selected word
Selection.MoveRight Unit:=wdCharacter, Count:=1
'~~> Select the inserted word
Selection.MoveRight Unit:=wdCharacter, Count:=Len(wrd), Extend:=wdExtend
'~~> Change Style
Selection.Style = ActiveDocument.Styles("List Paragraph")
End Sub
Sub InsertBefore()
Dim wrd As String
Dim rng As Range
wrd = "Start"
Set rng = Selection.Range
rng.InsertBefore wrd
'~~> Remove selection. This will move the cursor at begining of inserted word
Selection.MoveLeft Unit:=wdCharacter, Count:=1
'~~> Select the inserted word
Selection.MoveRight Unit:=wdCharacter, Count:=Len(wrd), Extend:=wdExtend
'~~> Change Style
Selection.Style = ActiveDocument.Styles("List Paragraph")
End Sub
Here's a simple example:
Sub test()
Dim StartingCount As Long
Dim InsertBeforeCount As Long
With ActiveDocument
StartingCount = .Characters.Count
Selection.InsertBefore "start"
InsertBeforeCount = .Characters.Count - StartingCount
.Range(1, InsertBeforeCount).Font.Bold = True
Selection.InsertAfter "end"
.Range(StartingCount + InsertBeforeCount, .Characters.Count).Font.Italic = True
End With
End Sub