Hello,
I recorded a macro that formats a report by deleting every 6th line. It is working fine. I’d like to create a do loop that repeats the routine until it reaches EOF. Any help would be appreciated.
![]() |
Patch reliability is unclear. Unless you have an immediate, pressing need to install a specific patch, don't do it. |
SIGN IN | Not a member? | REGISTER | PLUS MEMBERSHIP |
Home » Forums » AskWoody support » Productivity software by function » Visual Basic for Applications » Do loop (Word XP)
Try this. It may not be the most efficient or elegant code possible.
Sub DeleteEverySixthLine()
Dim lngLine As Long
Dim lngEnd As Long
Selection.HomeKey Unit:=wdStory
Selection.EndKey Unit:=wdLine
lngEnd = ActiveDocument.Bookmarks(“EndOfSel”).End
Do
Selection.MoveDown Unit:=wdLine, Count:=1
Selection.EndKey Unit:=wdLine
If ActiveDocument.Bookmarks(“EndOfSel”).End = lngEnd Then
Exit Do
Else
lngLine = lngLine + 1
lngEnd = ActiveDocument.Bookmarks(“EndOfSel”).End
End If
If lngLine Mod 5 = 0 Then
Selection.HomeKey Unit:=wdLine
Selection.MoveDown Unit:=wdLine, Extend:=wdExtend
Selection.Delete
End If
Loop
End Sub
Hans,
I didn’t know you did Word too! Good to hear from you. Thanks, your code works. I didn’t give you the whole story because I was hoping I could expand upon the loop idea and do the rest of the work myself, but alas, it’s a little too much. What’s really going on is this: I need to delete the first 13 lines on every page, then delete every 6th line 6 times.
I understand some of your logic: You are selecting the entire document so that you can know when you reach (“EndOf Sel”) and I think that is how the lngEnd is defined and I think lngLine is your counter. What do I need to paste and modify to include the 13 deletions along with the 6th line deletion?
Thanks.
The code I posted doesn’t select the entire document, but it uses the built-in bookmark EndOfSel that represents the end of the current selection to see if it changes when you move down a line; it it doesn’t, you have reached the document.
Here is revised code to do what you want. It assumes that each page is long enough to be able to delete the first 13 lines and every 6th line 6 times. It does check when you have reached the last page of the document. The procedure HandlePage does one page, the procedure HandleDocument does the entire document (it calls HandlePage for each page). The latter is the one you must run.
Test thoroughly on a copy of the real document!
Sub HandlePage()
Dim i As Integer
Selection.MoveDown Unit:=wdLine, Count:=13, Extend:=wdExtend
Selection.Delete
For i = 1 To 6
Selection.MoveDown Unit:=wdLine, Count:=5
Selection.HomeKey
Selection.MoveDown Unit:=wdLine, Extend:=wdExtend
Selection.Delete
Next i
End Sub
Sub HandleDocument()
Dim lngStart As Long
Selection.HomeKey Unit:=wdStory
Do
lngStart = ActiveDocument.Bookmarks(“Page”).Start
HandlePage
Selection.GoToNext What:=wdGoToPage
If ActiveDocument.Bookmarks(“Page”).Start = lngStart Then
Exit Do
Else
lngStart = ActiveDocument.Bookmarks(“Page”).Start
End If
Loop
End Sub
Hans,
I’m getting the hang of this, and the HandlePage sub is working. I just have one glitch: I need this code:
Selection.MoveDown Unit:=wdLine, Count:=13, Extend:=wdExtend
Selection.Delete
to only run when you first call up the routine (for the first page). The rest of the routine is fine, but for each subsequent page, I need to change the number from 13 (in the code above) to 18.
So basically, how do you get a routine to run once and then ignore that part of the routine? Would I use a counter and set it to one? I could then have the 18 lines that separate each of the other pages to be part of the routine.
Thanks.
I would indeed keep track op the page through a counter.
Sub HandlePage(intPage As Integer)
Dim i As Integer
Dim intCount As Integer
If intPage = 1 Then
intCount = 13
Else
intCount = 18
End If
Selection.MoveDown Unit:=wdLine, Count:=intCount, Extend:=wdExtend
Selection.Delete
For i = 1 To 6
Selection.MoveDown Unit:=wdLine, Count:=5
Selection.HomeKey
Selection.MoveDown Unit:=wdLine, Extend:=wdExtend
Selection.Delete
Next i
End Sub
Sub HandleDocument()
Dim lngStart As Long
Dim intPage As Integer
Selection.HomeKey Unit:=wdStory
Do
intPage = intPage + 1
lngStart = ActiveDocument.Bookmarks(“Page”).Start
HandlePage intPage
Selection.GoToNext What:=wdGoToPage
If ActiveDocument.Bookmarks(“Page”).Start = lngStart Then
Exit Do
Else
lngStart = ActiveDocument.Bookmarks(“Page”).Start
End If
Loop
End Sub
You may have to fiddle a bit to get it right.
Hans,
Can you explain a couple of things? When I run the macro, the first page is perfect, but then everything is off. I’m noticing that the page breaks (which are manual and are included in the 18 lines) are still there, and lines that contain data are being deleted.
What do these lines of code do?
lngStart = ActiveDocument.Bookmarks(“Page”).Start
HandlePage intPage
Selection.GoToNext What:=wdGoToPage
If ActiveDocument.Bookmarks(“Page”).Start = lngStart
I wanted to avoid sending you the document and fix this myself, but I made need to send it in order for you to really see what I’m trying to accomplish. Would that be OK?
(1) lngStart = ActiveDocument.Bookmarks(“Page”).Start
(2) HandlePage intPage
(3) Selection.GoToNext What:=wdGoToPage
(4) If ActiveDocument.Bookmarks(“Page”).Start = lngStart Then
Line (1) sets the lngStart variable to the position of the start of the current page.
Line (2) processes the current page (i.e. deletes the first 13 or 18 lines, then 5 times deletes the 6th line of the remainder.
Line (3) moves to the next page
Line (4) compares the position of the start of the current page to the value stored in lngStart. If they are equal, we didn’t really move down a page, so we must already be on the last page. Time to get out (Exit Do).
If you can’t solve this yourself, make a copy of the document, replace any sensitive information with dummy data, and attach it to a reply. It should be below 100 KB; if it’s too large, make a zip file and attach that.
Hans,
I’m disappointed in myself because I can read this and understand what is happening, yet I can’t get it to work. I’ve attached the file that contains your macro, as well as my other macros (which will reveal my thought processes). The first macro in the list actually works, but it was created by recording keystrokes. Anyway, thanks for all of your help.
Hans,
To check myself when I got your email, I went into the above post, opened the attachment and clicked Tools, Macros, and there they are. I see them. Anyway, I saved the file I was working in to another folder and opened it up to make sure it contained the macros and it does. If you don’t see them, I don’t know what could be wrong. There’s no way that macros get stripped out of a file, is there?
The way Word deletes text immediately after a hard page break is a bit strange.
Frankly, I don’t understand why you want to delete 18 lines on the 2nd and following pages. By trial and error, the following seemed reasonable, but of course I don’t know your purpose.
Sub HandlePage(intPage As Integer)
Dim i As Integer
Selection.MoveDown Unit:=wdLine, Count:=13 – (intPage > 1), Extend:=wdExtend
Selection.Delete
If intPage > 1 Then
Selection.Delete
End If
For i = 1 To 6
Selection.MoveDown Unit:=wdLine, Count:=5
Selection.HomeKey
Selection.MoveDown Unit:=wdLine, Extend:=wdExtend
Selection.Delete
Next i
End Sub
Sub HandleDocument()
Dim lngStart As Long
Dim intPage As Integer
Selection.HomeKey Unit:=wdStory
Do
intPage = intPage + 1
lngStart = ActiveDocument.Bookmarks(“Page”).Start
HandlePage intPage
Selection.GoToNext What:=wdGoToPage
If ActiveDocument.Bookmarks(“Page”).Start = lngStart Then
Exit Do
Else
lngStart = ActiveDocument.Bookmarks(“Page”).Start
End If
Loop
End Sub
Note: Perhaps you also want to delete the last line on each page?
Hans,
I will gladly share the plan. Eventually this data is going to become records in Excel. I couldn’t get the formatting to work in Excel, so I am using Word as a formatting stage to strip out all unnecessary blank lines, so that I end up with a steady stream of the 5 fields.
Once I get it into Excel there are other challenges because I now have to transpose the spot info with the numbers into 5 columns, plus take the Program title, time slot and Program number and combine all of that to create a complete record.
That was my thinking. I’m all ears, so please share your thoughts with me.
The Word document you posted yesterday looks like a report generated by another application. Does that application have an option to export to other formats, such as fixed width or delimited text file, Excel, DBase, …?
If not, should the entire document become one table in Excel? If so, the following modification will convert the document to a form that can be copied and pasted into Excel, then converted to a table using Data | Text to Columns with the vertical bar | as delimiter.
Sub HandlePage(intPage As Integer)
Dim i As Integer
Selection.MoveDown Unit:=wdLine, Count:=13 – (intPage > 1), Extend:=wdExtend
Selection.Delete
If intPage > 1 Then
Selection.Delete
End If
For i = 1 To 6
Selection.MoveDown Unit:=wdLine, Count:=5
Selection.HomeKey
Selection.MoveDown Unit:=wdLine, Extend:=wdExtend
Selection.Delete
Next i
Selection.MoveDown Unit:=wdLine, Count:=2, Extend:=wdExtend
Selection.Delete
End Sub
Sub HandleDocument()
Dim lngStart As Long
Dim intPage As Integer
Selection.HomeKey Unit:=wdStory
Do
intPage = intPage + 1
lngStart = ActiveDocument.Bookmarks(“Page”).Start
HandlePage intPage
Selection.GoToNext What:=wdGoToPage
If ActiveDocument.Bookmarks(“Page”).Start = lngStart Then
Exit Do
Else
lngStart = ActiveDocument.Bookmarks(“Page”).Start
End If
Loop
Selection.HomeKey Unit:=wdStory
With Selection.Find
.ClearFormatting
.Text = “^m”
.Replacement.Text = “”
.Replacement.ClearFormatting
.MatchWildcards = False
.Execute Replace:=wdReplaceAll
End With
End Sub
Hi, Hans. I have found your post during a search to find something that I can use to delete every third line of text from a document. I massaged your code and it worked great. Here comes the “except for” part of this. The document is 34 pages long and was created from a text file. After 6 pages, the macro stops. It stops at a point that doesn’t appear to be anything special. Any ideas what I may have done wrong? The only thing that I changed about your code was “If lngLine Mod 3 = 0 “. I have been tearing my hair out!! I appreciate your help. Thanks.
I tried it on a document with over a hundered pages and the macro ran to completion without problems, so without seeing the document it’s hard to say what goes wrong. By the way, if you want to delete every 3rd line, you should use
If lngLine Mod 2 = 0 Then
It might be easier to work with the text file directly. Do you want to save it as a text file again, or should the end result be a Word document?
Ultimately the text/document will be converted to a PDF. I will try to run it on a text file instead of a Word doc. I am just trying to make it easier on someone who has to go through these documents and perform this action on a regular basis. Thanks for the correction, but the way. I’ll keep you posted.
Here is a macro that will read a text file (specified by strInput) and write its lines with the exception of every third line to a new text file (specified by strOutput). It should be *much* faster than a macro that processes a Word document.
Sub DeleteEveryThirdLine()
‘ Change the constants as needed
Const strSource = “C:TestSource.txt”
Const strTarget = “C:TestTarget.txt”
Dim f1 As Integer
Dim f2 As Integer
Dim strLine As String
Dim n As Long
f1 = FreeFile
Open strSource For Input As #f1
f2 = FreeFile
Open strTarget For Output As #f2
Do While Not EOF(f1)
Line Input #f1, strLine
n = n + 1
If n Mod 3 > 0 Then
Print #f2, strLine
End If
Loop
Close #f2
Close #f1
End Sub
Note: this macro has … Mod 3 because it works differently.
If it works correctly for you, you can add bells and whistles, such as prompting the user for the input and output files.
Your code works perfectly. However, I went back to the user and they need 2 things. A blank line needs to replace the deleted line so that there is an obvious space between each set of 2. Also, if the third line slated for deletion happens to fall on a blank line, then they need to delete the 4th line instead of the 3rd line. Again, any assistance is appreciated. Thanks.
Try changing the loop within the macro to
Do While Not EOF(f1)
Line Input #f1, strLine
n = n + 1
If n Mod 3 = 0 Then
If strLine = “” Then
n = n – 1
Else
Print #f2, “”
End If
Else
Print #f2, strLine
End If
Loop
Test thoroughly to see if the code handles all blank lines the way the user wants.
It looks like the first iteration of the code is handling the entire project handily. The text file is extremely hard to read in the first place, so I need to test some more just to make sure that there are no weird happenings. Thanks for all of your help!! I couldn’t have done this without your assistance!
The Word document you posted yesterday looks like a report generated by another application. Does that application have an option to export to other formats, such as fixed width or delimited text file, Excel, DBase, …?
If not, should the entire document become one table in Excel? If so, the following modification will convert the document to a form that can be copied and pasted into Excel, then converted to a table using Data | Text to Columns with the vertical bar | as delimiter.
Sub HandlePage(intPage As Integer)
Dim i As Integer
Selection.MoveDown Unit:=wdLine, Count:=13 – (intPage > 1), Extend:=wdExtend
Selection.Delete
If intPage > 1 Then
Selection.Delete
End If
For i = 1 To 6
Selection.MoveDown Unit:=wdLine, Count:=5
Selection.HomeKey
Selection.MoveDown Unit:=wdLine, Extend:=wdExtend
Selection.Delete
Next i
Selection.MoveDown Unit:=wdLine, Count:=2, Extend:=wdExtend
Selection.Delete
End Sub
Sub HandleDocument()
Dim lngStart As Long
Dim intPage As Integer
Selection.HomeKey Unit:=wdStory
Do
intPage = intPage + 1
lngStart = ActiveDocument.Bookmarks(“Page”).Start
HandlePage intPage
Selection.GoToNext What:=wdGoToPage
If ActiveDocument.Bookmarks(“Page”).Start = lngStart Then
Exit Do
Else
lngStart = ActiveDocument.Bookmarks(“Page”).Start
End If
Loop
Selection.HomeKey Unit:=wdStory
With Selection.Find
.ClearFormatting
.Text = “^m”
.Replacement.Text = “”
.Replacement.ClearFormatting
.MatchWildcards = False
.Execute Replace:=wdReplaceAll
End With
End Sub
Hans,
I will gladly share the plan. Eventually this data is going to become records in Excel. I couldn’t get the formatting to work in Excel, so I am using Word as a formatting stage to strip out all unnecessary blank lines, so that I end up with a steady stream of the 5 fields.
Once I get it into Excel there are other challenges because I now have to transpose the spot info with the numbers into 5 columns, plus take the Program title, time slot and Program number and combine all of that to create a complete record.
That was my thinking. I’m all ears, so please share your thoughts with me.
The way Word deletes text immediately after a hard page break is a bit strange.
Frankly, I don’t understand why you want to delete 18 lines on the 2nd and following pages. By trial and error, the following seemed reasonable, but of course I don’t know your purpose.
Sub HandlePage(intPage As Integer)
Dim i As Integer
Selection.MoveDown Unit:=wdLine, Count:=13 – (intPage > 1), Extend:=wdExtend
Selection.Delete
If intPage > 1 Then
Selection.Delete
End If
For i = 1 To 6
Selection.MoveDown Unit:=wdLine, Count:=5
Selection.HomeKey
Selection.MoveDown Unit:=wdLine, Extend:=wdExtend
Selection.Delete
Next i
End Sub
Sub HandleDocument()
Dim lngStart As Long
Dim intPage As Integer
Selection.HomeKey Unit:=wdStory
Do
intPage = intPage + 1
lngStart = ActiveDocument.Bookmarks(“Page”).Start
HandlePage intPage
Selection.GoToNext What:=wdGoToPage
If ActiveDocument.Bookmarks(“Page”).Start = lngStart Then
Exit Do
Else
lngStart = ActiveDocument.Bookmarks(“Page”).Start
End If
Loop
End Sub
Note: Perhaps you also want to delete the last line on each page?
If you play with the drop-down in that dialog, you might find that the macros are stored either in the document’s attached template or in Normal.dot, rather than in the document itself. If the contents of the document are not essential to understand the code, you could open the editor and export the modules to .bas files. (For easiest posting, zip the .bas files together and upload the ZIP file.)
If you play with the drop-down in that dialog, you might find that the macros are stored either in the document’s attached template or in Normal.dot, rather than in the document itself. If the contents of the document are not essential to understand the code, you could open the editor and export the modules to .bas files. (For easiest posting, zip the .bas files together and upload the ZIP file.)
Hans,
To check myself when I got your email, I went into the above post, opened the attachment and clicked Tools, Macros, and there they are. I see them. Anyway, I saved the file I was working in to another folder and opened it up to make sure it contained the macros and it does. If you don’t see them, I don’t know what could be wrong. There’s no way that macros get stripped out of a file, is there?
Hans,
I’m disappointed in myself because I can read this and understand what is happening, yet I can’t get it to work. I’ve attached the file that contains your macro, as well as my other macros (which will reveal my thought processes). The first macro in the list actually works, but it was created by recording keystrokes. Anyway, thanks for all of your help.
(1) lngStart = ActiveDocument.Bookmarks(“Page”).Start
(2) HandlePage intPage
(3) Selection.GoToNext What:=wdGoToPage
(4) If ActiveDocument.Bookmarks(“Page”).Start = lngStart Then
Line (1) sets the lngStart variable to the position of the start of the current page.
Line (2) processes the current page (i.e. deletes the first 13 or 18 lines, then 5 times deletes the 6th line of the remainder.
Line (3) moves to the next page
Line (4) compares the position of the start of the current page to the value stored in lngStart. If they are equal, we didn’t really move down a page, so we must already be on the last page. Time to get out (Exit Do).
If you can’t solve this yourself, make a copy of the document, replace any sensitive information with dummy data, and attach it to a reply. It should be below 100 KB; if it’s too large, make a zip file and attach that.
Hans,
Can you explain a couple of things? When I run the macro, the first page is perfect, but then everything is off. I’m noticing that the page breaks (which are manual and are included in the 18 lines) are still there, and lines that contain data are being deleted.
What do these lines of code do?
lngStart = ActiveDocument.Bookmarks(“Page”).Start
HandlePage intPage
Selection.GoToNext What:=wdGoToPage
If ActiveDocument.Bookmarks(“Page”).Start = lngStart
I wanted to avoid sending you the document and fix this myself, but I made need to send it in order for you to really see what I’m trying to accomplish. Would that be OK?
I would indeed keep track op the page through a counter.
Sub HandlePage(intPage As Integer)
Dim i As Integer
Dim intCount As Integer
If intPage = 1 Then
intCount = 13
Else
intCount = 18
End If
Selection.MoveDown Unit:=wdLine, Count:=intCount, Extend:=wdExtend
Selection.Delete
For i = 1 To 6
Selection.MoveDown Unit:=wdLine, Count:=5
Selection.HomeKey
Selection.MoveDown Unit:=wdLine, Extend:=wdExtend
Selection.Delete
Next i
End Sub
Sub HandleDocument()
Dim lngStart As Long
Dim intPage As Integer
Selection.HomeKey Unit:=wdStory
Do
intPage = intPage + 1
lngStart = ActiveDocument.Bookmarks(“Page”).Start
HandlePage intPage
Selection.GoToNext What:=wdGoToPage
If ActiveDocument.Bookmarks(“Page”).Start = lngStart Then
Exit Do
Else
lngStart = ActiveDocument.Bookmarks(“Page”).Start
End If
Loop
End Sub
You may have to fiddle a bit to get it right.
Hans,
I’m getting the hang of this, and the HandlePage sub is working. I just have one glitch: I need this code:
Selection.MoveDown Unit:=wdLine, Count:=13, Extend:=wdExtend
Selection.Delete
to only run when you first call up the routine (for the first page). The rest of the routine is fine, but for each subsequent page, I need to change the number from 13 (in the code above) to 18.
So basically, how do you get a routine to run once and then ignore that part of the routine? Would I use a counter and set it to one? I could then have the 18 lines that separate each of the other pages to be part of the routine.
Thanks.
The code I posted doesn’t select the entire document, but it uses the built-in bookmark EndOfSel that represents the end of the current selection to see if it changes when you move down a line; it it doesn’t, you have reached the document.
Here is revised code to do what you want. It assumes that each page is long enough to be able to delete the first 13 lines and every 6th line 6 times. It does check when you have reached the last page of the document. The procedure HandlePage does one page, the procedure HandleDocument does the entire document (it calls HandlePage for each page). The latter is the one you must run.
Test thoroughly on a copy of the real document!
Sub HandlePage()
Dim i As Integer
Selection.MoveDown Unit:=wdLine, Count:=13, Extend:=wdExtend
Selection.Delete
For i = 1 To 6
Selection.MoveDown Unit:=wdLine, Count:=5
Selection.HomeKey
Selection.MoveDown Unit:=wdLine, Extend:=wdExtend
Selection.Delete
Next i
End Sub
Sub HandleDocument()
Dim lngStart As Long
Selection.HomeKey Unit:=wdStory
Do
lngStart = ActiveDocument.Bookmarks(“Page”).Start
HandlePage
Selection.GoToNext What:=wdGoToPage
If ActiveDocument.Bookmarks(“Page”).Start = lngStart Then
Exit Do
Else
lngStart = ActiveDocument.Bookmarks(“Page”).Start
End If
Loop
End Sub
Hans,
I didn’t know you did Word too! Good to hear from you. Thanks, your code works. I didn’t give you the whole story because I was hoping I could expand upon the loop idea and do the rest of the work myself, but alas, it’s a little too much. What’s really going on is this: I need to delete the first 13 lines on every page, then delete every 6th line 6 times.
I understand some of your logic: You are selecting the entire document so that you can know when you reach (“EndOf Sel”) and I think that is how the lngEnd is defined and I think lngLine is your counter. What do I need to paste and modify to include the 13 deletions along with the 6th line deletion?
Thanks.
Try this. It may not be the most efficient or elegant code possible.
Sub DeleteEverySixthLine()
Dim lngLine As Long
Dim lngEnd As Long
Selection.HomeKey Unit:=wdStory
Selection.EndKey Unit:=wdLine
lngEnd = ActiveDocument.Bookmarks(“EndOfSel”).End
Do
Selection.MoveDown Unit:=wdLine, Count:=1
Selection.EndKey Unit:=wdLine
If ActiveDocument.Bookmarks(“EndOfSel”).End = lngEnd Then
Exit Do
Else
lngLine = lngLine + 1
lngEnd = ActiveDocument.Bookmarks(“EndOfSel”).End
End If
If lngLine Mod 5 = 0 Then
Selection.HomeKey Unit:=wdLine
Selection.MoveDown Unit:=wdLine, Extend:=wdExtend
Selection.Delete
End If
Loop
End Sub
Donations from Plus members keep this site going. You can identify the people who support AskWoody by the Plus badge on their avatars.
AskWoody Plus members not only get access to all of the contents of this site -- including Susan Bradley's frequently updated Patch Watch listing -- they also receive weekly AskWoody Plus Newsletters (formerly Windows Secrets Newsletter) and AskWoody Plus Alerts, emails when there are important breaking developments.
Welcome to our unique respite from the madness.
It's easy to post questions about Windows 11, Windows 10, Win8.1, Win7, Surface, Office, or browse through our Forums. Post anonymously or register for greater privileges. Keep it civil, please: Decorous Lounge rules strictly enforced. Questions? Contact Customer Support.
Want to Advertise in the free newsletter? How about a gift subscription in honor of a birthday? Send an email to sb@askwoody.com to ask how.
Mastodon profile for DefConPatch
Mastodon profile for AskWoody
Home • About • FAQ • Posts & Privacy • Forums • My Account
Register • Free Newsletter • Plus Membership • Gift Certificates • MS-DEFCON Alerts
Copyright ©2004-2025 by AskWoody Tech LLC. All Rights Reserved.
Notifications