1
\$\begingroup\$

I have some code in a particular coding language, and I am trying to clean it up by adding spaces around the variables. I wrote this code, and it works on small amounts of text and if I set a break point and run through it manually for large amounts of text. But when I try to run through it without frequently stopping the macro, Word stops responding and I have to restart the program. I think it is because the code is inefficient, but I don't have enough knowledge of vba to make it more efficient.

My code

Sub SpaceVarsAndEqns()
Dim i As Long
Dim paragraphIndex As Long
Dim characterIndex As Long
Dim isVar As Boolean
Dim varIndexBegin As Long
Dim varIndexEnd As Long
Dim Doc As Range
Dim Par As Range
Dim Char As Range
Set Doc = ActiveDocument.Range
For paragraphIndex = 1 To Doc.Paragraphs.Count
 Set Par = Doc.Paragraphs(paragraphIndex).Range
 isVar = False
 characterIndex = 1
 Do
 Set Char = Par.Characters(characterIndex)
 If isVar Then
 If Char.Text = "$" Then
 varIndexEnd = characterIndex
 If Not Par.Characters(varIndexEnd + 1).Text = " " Then
 Par.Characters(varIndexEnd).InsertAfter (" ")
 characterIndex = characterIndex + 1
 End If
 If Not Par.Characters(varIndexBegin - 1).Text = " " Then
 Par.Characters(varIndexBegin).InsertBefore (" ")
 characterIndex = characterIndex + 1
 End If
 varIndexBegin = 0
 varIndexEnd = 0
 isVar = False
 ElseIf Not (IsAlphaNumber(Char.Text) Or (Char.Text = ".")) Then
 varIndexBegin = 0
 varIndexEnd = 0
 isVar = False
 End If
 Else
 If Par.Characters(characterIndex).Text = "$" Then
 varIndexBegin = characterIndex
 isVar = True
 End If
 End If
 characterIndex = characterIndex + 1
 Loop While (characterIndex <= Par.Characters.Count)
Next paragraphIndex
End Sub

Text Before

\begin{bmatrix} $eval(($d$*$d.pmv$)/(|$d.et$|)*($d.et$*$xm$) + (($b$*-1)*$d.pmv$)/(|$d.et$|)*($d.et$*$ym$) + $dist5,0ドル.###)\\ $eval((((($a$*$d$)-$d.et$)/($b$))*$d.pmv$*-1)/(|$d.et$|)*($d.et$*$xm$) + ($a$*$d.pmv$)/(|$d.et$|)*($d.et$*$ym$)+ $dist6,0ドル.###) \end{bmatrix}

Text After

\begin{bmatrix} $eval(( $d$ * $d.pmv$ )/(| $d.et$ |)*( $d.et$ * $xm$ ) + (( $b$ *-1)* $d.pmv$ )/(| $d.et$ |)*( $d.et$ * $ym$ ) + $dist5$ ,0.###)\\ $eval((((( $a$ * $d$ )- $d.et$ )/( $b$ ))* $d.pmv$ *-1)/(| $d.et$ |)*( $d.et$ * $xm$ ) + ( $a$ * $d.pmv$ )/(| $d.et$ |)*( $d.et$ * $ym$ )+ $dist6$ ,0.###) \end{bmatrix}

I think it could be improved by using a find method to find two consecutive $ symbols, and checking if the characters in between are consistent with a variable. However, I don't know how I would add spaces doing it this way.

200_success
145k22 gold badges190 silver badges478 bronze badges
asked Jun 23, 2017 at 17:28
\$\endgroup\$
9
  • \$\begingroup\$ Not sure why this has DV's/CV's, totally on-topic. Code works, just not well. \$\endgroup\$ Commented Jun 23, 2017 at 18:09
  • \$\begingroup\$ @EBrown it's off-topic because OP looks for a specific solution he's apparently not able to implement. \$\endgroup\$ Commented Jun 23, 2017 at 19:05
  • \$\begingroup\$ Can you confirm that the macro works, uninterrupted, for a small document? If no test case works, then it might not be appropriate as a Code Review question. \$\endgroup\$ Commented Jun 23, 2017 at 19:22
  • \$\begingroup\$ @t3chb0t I'm inclined to say that's wrong because of the "I think..." bit. \$\endgroup\$ Commented Jun 23, 2017 at 19:33
  • 2
    \$\begingroup\$ @200_success The example text and resulting modification in the question body was modified by the macro and it worked. \$\endgroup\$ Commented Jun 23, 2017 at 20:51

1 Answer 1

1
\$\begingroup\$

Here's a version using Regular Expressions.

Option Explicit
Sub SpaceVarsAndEqns()
 Dim DocumentRange As Range, ParagraphRange As Range
 Dim i As Long, P As Paragraph
 Dim Pattern As String, Replace As String, RegEx As New RegExp
 Dim ParagraphText As String
 Pattern = "(?:\s?)\$[^$(]*\$(?:\s?)"
 Replace = " $& "
 With RegEx
 .Global = True
 .MultiLine = True
 .IgnoreCase = True
 .Pattern = Pattern
 End With
 Set DocumentRange = ActiveDocument.Range
 For i = 1 To DocumentRange.Paragraphs.Count
 Set P = DocumentRange.Paragraphs(i)
 ParagraphText = P.Range.Text
 If RegEx.Test(ParagraphText) Then
 P.Range.Text = RegEx.Replace(ParagraphText, Replace)
 End If
 Next
End Sub

Before:

\begin{bmatrix} $eval(($d$*$d.pmv$)/(|$d.et$|)*($d.et$*$xm$) + (($b$*-1)*$d.pmv$)/(|$d.et$|)*($d.et$*$ym$) + $dist5,0ドル.###)\\ $eval((((($a$*$d$)-$d.et$)/($b$))*$d.pmv$*-1)/(|$d.et$|)*($d.et$*$xm$) + ($a$*$d.pmv$)/(|$d.et$|)*($d.et$*$ym$)+ $dist6,0ドル.###) \end{bmatrix}

After:

\begin{bmatrix} $eval(( $d$ * $d.pmv$ )/(| $d.et$ |)*( $d.et$ * $xm$ ) + (( $b$ *-1)* $d.pmv$ )/(| $d.et$ |)*( $d.et$ * $ym$ ) + $dist5$ ,0.###)\\ $eval((((( $a$ * $d$ )- $d.et$ )/( $b$ ))* $d.pmv$ *-1)/(| $d.et$ |)*( $d.et$ * $xm$ ) + ( $a$ * $d.pmv$ )/(| $d.et$ |)*( $d.et$ * $ym$ )+ $dist6$ ,0.###) \end{bmatrix}


This requires adding a reference to the Microsoft VBScript Regular Expressions 5.5 by going to Tools> References and checking that box:

Adding a reference to Microsoft VBScript Regular Expressions 5.5

You can read more on Regular Expressions in VBA in this Stack Overflow answer.

answered Jul 5, 2017 at 21:03
\$\endgroup\$
2
  • \$\begingroup\$ For the record, the reason I used the i loop counter rather than For Each P in DocumentRange.Paragraphs directly was because the latter resulting in an infinite loop due to the paragraphs being edited during the loop. \$\endgroup\$ Commented Jul 5, 2017 at 21:04
  • \$\begingroup\$ Also I have no recollection of ever writing this code... \$\endgroup\$ Commented Mar 26, 2022 at 2:06

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.