MS Office Forum / Word / Programming / November 2006
how does a macro know it's reached EOF?
|
|
Thread rating:  |
Allen_N - 06 Nov 2006 00:31 GMT I'm trying to use Word for same elementary text processing. I just want to remove 6 lines from each page (to get rid of page headers in a big report). My macro works, but it doesn't know when to stop. The macro body is as follows:
Do Selection.MoveDown Unit:=wdLine, Count:=6, Extend:=wdExtend Selection.Delete Unit:=wdCharacter, Count:=1 Selection.MoveDown Unit:=wdLine, Count:=48 Loop Until Selection.Text = "" (N.B. I set orientation to Landscape and fiddled with margins until all pages began with the header.)
Several people have asked similar questioins, but everybody that answers seems to have better methods; no one seems inclined to answer the question: how does the macro know when the selection has become the end of the document?
Jay Freedman - 06 Nov 2006 01:02 GMT Most people who answer questions like this realize that forcing a macro to behave like it's pressing keys (the "automated typist" scenario) is the least efficient and most error-prone way of handling jobs like this. That's why the answer usually involves a different and, yes, better method.
In this case, the better method would probably be a wildcard search & replace with a search expression that's crafted to find only the page headers. Not only would it be easier to program, but it would run about a hundred times faster, and it wouldn't risk deleting the wrong lines just because one page is a little different from the others.
But... If you insist on making Word behave like a refugee from the 1980s word-processor scrap heap, you can do it.
Declare a numeric variable and assign to it the return value of the final MoveDown call. The return value of the call is the number of lines the Selection actually moved. End the loop when that return value is less than the requested number of lines, because the Selection can't move down past the end of the document:
Dim actualMove As Long Do Selection.MoveDown Unit:=wdLine, Count:=6, Extend:=wdExtend Selection.Delete Unit:=wdCharacter, Count:=1 actualMove = Selection.MoveDown (Unit:=wdLine, Count:=48) Loop Until actualMove < 48
If you're unlucky, this method might still err on the last page if it contains just the wrong number of lines, so an On Error trap is recommended.
-- Regards, Jay Freedman Microsoft Word MVP FAQ: http://word.mvps.org Email cannot be acknowledged; please post all follow-ups to the newsgroup so all may benefit.
>I'm trying to use Word for same elementary text processing. I just want to >remove 6 lines from each page (to get rid of page headers in a big report). [quoted text clipped - 13 lines] >seems to have better methods; no one seems inclined to answer the question: >how does the macro know when the selection has become the end of the document? Jezebel - 06 Nov 2006 01:05 GMT Probably no-one wanted to volunteer because it's just such a silly way to process a document, for any number of reasons. But if you must --
Selection.start = Activedocument.range.end - 1
> I'm trying to use Word for same elementary text processing. I just want to > remove 6 lines from each page (to get rid of page headers in a big [quoted text clipped - 16 lines] > how does the macro know when the selection has become the end of the > document? Allen_N - 06 Nov 2006 03:17 GMT Thanks for the advice.
Silly? No sillier than fixed-format, mainframe-generated, ASCII reports, surely. I though I was being clever by using Word to process such a text file rather than writing a VB program to do so.
If the source data had been a DOC file I would certainly have been inclined to think in terms of the Word object model. Speaking for myself, however, BFI sequential processing is easier to implement when I am unfamiliar with object model and disinclined to spend hours wading through Help screens.
Cheers!
> Probably no-one wanted to volunteer because it's just such a silly way to > process a document, for any number of reasons. But if you must -- [quoted text clipped - 21 lines] > > how does the macro know when the selection has become the end of the > > document? Jezebel - 06 Nov 2006 04:18 GMT There are much easier ways to process a text file with VBA than that. For one:
1. Read the file directly into an array --
Dim pLines() as string Dim pFileNum as long Dim pIndex as long
pFileNum = FREEFILE Open "c:\.....\myfile.txt" for input as pFileNum pLines = split(input(LOF(#pFileNum,pFileNum)), vbCr) Close pFileNum
2. Process the lines -- For pIndex = lbound(pLines) to ubound(plines) ... do whatever with pLines(pIndex) Next
> Thanks for the advice. > [quoted text clipped - 40 lines] >> > how does the macro know when the selection has become the end of the >> > document? Allen_N - 06 Nov 2006 05:22 GMT Cool! I'll have to have a go at that.
-- Allen
> There are much easier ways to process a text file with VBA than that. For > one: [quoted text clipped - 59 lines] > >> > how does the macro know when the selection has become the end of the > >> > document? Greg Maxey - 06 Nov 2006 14:47 GMT Jezebel,
I tried running your example on a simple text file and I get a compile error on the "#" in this line:
pLines = split(input(LOF(#pFileNum,pFileNum)), vbCr) 'Compile error on "#"
I haven't messed with this sort of code very much but found that I could get a msgbox to display the text of the file using:
MsgBox Input(LOF(pFileNum), pFileNum) 'Returns the text. No error
However is I declare a string and use: pStr = Input(LOF(pFileNum), pFileNum) 'Run-Time error 62 "Input past end of file"
I get a runtime error 62 "Input past end of file"
Can you explain what I am doing wrong? Can you explain why the msgbox text can be created but not a string?
Thanks.
> There are much easier ways to process a text file with VBA than that. For > one: [quoted text clipped - 59 lines] > >> > how does the macro know when the selection has become the end of the > >> > document? Greg Maxey - 06 Nov 2006 15:47 GMT I got this to work:
Sub Test() Dim pLines() As String Dim pFileNum As Long Dim pIndex As Long pFileNum = FreeFile Open "c:\Txt file.txt" For Input As pFileNum pLines = Split(Input(LOF(pFileNum), pFileNum), vbCr) Close pFileNum For pIndex = LBound(pLines) To UBound(pLines) - 1 MsgBox pLines(pIndex) Next End Sub
> There are much easier ways to process a text file with VBA than that. For > one: [quoted text clipped - 59 lines] > >> > how does the macro know when the selection has become the end of the > >> > document? Jezebel - 06 Nov 2006 20:40 GMT sorry about the typos.
>I got this to work: > [quoted text clipped - 81 lines] >> >> > how does the macro know when the selection has become the end of the >> >> > document? Lüko Willms - 06 Nov 2006 10:59 GMT Am Mon, 6 Nov 2006 03:17:01 UTC, schrieb Allen N <AllenN@discussions.microsoft.com> auf microsoft.public.word.vba.general :
> Silly? No sillier than fixed-format, mainframe-generated, ASCII reports, > surely. I though I was being clever by using Word to process such a text file > rather than writing a VB program to do so. Alternatively to reading all the document into an array (one entry per line), you could avoid using MS-Word altogether and write a script reading the mainframe outpout as a text stream object, and copying it to a new text stream; scanning each line for the characteristics of the page break and headers, and dropping those lines from the copy process, or skipping the fixed number of lines from the source file with the SkipLine method.
something like this (untested and uncompiled) script in VBScript:
Dim fso, inFile, outFile, myLine const nameInFile = "C:\tmp\mainframe_original.txt") ' example const nameOutFile = "C:\tmp\mainframe_edited.txt") ' another example const pageMarker = "String which marks the begin of the m/f page break"
set fso = CreateObject("Scripting.FileSystemObject") set inFile = fso.OpenTextFile(nameInfile, ForReading, TriStateFalse) ' false : read as ASCII set outFile = fso.CreateTextFile(nameOutFile, ForWriting, TriStateFalse) myLine = inFile.ReadLine Do While NOT inFile.AtEndOfStream IF InStr(myLine, pageMarker) = 0 ' alternatively use the RegExp object outFile.WriteLine(myLine) Else For i = 1 to 5 inFile.SkipLine Next End If myLine = inFile.ReadLine Loop inFile.Close outFile.Close
'############### end of script ###############
One could make it into a SUB and pass the filenames as parameters, or better pass them on the commandline, and processing the commandline parameters as the WshArguments object.
Some error handling should also be added for missing parameters, non-existing files, writing or reading errors, etc.
Yours, L.W.
Allen_N - 09 Nov 2006 22:31 GMT Thanks, Lüko.
I've never used VBScript, but I was originally going to do something like that with VB4. I thought I'd try Word in case I later wanted to generalise the macro for wider application.
conradrg - 13 Nov 2006 20:58 GMT Here's the code you should use, and I tested it to see if it works. simply added the end of document statement to what you previousl wrote.
Do Selection.MoveDown Unit:=wdLine, Count:=6, Extend:=wdExtend Selection.Delete Unit:=wdCharacter, Count:=1 Selection.MoveDown Unit:=wdLine, Count:=48 Loop Until Until ActiveDocument.Range.End - 1
OR
Do Until Until ActiveDocument.Range.End - 1 Selection.MoveDown Unit:=wdLine, Count:=6, Extend:=wdExtend Selection.Delete Unit:=wdCharacter, Count:=1 Selection.MoveDown Unit:=wdLine, Count:=48 Loop
Conrad R. G
-- conradr
Posted from - http://www.officehelp.i
|
|
|