Some macros can be reimagined to incorporate additional functionality based on typical conditions when the user runs them. This makes them more useful without having to write a gazillion variations of the same basic idea behind the macro. This version of the delete current paragraph macro extends the implementation to allow for a conveniently deleting either the current or multiple paragraphs at once. We further include a more detailed introduction to conditional statements and the Selection as VBA sees it.
Thanks for your interest
This content is part of a paid plan.
Original delete paragraph macro
The starting point of the original delete paragraph macro was:
The Selection in VBA includes any text (or Word tables, drawing objects, etc.) in the current selection. We will focus on text-only selections throughout our articles with our main use case of helping authors write and edit faster.
If there is no selected text, then VBA treats the Selection as just the current cursor position (it's actually slightly more complicated, but that's the basic idea) in which case the "first" paragraph is the current paragraph containing the cursor (the blinking I-bar not the mouse pointer).
Extending the delete paragraphs macro
In our extension here, we still want the macro to delete the current paragraph just like before if there is no selection or if only one paragraph selected.
How many paragraphs are in the selection?
How can we check the number of paragraphs that are selected by the user?
To do this, we need a conditional statement otherwise called an If statement. (There are more types of conditional statements, but an If statement is the most common one by far.)
Conditional statement
So we need a way to tell VBA if some condition is met then perform some step in your macro.
In VBA and many other programming languages, we have to clearly tell the computer where the If ends. We can't be ambiguous or VBA will get confused and complain at us which is annoying.
Essentially, the command does exactly how it reads. If SomeCondition indeed has a value of True (or whatever condition you set such as "If SomeNumber = 123 Then") then run the steps inside the condition. Otherwise skip the steps and continue with any commands placed after the End If.
It is also customary to indent the contents of the condition a little farther over (two extra spaces here) to make identifying the commands inside or outside the condition easier.
What is the number of paragraphs in the Selection?
Now we need a way to reference how many paragraphs are in the Selection.
In a Word Selection, there cannot be "zero" paragraphs since the current paragraph counts even if no characters are selected.
Enter the Count property of the collection of Paragraphs in the Selection. We reference the paragraphs just like we did before with Selection.Paragraphs, and it looks like:
So, the easiest way of checking for multiple paragraphs in the Selection is to just see if there is one paragraph. If there is one, we delete it like before in the original macro (all the way up top). If not, we we know there has to be multiple paragraphs in the Selection. We'll address the latter case below.
This is called "pseudo-code" by the way. It won't actually run. We're just trying to get the steps down in our mind.
Putting all the ideas together for the single paragraph case, we have this in VBA:
Finally, we have the original macro recreated. This macro checks if there is one paragraph in the Selection. If so, it deletes the paragraph. If more than one paragraph is in the Selection, then it will skip the delete step and end the macro.
Deleting multiple paragraphs
Now we want the work out the second case: allow the user to delete all of the selected paragraphs (presumably more than one of them since we handled that case earlier) even if the selection is sloppy and does not include the full paragraphs.
The "sloppy selection" convenience is just because we don't want to make ourselves think any harder than we need to think when we use the macro. If we have to remember some special steps, we are much less likely to use it.
Else conditions
We need a way to tell the conditional statement to do one thing if the condition is true otherwise do something else. That's almost exactly how we write it. We include an Else part in between the If and the End if.
What do we want to do exactly?
If there is one paragraph, then delete it like normal. We did that part above.
Otherwise, if there is more than one paragraph, then delete all of them. The whole paragraphs.
This is where we have to think a little more carefully. What if the user didn't select all of the first or last paragraph? (Presumably, the middle paragraphs have no way to be partially selected. We will ignore non-contiguous selections in Word for now.)
In the original macro all the way up top, we got away with not selecting the current paragraph since the Selection.Paragraphs.First.Range part of the command did that for us. Now we don't have that luxury.
We need to include all of the first and last paragraphs using steps in the macro (in VBA terms).
How can we select all of the paragraphs?
One way to work out the steps in VBA is to imagine ourselves doing it manually.
We can imagine using the keyboard to extend the beginning of the Selection backward in the document to the start of the first paragraph. (It's a little more complicated than that since only one end of the Selection actually "active" but the idea is clear enough).
Then we could extend the end of the Selection forward in the document to the end of the last paragraph. Everything in the middle stay selected.
How do we do this in VBA? (I promise this sounds a lot harder than it is once you get the idea. VBA makes still stuff a lot easier than most other programming languages.)
To answer that, we have to dig a little deeper into understanding what a selection is in Word and how VBA sees it.
What is a Selection?
A Selection (actually any general "Range" in a Word document) is basically a starting point in the document and an ending point in the document, called Start and End, respectively. It is literally a character position, but we don't have to worry about that detail to solve our current problem.
You might guess: "Oh, just use Selection.Start and Selection.End then ..."
The trick is we can't use Selection.Start since that is already set the beginning of the current Selection. We need the beginning of the first paragraph of the Selection?
Selecting the start of the first paragraph?
We refer to the first paragraph of the Selection like we did in the original macro, but we want the Start of the first paragraph range.
We have the position in the document, but what do we do with it? That is, how can we set the start of the selection to the start of the first paragraph?
Simple Assignments in VBA
That brings us to assignments.
In general, we can set one simple variable value type like:
This makes the variable x take on the value of 1 within VBA.
Assigning the Start of the Selection
So we do the same thing with the start of the Selection. We assign the Start of the Selection with the value of the beginning of the first paragraph range.
Now we repeat all the same concepts for the end of the last paragraph. One caveat is we get the last paragraph in the Selection using Selection.Paragraphs.Last just like we did with the first paragraph in the Selection several posts ago.
Now that we have the Selection Start and End set correctly, we can just delete what we've selected.
Combining these last two statements and the delete command, we can now delete multiple if they are selected when the macro is run.
Recall these steps were to be run in the above conditional/if statement inside the "Else" part.
Putting it all together, we have our final macro.
Notice that since the macro is getting more complicated, I included some comments (the description text after the single quotes). Remember comments are ignored by VBA, but in a year or more, I may not remember what I was thinking. The comments will help me remember if I need to make any modifications or if there is a problem with the macro for some special case I did not envision when I first created it.
Usability considerations when extending macros
We need to be a little careful when extending macros in the sense that the extensions need to make sense, be intuitive, and also useful.
Consistency in our macros
For example in this article, I just extended our original one-paragraph version to handle the special case of multiple selected paragraphs. I made it easier to use by allowing for a sloppy selection with incompletely selected paragraphs, so the user can just make a quick selection, delete it, and move on with their work.
The extension makes sense in the overall purpose of the original macro while also being as easy and intuitive to use as possible.
Using the Selection in VBA
In practice, it's probably better to not constantly refer to the Selection object directly since it can be slow and make your screen "flicker" if you're making lots of changes. However, for simple macros, it's usually easier.
A fancier method uses Ranges, but that is a topic for another day.
Another method to do the same task
There is often more than one way to solve a problem.
In this case, we could have accomplished the same thing without a conditional statement. In fact, it would be ever so slightly more efficient.
How?
By skipping the single paragraph part of our solution and just running the multiple paragraphs part.
If you think about it, all of the steps of extending the selection forward and backward in the document would apply just fine even if there is only one paragraph. I don't care about hyper efficiency here since I'll never notice the difference in a practical sense. Here is the simplified macro:
Notice how it gets the same job done with a simpler set of steps, but the thinking level to get to this set of steps is a little higher or requires a little more practice with VBA in Word.
You would hardly ever notice any variation in run time less than about a quarter of a second, and this macro runs much faster than that.