To the Original Word Merge Code. Add these three lines to the top by the other variables
Var vLabel as String
Var vLabelNumber as Int
Var vLabelLoop as Int
Then on line 145(Which should be after subroutine GET_DOCS ends and before Subroutine PrintCurrentRecordOnly())
Function AddBlankRecords() as String
Var vRecs as String
vLabelLoop = 1
vRecs = ""
While vLabelLoop <= vLabelNumber - 1
{
vRecs = vRecs + @Text(@CountStringArray(vNames), "^")
vRecs = vRecs + @Newline()
vLabelLoop = vLabelLoop + 1
}
Return(vRecs)
End Function
Then in Subroutine PrintCurrentRecordOnly() on line 190 put the following code.
vData = AddBlankRecords() + vData
Then in Subroutine PrintAllRetrievedRecords() on line 226 put the following code.
vData = AddBlankRecords()
FileWrite(vFileHandle, vData)
vData = ""
Then on line 304 add the following lines of code
vLabel = @PopupMenu("1. Label #1;2. Label #2;3. Label #3;4. Label #4;5. Label #5;6. Label #6", "What label would you like to start on?")
If vLabel = "" Then
{
vLabelNumber = 1
}
Else
{
vLabelNumber = @ToNumber(@Left(vLabel, 1))
}
So the entire programming should be
// WordMerge 2.44 November 2008
// Written for use with MS Word(tm) Word Processor
// The following 3 variables are user-modifiable ..
var vDataPath as String = "Docs\MergeData.txt" // Merge data source file for Word (output file)
// THIS FILE GETS CREATED AUTOMATICALLY
// can optionally be a full path such as
// "C:\Sesame2\Docs\MergeData.txt"
var vDocType as string = ".DOCx;.DOC" // document types (file extensions)
// For Office 2007, added DOCx to document types
var vStartPath as string = "docs" // folder to start in, relative to Sesame's Start In folder,
// normally c:\sesame2
// Can optionally be a full path such as "C:\Docs\MergeDocs"
// ************** Variables for Program (Do Not Modify) ******************
var vFileHandle as Int // For writing merge data source file for Word
var vHeader as String // Data source file header line
var vData as String // Data source file data line
var n as Int // General purpose counter var
var vSelectedDoc as String // The selected Word doc
var vOneOrAll as String // Include record(s) option
var vNames as string // Form LE names of LEs with editable data (not static text, etc)
var vStartingRec as INT // Current record number
var vProceed as INT // Used to determine whether to run Word
var vVal as string // Used to hold One data element
var vName as string // name of an LE on the form for merge
var nn as Int // general purpose counter
var vLEs as String // All LE's on current form
Var vLabel as String
Var vLabelNumber as Int
Var vLabelLoop as Int
// The following are used in the GetDoc() subroutine that selects the doc to merge with
var vPath as String // Currrent docs path (changes as user navigates)
var vFileTypes as String // File types to find, such as .doc and .pdf
var vExtensions as String // Permitted file extensions
var vList as String // List of folders & files in vPath
var vFolderFlag as Int // Tells program that user selected a subfolder
var vFolders as String // Subfolders in selected folder
var vDocs as String // Available doc files of all desired types in selected folder
var vItem as String // Item selected by user
// vPath and vItem are assigned to vSelectedDoc for the actual Merge
// ******************************************************************
SUBROUTINE CheckData()
// This next line gets rid of embedded carriage returns in the data fields. Replaces with two spaces.
// This is necessary otherwise the merge will fail
vData = @Replace(vData, @Newline(), " ")
// This next line gets rid of double quotes in the data fields. Puts in 2 x single quotes.
// This is necessary otherwise the merge will fail ('cannot open source document')
vData = @Replace(vData, @Chr(34), @Chr(39) + @Chr(39) )
// This next line checks for an umlauted Y in data fields, resulting from mal-formed yes/no values from Q&A. Replaces with zero-length string.
vData = @Replace(vData, @Chr(255), "" )
END SUBROUTINE
// ******************************************************************
SUBROUTINE MergeFields() // to take all elements on the form, and generate a list of those that can contain data - not statics, not Command buttons, etc
var n as Int
var nn as Int
vLEs = @StringArrayElementList() // All LE's on current form
For n = 1 to @CountStringArray(vLEs)
vName = @AccessStringArray(vLEs, n)
SetThisElement(vName)
nn = @ElementType(ThisElement)
If nn > 999 and nn < 1009 // if in this range, element contains editable data
vNames = @AppendStringArray(vNames, vName) // add to the list of LEs to be exported for the Mailmerge
UnSetThisElement()
Next
END SUBROUTINE
// ******************************************************************
Subroutine GET_DOC()
var vTemp as String
var n as Int
vList = @LocalListDirectory(vPath)
// Isolate subfolders (items that have no "." in them)
vFolders = @SearchStringArray(vList, "/..\...")
vTemp = ""
// Add boldface and "+" sign to folder names
For n = 1 to @CountStringArray(vFolders)
vTemp = @AppendStringArray(vTemp, "@b" + "+" + @AccessStringArray(vFolders, n))
Next
vFolders = vTemp
vFileTypes = @Replace(vExtensions,".","...")
// Isolate document type filenames
vDocs = @SearchStringArray(vList, vFileTypes)
vDocs = @SortStringArray(vDocs, 0)
PopupSelectPosition(4, @XPos(ThisElement), @YPos(ThisElement))
If vFolderFlag = 1 // User selected a subfolder
{
vItem = @PopupChoiceList("@b[BACK]" + ";" + vFolders + ";" + vDocs,
"SELECT FOLDER or DOCUMENT")
vFolderFlag = 0
}
Else
{
vItem = @PopupChoiceList(vFolders + ";" + vDocs, "SELECT FOLDER or DOCUMENT")
}
If vItem = "@b[BACK]"
{
SetStringArraySeparator("\")
vPath = @TrimStringRight(@ReplaceStringArray(vPath, "",
@CountStringArray(vPath)), "\")
RestoreStringArraySeparator()
If @Instr(vPath, "\") > 0 And vPath <> vStartPath Then vFolderFlag = 1
GET_DOC()
}
Else If vItem <> ""
{
If @FindStringArray(vExtensions, @Right(vItem, 4)) = -1
{
vFolderFlag = 1
vPath = vPath + "\" + @Replace(vItem, "@b+", "")
GET_DOC()
}
// user selected a document file
}
End Subroutine
// ******************************************************************
Function AddBlankRecords() as String
Var vRecs as String
vLabelLoop = 1
vRecs = ""
While vLabelLoop <= vLabelNumber - 1
{
vRecs = vRecs + @Text(@CountStringArray(vNames), "^")
vRecs = vRecs + @Newline()
vLabelLoop = vLabelLoop + 1
}
Return(vRecs)
End Function
SUBROUTINE PrintCurrentRecordOnly()
var n as Int
For n = 1 to @CountStringArray(vNames)
vHeader = vHeader + @AccessStringArray(vNames,n) + "^"
vVal = @(@AccessStringArray(vNames,n)) // the one piece of data from an element
// Convert if money, number, date, time, bool, image
vName = @AccessStringArray(vNames, n)
If vVal <> ""
{
SetThisElement(vName)
vVal = @AsFormattedByLE(ThisElement, 0, vVal)
}
UnSetThisElement()
vData = vData + vVal + "^"
Next
CheckData() // Run subroutine to remove any of 3 non-permitted characters
vFileHandle = FileOpen(vDataPath)
IF vFileHandle <0 // IF FILE CANNOT BE OPENED
THEN
{
@MsgBox( " FILE CANNOT BE OPENED."," THIS IS PROBABLY BECAUSE A MERGE DOCUMENT ATTACHED TO IT IS ALREADY OPENED."," CLOSE THE MERGE DOCUMENT(S) AND TRY AGAIN.")
}
ELSE
{
FileSeek(vFileHandle, 0)
vData = AddBlankRecords() + vData
FileWriteLn(vFileHandle, vHeader + @NewLine() + vData)
FileClose(vFileHandle)
vProceed = 1
}
END SUBROUTINE
// ******************************************************************
SUBROUTINE PrintAllRetrievedRecords()
var n as Int
var i as Int
vStartingRec = @ResultSetCurrentPosition()
IF @Askuser("Merge Print " + vSelectedDoc + " for these " + @ResultSetTotal() + " retrieved records?",
"( If not, click on NO to cancel this task, press F7 for a new search,"," and retrieve the records you DO want to print. )")
THEN
{
For n = 1 to @CountStringArray(vNames)
vHeader = vHeader+ @AccessStringArray(vNames,n) + "^"
Next
vFileHandle = fileOpen(vDataPath)
IF vFileHandle <0 // IF FILE CANNOT BE OPENED
THEN
{
@MsgBox( " FILE CANNOT BE OPENED."," THIS IS PROBABLY BECAUSE A MERGE DOCUMENT ATTACHED TO IT IS ALREADY OPENED."," CLOSE THE MERGE DOCUMENT(S) AND TRY AGAIN.")
}
ELSE
{
FileSeek(vFileHandle, 0)
FileWriteLn(vFileHandle, vHeader)
vData = AddBlankRecords()
FileWrite(vFileHandle, vData)
vData = ""
For n = 1 to @ResultSetTotal()
ResultSetCurrentPosition(n)
For i = 1 to @CountStringArray(vNames)
// Convert if money, number, date, time, bool, image
vName = @AccessStringArray(vNames, i)
vVal = @(@AccessStringArray(vNames,i))
If vVal <> ""
{
SetThisElement(vName)
vVal = @AsFormattedByLE(ThisElement, 0, vVal)
}
UnSetThisElement()
vData = vData + vVal + "^"
CheckData() // Run subroutine to remove any of 3 non-permitted characters
Next
FileWriteLn(vFileHandle, vData)
@Msg("Processed Record " + n + " of " + @ResultSetTotal())
vData = ""
Next
FileClose(vFileHandle)
vProceed = 1
// Rewind to record where it all started
ResultSetCurrentPosition(vStartingRec)
} // END CONDITIONAL FILE CANNOT BE OPENED
} // END CONDITIONAL DO YOU WANT TO PROCEED WITH THIS MERGE
END SUBROUTINE
// - - - - - - - E N D O F V A R I B L E D E C L A R A T I O N S - - - - - - - - - - - -
// BEGIN MAIN PROGRAM
FormCommit("")
// Jan 2008 - generate the list of LEs for export for merge via MergeFields() subroutine
MergeFields() // generates a stringarray list of all editable LEs on the form - Export all editable data for merge
// Use GetDoc subroutine for user to select the document
vExtensions = vDocType // set the extensions the GetDoc() subroutine looks for
vPath = vStartPath
GET_DOC()
// GetDoc ends up with vItem - make that the selected doc
vSelectedDoc = vPath + "\" + vItem
// Set position of picklist to nearly over the command button
PopupSelectPosition(4,@Xpos(ThisElement)+10,@Ypos(ThisElement))
IF @RT(vSelectedDoc, 1) <> "\" and vSelectedDoc <> "" Then
{
// Build which record(s) menu
vOneOrAll = @PopupMenu("THIS Record Only;ALL Retrieved Records", "SELECT RECORD(S) TO MERGE PRINT")
// Reset Popup position
PopupSelectPosition(0,99,99)
IF vSelectedDoc <> "" and vOneOrAll <> "" Then
{
// Delete existing data file. New one will be generated.
IF FileExists(vSelectedDoc) Then
{
FileDelete(vDataPath)
vLabel = @PopupMenu("1. Label #1;2. Label #2;3. Label #3;4. Label #4;5. Label #5;6. Label #6", "What label would you like to start on?")
If vLabel = "" Then
{
vLabelNumber = 1
}
Else
{
vLabelNumber = @ToNumber(@Left(vLabel, 1))
}
IF vOneOrAll = "THIS Record Only" Then
PrintCurrentRecordOnly()
Else
PrintAllRetrievedRecords()
IF vProceed = 1 THEN
{
n = @ASynchShell(vselectedDoc)
}
} // END CONDITIONAL SELECTED DOCUMENT EXISTS
ELSE
@Msgbox(vSelectedDoc + " doesn't exist.","","Aw shucks!")
} // END CONDITIONAL ONE OR ALL HAS BEEN SELECTED
} // END CONDITIONAL A DOCUMENT HAS BEEN SELECTED
-Ray