![]() |
|
|
|
#1
|
|||
|
|||
|
If a paragraph starts with <S1> and the next paragraph is starts with <S2> in the to change them to <S1-S2>. (eg. <S1-S2>; <S2-S3>, <S3-S4>) <S1>Some Text <S2>Some Text Change to: <S1>Some Text <S1-S2>Some Text |
|
#2
|
||||
|
||||
|
Is this macro meant to work on the current paragraph or process the entire document?
Does '<S' appear anywhere in the document that you don't want to hit with the macro? What happens if <S1-S2> is followed by <S3>?
__________________
Andrew Lockton Chrysalis Design, Melbourne Australia |
|
#3
|
|||
|
|||
|
for entire document.
if <S1-S2> is followed by <S3> need to the <S3> has <S2-S3> sample file also attached. |
|
#4
|
|||
|
|||
|
Hi, try this. First I typed then removed my comments becuase, hopefully, the code is quite simple. Besides, I used selection, which I prefer. If you want to work on the whole doc, press Ctrl+A.
Code:
Sub Paras_Start_Change_1()
'Change the selected paras from Before to After:
'Before:
' <S1>Text
' <S2>Text
' <S3>Text
' <S4>Text
' <S5>Text
'After:
' <S1>Text
' <S1-S2>Text
' <S2-S3>Text
' <S3-S4>Text
' <S4-S5>Text
Dim oSel As range
Dim oPar As Paragraph
Application.ScreenUpdating = False
Set oSel = selection.range
For i = selection.range.Paragraphs.count To 1 Step -1
Set oPar = oSel.Paragraphs(i)
oPar.range.Select
selection.Collapse 1
selection.MoveUp Unit:=wdParagraph, count:=1
If selection.Start < oSel.Start Then Exit For
selection.MoveRight Unit:=wdCharacter, count:=1
selection.MoveEndUntil Cset:=">"
selection.Copy
selection.MoveDown Unit:=wdParagraph, count:=1
selection.MoveRight Unit:=wdCharacter, count:=1
selection.PasteAndFormat (wdFormatOriginalFormatting)
selection.TypeText text:="-"
Next i
Application.ScreenUpdating = True
End Sub
|
|
#5
|
|||
|
|||
|
balavaka,
Your sample document does not reflect your stated objective. Your statement below: "If a paragraph starts with <S1> and the next paragraph is starts with <S2> in the to change them to <S1-S2>." Example: <S1> AAA <S2> BBB Meets your conditions. Change "them" would imply: Would be: <S1-S2> <S1-S2> What exactly are you trying to achieve? What is the condition requiring change and what do you want changed. BREAK Vivka, why do you prefer working with the selection object? |
|
#6
|
|||
|
|||
|
Hi, Greg! I've learned (and still learning) a lot from your codes, as well as from macropod's, gmayor's, guessed's and other experts' (excuse me if I don't mention all those who are my indirect teachers). I'm not a programmer (I'm a psychologist) and vba is a little hobby of mine because I have to work with texts every day. As for 'selection', I may have used a wrong term. To be more precise, I prefer a selected range to an active document because the former allows working on any part of the document, including the whole document. And I'm fully aware that my solutions are not elegant and the most effective but they may be viewed as a starting point for better codes. Anyway, I'm open to new knowledge and will be greateful for it.
|
|
#7
|
|||
|
|||
|
Yes same for the others too.
Only if follows to another <S1> or <S2> or <S3> levels only need to change as in would be change. Example <S1> AAA <S2> BBB <S3> CCC <S4> CCC Would be: <S1>AAA <S1-S2>BBB <S2-S3>CCC <S3-S4>DDD |
|
#8
|
|||
|
|||
|
Balavaka, this is exactly what my code is doing. Have you tried it?
|
|
#9
|
|||
|
|||
|
vivka,
I'm sorry, but your code doesn't do that exactly. Your code is altering every subsequent paragraph to the first paragraph regardless is the subsequent paragraph meets the condition for change. The condition for change is "Is the subsequent paragraph S index 1 more than the reference paragraph. Running your code on the last sample provided returns: <S1> AAA < S1- S1-S2> BBB < S2-S3> CCC < S3-S4> CCC Running it on a sample where the one or more of the next paragraphs are NOT one index higher e.g., <S1> AAA <S2> BBB <S2> bbb (note this paragraph is not indexed 1 higher than the previous) <S3> CCC <S4> DDD Returns this: <S1> AAA < S1- S1-S2> BBB < S2-S2> bbb < S2-S3> CCC < S3-S4> CCC With that said, Balavaka your examples are still as clear as mud. How do you go from <S4> CCC to <S3-S4) DDD? This is not a simple process. However, the following might get you close: Code:
Sub ScratchMacro()
'A basic Word Macro coded by Gregory K. Maxey
Dim lngIndex As Long
Dim oRng As Range
Dim oParRng As Range
Dim arrIndexParts() As String
Dim strRefIndex As String
Set oRng = ActiveDocument.Range 'or selection range
For lngIndex = 1 To oRng.Paragraphs.Count - 1
'See if the paragraph and subsequent paragraph have the indexing flag.
If InStr(oRng.Paragraphs(lngIndex).Range.Text, "<S") = 1 And InStr(oRng.Paragraphs(lngIndex + 1).Range.Text, "<S") = 1 Then
Set oParRng = oRng.Paragraphs(lngIndex).Range
'Move the range until after the "<S"
oParRng.MoveStart wdCharacter, 2
'See if the paragraph is a simple or complex index e.g., "S1" or "S1-S2"
If InStr(oParRng.Text, "-S") > 0 And InStr(oParRng.Text, "-S") < InStr(oParRng.Text, "> ") Then
'Complex, move range passed the second index flag.
oParRng.MoveStartUntil Cset:="S"
oParRng.MoveStart wdCharacter, 1
'Get the index number.
arrIndexParts = Split(oParRng.Text, "> ")
strRefIndex = arrIndexParts(0)
Else
'Get the index number
arrIndexParts = Split(oParRng.Text, "> ")
strRefIndex = arrIndexParts(0)
End If
'Get the subsequent paragraph index number and compare to previous
Set oParRng = oRng.Paragraphs(lngIndex + 1).Range
oParRng.MoveStart wdCharacter, 2
arrIndexParts = Split(oParRng.Text, "> ")
If strRefIndex + 1 = arrIndexParts(0) Then
'Condition met. Create complex index.
oParRng.InsertBefore strRefIndex & "-S"
End If
End If
Next lngIndex
lbl_Exit:
Exit Sub
End Sub
Last edited by gmaxey; 08-28-2023 at 06:15 PM. |
|
#10
|
|||
|
|||
|
Thank you, Greg, for another interesting lesson on vba and patience! My life principle is "Live and learn." Knowledge is as precious as gold for me. As to the code I came up with, it does the task as I understood it and I didn't open the sample file. I am grateful to you and other experts on this forum for sharing your gems of knowledge!
|
|
#11
|
|||
|
|||
|
vivka,
I can tell that you want to learn so I don't feel like I'm poking you in your eye with what is intended to be constructive criticism. Look at the code you posted again. Your notes state that is converts: <S1> <S2> <S3> <S4> <S5> To: <S1> <S1-S2> <S2-S3> <S3-S4> <S4-S5> When it is actually doing this: Two problems in your code. 1) You are processing the first paragraph when you don't need to and 2) you are using smart cut and paste which is inserting unwanted spaces. This does as your notes describes: Code:
Sub Paras_Start_Change_1()
'Modified by GKM
Dim lngIndex 'Declare variable for indexing.
Dim oSel As Range
Dim oPar As Paragraph
Dim bSCP As Boolean 'Added variable to store user setting.
Application.ScreenUpdating = False
'Save user setting
bSCP = Options.PasteSmartCutPaste
'Turn off smart cut and paste
Options.PasteSmartCutPaste = False
Set oSel = Selection.Range
'Change .Count to 1 to .Count to 2
For lngIndex = Selection.Range.Paragraphs.Count To 2 Step -1
Set oPar = oSel.Paragraphs(lngIndex)
oPar.Range.Select
With Selection
.Collapse 1
.MoveUp Unit:=wdParagraph, Count:=1
.MoveRight Unit:=wdCharacter, Count:=1
.MoveEndUntil Cset:=">"
.Copy
.MoveDown Unit:=wdParagraph, Count:=1
.MoveRight Unit:=wdCharacter, Count:=1
.PasteAndFormat (wdFormatOriginalFormatting)
.TypeText Text:="-"
End With
Next lngIndex
'Restore user setting.
Options.PasteSmartCutPaste = bSCP
Application.ScreenUpdating = True
End Sub
|
|
#12
|
|||
|
|||
|
Thank you, Greg, for your corrections and clear explanations! Your code is definitely better! "I am not a magician, I'm just learning to be a magician" (a phrase from an old Soviet film Cinderella).
|
|
|
|