IfPlatform (Macro_comments_begin_here)

MakeSubDocs.wcm (v1.09) - Revised: November 16, 2012

    © 2004-2012 by Barry MacDonnell. All Rights Reserved.
    More free macros at http://wptoolbox.com
    Thanks to Bill Pickens in Florida for the idea behind this macro.


Purpose

A WordPerfect 9+ macro that inserts all files of a given file type (usually, WPD files) that are found in a specified directory/folder as subdocuments inside the current (master) document. [For more on master and subdocuments, see WordPerfect's Help (F1 key, Index).]

Notes and tips

        You should first ensure that the files you want to include as subdocuments are all in the same folder on your disk. This macro will process ALL files found in that folder with the specified filename extension.

You may want to play this macro while inside a new, empty document first until you see how it works.

You may want to modify the default values displayed on the macro's menu. You can change them in the redlined User Modification Area below.

The first time you play the macro or edit it, you might get a warning message about the SortArray command being obsolete. However, this command seems to work just fine. Just press "Continue Compilation" if you get this warning message.

    (Warnings about obsolete commands were implemented by Corel in WP9/sp4. But even though many commands have been named 'obsolete' by Corel since very early WP versions _ probably with a view toward consistency and conservation of code overhead _ most still work, and probably will work in versions to come.)

The order of files in the source directory/folder may be different than expected due to the way Windows stores files. Hence, you have a choice of "ascending" or "descending" order on the menu. Try each to see which works best for your particular setup, and set the default menu choice below. (If you want more technical information, see the comment at the end of this macro about FileFind, SortArray, etc.)

Programmers: If you want to use the FileFind() code in this macro to process files in some other way than is done here (say, to convert them, rename them, etc.), see the comments following the end of the macro code.

Version history:
V1.01 adds more information about the FileFind() command in a large WP Comment at the end of the macro code. To read it, edit the comment and scroll down as needed.
V1.02 changed the last message to include the number of words in the master document.
V1.03 adds a menu to allow selecting the folder that contains the files to process.
V1.04 uses a different routine (with SortArray) to insert the files. Several other code changes and error-trapping routines. Added the option to add a page break between inserted files, and a Please Wait message.
V1.04.01 - Made a minor change to the menu and code to process all filenames (*.*) in a folder.
v1.05 - Added word count report for each subdocument.


v1.06 - Made minor correction to menu choice (create report). Minor code cleanup.
v1.07 - Deleted VersionInfo command.
v1.08 - (Jan 2008) Minor fix to 'Please Wait' routine for Vista compatibility.
v1.09 - (Nov 2012) Minor changes to menu and macro comments.

(Macro_comments_end_here) EndIfPlatform


// - - - Macro code begins here - - -
// Note: if you have two different language versions of WordPerfect on your computer, you will need to add a semicolon and "EN" (or whatever language code you require) to the end of the parameters in the Application() command.For example:Application (WordPerfect; "WordPerfect"; Default!; "EN")[Note: If this macro runs under WP7 or earlier, users should change "EN" to "US" (or other code) in the Application() command.]
Application (WordPerfect; "WordPerfect"; Default!)    

// - - - User Modification Area - - -

//

MENU DEFAULTS CAN BE SET HERE:

// Change the drive letter, folder name(s), and filename type to the appropriate values in the next two commands, then Save & Compile the macro. For example, using "<any>" instead of *.wpd tells the macro to process all files in the folder. Using m*.doc would process all .DOC files in the folder that begin with the letter "M". [Be sure to retain the beginning and ending quote marks on the right side of the command.]:

//    vDirectory:="C:\My Documents\Temp"

// Set the filename extension (file type) of the files you want to process:

    vFileType:=".WPD"    // <= Note the period and filename extension (for all file types, use "<any>")

// Create report of total number of words in all subdocuments? (Requires expanding all subdocuments) - ONLY ONE of the next three variables can be set to "1" - the others must be set to zero:

    vNoCount:=1        // Don't display a count or create a report? 1=Yes; 0=No
    vCountWords:=0    // Display a word count? 1=Yes; 0=No
    vWCReport:=0        // Display a word cound and create a separate word count report? 1=Yes; 0=No

// Specify the sort order for iinserting the files - ONLY ONE of the next two variables can be set to "1" - the other must be set to zero:

    // Note: Alphabetical sorts may be reversed on some systems, depending on how the files were created in (or copied into) the Windows folder. Try both sort types and then set your preferred default.

    vAscending:=1
    vDescending:=0

// Insert a hard page break after each subdocument to separate them?

    vPageBreak:=1    // 1=Yes; 0=No

// - - - End of User Modification Area - - -

// Display messages if needed -


If(NOT ?DocBlank)
    MessageBox(vAns;"Current Document is NOT Blank";"This macro will insert files into the current document."+NToC(0F90Ah)+NToC(0F90Ah)+"Continue?";IconInformation! | OKCancel!)
    If(vAns=2) Quit Endif
EndIf
If(?Substructure or ?GraphicSelected)    // If inside a header, footnote, text box, etc.
    MessageBox(vAns;"Not At Main Edit Screen";"This macro can be started only from the main editing screen."+NToC(0F90Ah)+"Exit from any header, footer, footnote, text box, graphic, WP comment, etc., and play the macro again.";IconStop!)
    If(vAns=2) Quit Endif Quit
EndIf

// If the macro encounters an error, exit from the macro -
OnError(End@)
OnCancel(End@)

// Set some initial conditions -
vCount:=0 vWordCount:=0
MacroStatusPrompt(Off!)

// - - - Display menu here - - -
vBoldOn:=NToC(65048) vBoldOff:=NToC(65049)
vRedOn:=NToC(65044) vRedOff:=NToC(65045)
vDialogHeading:="" // (used in dialog's first static text box)
DialogShow("menu"; "WordPerfect")        // ("menu" was created with the Dialog Editor)
vAns:=MacroDialogResult    // Store the result of the user entry (OK, Cancel, etc.)
If(vAns=2) Go(End@) Endif    // If "Cancel", exit
// - - - End of menu area - - -

// Optionally create a separate word dount report -
If(vWCreport=1 and ?NumberOpenDocuments>7)    // (v1.05)
    MessageBox(;"Too Many Open Documents";"This macro requires at least TWO available open documents."+HRt+"Close one or more open documents and play the macro again.";IconStop!)
    Quit
EndIf

// Remove any backslash inadvertantly entered in User Modification Area
vDirectory:=StrTrim(vDirectory;;TrimRight!;"\")    // (v1.03)

// Remove any asterisk from the front of the filename extension string -
vFileType:=StrTrim(vFileType;;TrimLeft!;"*")    // (v1.04.01)
If(ToLower(vFileType) = "<any>")    // (v1.04.01)
    vFileType:=".*"
Endif

// Store the location and file type
vFiles:=vDirectory+"\*"+vFileType    // (v1.03)

// Store the first file in the folder that matches the vFiles:= specification in the variable, vCurrentFile -
vCurrentFile := FileFind (Filename: vFiles; Context:1)


// Process the folder - // (v1.04)
If(vCurrentFile !="")    // If there is at least one file matching the specification (i.e., not "empty") -

    Call(WaitMsg@)    // Display a Please Wait message

    // Assume that there won't be more than 1000 files (thanks to J. Dan Broadhead for these snippets) -
    Declare f[1000]

     // Get the list of files -
    i = 1
    f[i] = FileFind (vFiles)
    While (f[i] != "")
        i = i + 1
        If (i > 1000)
            Break
        Endif
        f[i] = FileFind ()
    Endwhile

     // Sort the list f[] -
    If (i > 1)
        // Note: SortArray is undocumented and "obsolete" but seems to work fine. Just continue compiling if you get a warning message -
        If(vAscending=1)
            vSortOrder:=0
        Endif
        If(vDescending=1)
            vSortOrder:=1
        Endif
        f[] = SortArray (f[1..i-1]; vSortOrder; QuickSort!)
    Endif

     // Now insert all the files -
    Fornext (j; 1; i-1; 1)
            SubdocInclude (f[j])
            If(vPageBreak=1)    // If menu option was enabled -
                HardPageBreak
            Endif
            // Increment the counter -
            vCount:=vCount+1
            MacroStatusPrompt(On!; "Processing file # "+vCount)
    Endfor

Else
    // Display an error message if no files found in the folder that match the specification -
    MessageBox(;"Error";"The macro couldn't find a file matching the specification -" + NToC(0F90Ah) + NToC(0F90Ah) + "^0" + NToC(0F90Ah) + NToC(0F90Ah) + "Check your system to make sure these files exist in the drive and folder you selected."; IconWarning! | HasParameters! ;vFiles)
    Quit
Endif

// Optionally expand the master document -
If(vCountWords=1 or vWCReport=1)
    MacroStatusPrompt(On!; "Expanding the "+vCount+" files in this master document...")
    MasterDocExpand ()    // (v1.02) Expand to allow counting words for Messagebox
    vWordCount:=DocumentInfo(Words!)    // (v1.02)
Endif

If(vWCReport=1)    // (v1.05)

    vCurrentDoc:=?DocNumber    // Store the current document's number
    pResetFindReplace ()    // Reset search parameters
    PosDocVeryTop

    FileNew    // Open a 'report' file
    vReportDoc:=?DocNumber
    FontSize(10p)

    AttributeAppearanceOn (Bold!)
    Type("WORD COUNT REPORT")
    AttributeAppearanceOff (Bold!)
    HardReturn
    HardReturn

    FileNew    // Open a new, temp file
    vTempDoc:=?DocNumber

    // Now insert all the files one at a time and do a count -
    Fornext (j; 1; i-1; 1)
        SubdocInclude (f[j])    // Include subdoc in temp file
        MasterDocExpand ()    // Expand to allow counting words
        vWordCountSubDoc:=DocumentInfo(Words!)    // Get the word count
        SelectAll
        SelectDelete
        SwitchDoc(vReportDoc)    // Switch to the report file
        PosDocBottom
        HardReturn
        Type("File: ")
        Type(f[j])
        HardReturn
        Tab
        Type("WordCount: ")
        FlushRight
        Type(vWordCountSubDoc)
        HardReturn
        SwitchDoc(vTempDoc)
    Endfor

    SwitchDoc(vReportDoc)
    PosDocBottom
    HardReturn
    HardReturn


    Type("TOTAL: ")
    FlushRight
    Type(vWordCount)

    SwitchDoc(vTempDoc)
    CloseNoSave

    SwitchDoc(vReportDoc)
    PosDocTop

        Display(On!)
        Messagebox(vAns;"Report Complete"; "You can view, print, and/or save this temporary report document after the macro finishes." +NToC(0F90Ah)+NToC(0F90Ah)+ "Do you want to return to the Master document now?" +NToC(0F90Ah)+ "('Yes' = Retain this report, return to Master; 'No' = Stay in this report document, retain Master)" ; IconQuestion! | YesNo!)
        If(vAns=2 or vAns=7) Go(End@) Endif    // If 'No' or 'Cancel'

    SwitchDoc(vCurrentDoc)
    PosDocTop

Endif

// Prepare to exit -
MacroStatusPrompt(Off!)
Call(KillWaitMsg@)        // Remove the Please Wait message

// Exit -
Label(End@)
Display(On!)    // Allows viewing the macro results while the next message box is still onscreen
pResetFindReplace ()    // Reset search parameters
If(vCount>0)    // If at least one file was processed, display a message -
    If(vCountWords=1)
        MessageBox(;"Done"; vCount + " files were processed with a total of " + vWordCount + " words." +NToC(0F90Ah)+NToC(0F90Ah)+ "You can now condense this Master document or simply abandon it.")
    Endif
    If(vNoCount=1 or vWCReport=1)
        MessageBox(;"Done"; vCount + " files were included as subdocuments in the Master document.")
    Endif
Endif
Quit

// - - - Process other routines here - - -

Label(WaitMsg@)    // This displays a Please Wait message -
DialogDefine(101;50;50;100;80;256+16+8+2;"")
DialogAddText(101;"T1";10;10;80;12;4;"... Working ...")
DialogAddText(101;"T2";10;25;80;12;4;"... please wait ...")
DialogAddText(101;"T3";10;40;80;12;4;"... (see status bar) ...")
DialogShow(101;1;Msg)
Return


Label(Msg)
If(Msg[3] = "CancelBttn")
Assert(CancelCondition!)
EndIf
Return
Label(KillWaitMsg@)    // This cancels the message
DialogDestroy(101)
Return

Procedure pResetFindReplace ()
SearchString ("")
ReplaceString ("")
// Only one of these 4 Match commands can be active at any one time
// MatchPositionAfter ()
// MatchExtendSelection()
// MatchPositionBefore()
MatchSelection()
SearchFindWholeWordsOnly (No!)
MatchWithAttributes (No!)
ReplaceWithAttributes (No!)
SearchCaseSensitive (No!)
ReplaceWithCase (No!)
MatchWithFont (No!)
ReplaceWithFont (No!)
MatchWithFontSize (No!)
ReplaceWithFontSize (No!)
SearchInSelection (No!)
SearchWordForms (No!)
SearchWrap (No!)
MatchLimit (No!)
EndProcedure

// - - - Macro code ends here - - -