Normal Topic Label merge start at label number… (Read 1311 times)
tcgeo
Full Member
***
Offline



Posts: 278
Location: Traverse City, Michigan
Joined: May 13th, 2008
Label merge start at label number…
Dec 28th, 2009 at 7:06pm
Print Post Print Post  
I have a client that’ll be getting new computers and printers.  They’ve been printing 4” x 2 15/16” labels using a pin fed label printer. The new printer will be your basic single sheet printer. They will use Avery 5164 sheet labels which contain six labels each.  One of  the concerns I have is that when they go to print labels via the merge code from Sesame (which works great) they are sure to run into a situation where they will have leftover labels which means higher cost if the leftovers are not used.  So, I’ve created code that will allow the client to add blank records to their result set depending on which label they want to start on.  For example if they need to start on label number 4 on the sheet they click a command button that would give them a list to choose from and select #4.   After selection, the code would place the number of blank records required at the beginning of their result set so that when they run the merge the blanks “push” the first record that contains correct data into the label that they want to start with.  These blanks will have a “_” placed in one field so that they can be easily deleted after printing.

This whole deal works rather well and I’ve added to the merge code the portion that runs the deleting of the blanks so that the deleting of the blanks is automated rather than making the client push one more button.

After feeling pretty good about myself that I actually got it to work, I got to thinking that the code, especially the part that adds the number of blank records, seems to be rather cumbersome and that there may be a way to consolidate it, especially if this was to be used with a different type of label that would have 30 labels per sheet instead of 6.  So, I’m asking for a critiquing of my code for 1, and 2, whether or not there’s a better way that you know of to select the label to start printing on.

Thanks for any help or advice.

[code]//Add blank record Subroutine.  Adds a blank record and places a “_” into the IDno field.

Subroutine AddBlank()
var vRS as int
var viD as string
var vNav as Int

vid = idno

       vRS = @XResultSetSearch(@fn, "SRA", SEARCH_MODE_AND, SEARCH_SYNTAX_QA, "IDno=" + "NextShipDate=")
       If (vRS > -1)
       {
                 XResultSetCreateNewRecord(vRS)
                 XResultSetValue(vRS, "nextshipdate", nextshipdate)
                 XResultSetValue(vRS, "IDno", "_")

           XResultSetClose(vRS)
       }
End Subroutine




//Add the number of blank records wanted to beginning of retrieved records.

var success as Int
var vNav as Int
var vLabel as Int

     PopupSelectPosition(4, @XPos(Test) , @YPos(Test))
     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 = "1. Label #1" Then  //may remove this option
           {
           vNav = @SelectTreeItem("Search Menu!Search Commands!Retrieve New Results (F10)")
           }
           Else If vLabel = "2. Label #2"
           {
           AddBlank()
           success = @LoadSortSpec("AddBlankSort")
           vNav = @SelectTreeItem("Search Menu!Search Commands!Retrieve New Results (F10)")
           }      
           Else if vLabel = "3. Label #3"
           {
           AddBlank()
           AddBlank()
           success = @LoadSortSpec("AddBlankSort")
           vNav = @SelectTreeItem("Search Menu!Search Commands!Retrieve New Results (F10)")            
           }
           Else If vLabel = "4. Label #4"
           {
           AddBlank()
           AddBlank()
           AddBlank()
           success = @LoadSortSpec("AddBlankSort")
           vNav = @SelectTreeItem("Search Menu!Search Commands!Retrieve New Results (F10)")
           }      
           Else if vLabel = "5. Label #5"
           {
           AddBlank()
           AddBlank()
           AddBlank()
           AddBlank()
           success = @LoadSortSpec("AddBlankSort")
           vNav = @SelectTreeItem("Search Menu!Search Commands!Retrieve New Results (F10)")            
           }
           Else if vLabel = "6. Label #6"
           {
           AddBlank()
           AddBlank()
           AddBlank()
           AddBlank()
           AddBlank()
           success = @LoadSortSpec("AddBlankSort")
           vNav = @SelectTreeItem("Search Menu!Search Commands!Retrieve New Results (F10)")
           }


//Find all records that contain a “_” and deletes them.

var vRS as int
var vNav as Int
var vCount as Int
var vLoop as Int
var vidno as string


vNav = @SelectTreeItem("Search Update Menu!Search (F7)")


vidno = "_"

       vRS = @XResultSetSearch(@fn, "SRA", SEARCH_MODE_AND, SEARCH_SYNTAX_QA, "IDno=" + vidno) // + "NextShipDate=")
       If (vRS > -1)
       {
     vCount = @XResultSetTotal(vRS)
           If vCount > 0
           {
                 For vLoop = 1 To vCount
                                               
                       XResultSetDeleteRecord(vRS)
                 
                 Next
           }
           Else
           {
                 @MsgBox("No matching records.", "", "")
           }

           XResultSetClose(vRS)
                 
}

vNav = @SelectTreeItem("Search Update Menu!Search (F7)")
[/code]
  
Back to top
IP Logged
 
Ray the Reaper
Global Moderator
Members
Lantica Support
*****
Offline


The One & The Only

Posts: 2482
Joined: Aug 20th, 2003
Re: Label merge start at label number…
Reply #1 - Dec 29th, 2009 at 1:12pm
Print Post Print Post  
Hello,

If you are using the WordMerge code where you write the Export file in programming, there is no need to add extra records to the ResultSet and then delete them. Just write the appropriate number of blank records directly to the export file before the loop that gets your actual record data.

-Ray
  

Raymond Yoxall Consulting
ray.yoxall@gmail.com
ryoxall@lantica.com
Sesame Applications, Design and Support
Back to top
IP Logged
 
tcgeo
Full Member
***
Offline



Posts: 278
Location: Traverse City, Michigan
Joined: May 13th, 2008
Re: Label merge start at label number…
Reply #2 - Dec 29th, 2009 at 8:18pm
Print Post Print Post  
Thanks for the response Ray,

You said; “If you are using the WordMerge code where you write the Export file in programming”,  I’m not sure that I am.   I’m using the WordMerge 2.44 November 2008 found in the WordMergeCommand.txt file located in Sesame Docs.  Is this the one you are referring to?

I’ve scoured through the WordMerge code looking for a place to add a record without success.  I thought that two of the places that I should be doing this is with the SUBROUTINE PrintCurrentRecordOnly() and SUBROUTINE PrintAllRetrievedRecords() but I may be way off base.

Any help in getting me on the right track would be appreciated.

Thanks
  
Back to top
IP Logged
 
Ray the Reaper
Global Moderator
Members
Lantica Support
*****
Offline


The One & The Only

Posts: 2482
Joined: Aug 20th, 2003
Re: Label merge start at label number…
Reply #3 - Dec 30th, 2009 at 2:26pm
Print Post Print Post  
To the Original Word Merge Code. Add these three lines to the top by the other variables

Code
Select All
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())

Code
Select All
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.

Code
Select All
	vData = AddBlankRecords() + vData 



Then in Subroutine PrintAllRetrievedRecords() on line 226 put the following code.

Code
Select All
		vData = AddBlankRecords()
		FileWrite(vFileHandle, vData)
		vData = "" 



Then on line 304 add the following lines of code
Code
Select All
			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
Code
Select All
// 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
  

Raymond Yoxall Consulting
ray.yoxall@gmail.com
ryoxall@lantica.com
Sesame Applications, Design and Support
Back to top
IP Logged
 
tcgeo
Full Member
***
Offline



Posts: 278
Location: Traverse City, Michigan
Joined: May 13th, 2008
Re: Label merge start at label number…
Reply #4 - Dec 30th, 2009 at 2:57pm
Print Post Print Post  
Ray, WOW,  I don't even know what to say accept, that's a thing of beauty!

Thank you very much!  I'm pretty sure I would never have solved this on my own, but I will definitely study this for future endeavors.

Where do I send you a case of Holiday Cheer?

Brandon
  
Back to top
IP Logged
 
tcgeo
Full Member
***
Offline



Posts: 278
Location: Traverse City, Michigan
Joined: May 13th, 2008
Re: Label merge start at label number…
Reply #5 - Dec 30th, 2009 at 4:49pm
Print Post Print Post  
So,

From BEGIN MAIN PROGRAM

vLabelNumber is where the selection of which label to start is held.

Then when PrintCurrentRecordOnly() or PrintAllRetrievedRecords() is called they look for

Function AddBlankRecords().  

Then in AddBlankRecords(),  vRecs = vRecs + @Text(@CountStringArray(vNames), "^")  is used to create the blank record that looks like this;  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^, the data separators.

Then, vRecs = vRecs + @Newline() adds as many blank records as defined by;   While vLabelLoop <= vLabelNumber – 1

Then the SUBROUTINE PrintCurrentRecordOnly() or PrintAllRetrievedRecords() looks for Return(vRecs) from the Function AddBlankRecords()  and inserts those blank records ahead of the actual records.

am I close?
  
Back to top
IP Logged
 
Ray the Reaper
Global Moderator
Members
Lantica Support
*****
Offline


The One & The Only

Posts: 2482
Joined: Aug 20th, 2003
Re: Label merge start at label number…
Reply #6 - Dec 30th, 2009 at 4:50pm
Print Post Print Post  
If you have any questions about how it works in the future, just send me an email at support@lantica.com and I'll be happy to help you figure it out.

Happy Holidays,
Ray
  

Raymond Yoxall Consulting
ray.yoxall@gmail.com
ryoxall@lantica.com
Sesame Applications, Design and Support
Back to top
IP Logged
 
Ray the Reaper
Global Moderator
Members
Lantica Support
*****
Offline


The One & The Only

Posts: 2482
Joined: Aug 20th, 2003
Re: Label merge start at label number…
Reply #7 - Dec 30th, 2009 at 5:03pm
Print Post Print Post  
tcgeo wrote on Dec 30th, 2009 at 4:49pm:
So,

From BEGIN MAIN PROGRAM

vLabelNumber is where the selection of which label to start is held.


Yup

Quote:
Then when PrintCurrentRecordOnly() or PrintAllRetrievedRecords() is called they look for

Function AddBlankRecords().


Yes

Quote:
Then in AddBlankRecords(),  vRecs = vRecs + @Text(@CountStringArray(vNames), "^")  is used to create the blank record that looks like this;  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^, the data separators.


Yup. One separator for each field of data you are exporting.

Quote:
Then, vRecs = vRecs + @Newline() adds as many blank records as defined by;   While vLabelLoop <= vLabelNumber – 1


It's the combination of the lines vRecs = vRecs + @Text(@CountStringArray(vNames), "^") and vRecs = vRecs + @Newline() that add the blank records. Yes it is controlled by the While loop.

Quote:
Then the SUBROUTINE PrintCurrentRecordOnly() or PrintAllRetrievedRecords() looks for Return(vRecs) from the Function AddBlankRecords()  and inserts those blank records ahead of the actual records.


Yes.

Quote:
am I close?

You've got it.

-Ray
  

Raymond Yoxall Consulting
ray.yoxall@gmail.com
ryoxall@lantica.com
Sesame Applications, Design and Support
Back to top
IP Logged
 
tcgeo
Full Member
***
Offline



Posts: 278
Location: Traverse City, Michigan
Joined: May 13th, 2008
Re: Label merge start at label number…
Reply #8 - Dec 30th, 2009 at 5:20pm
Print Post Print Post  
Thanks again Ray,

And Happy Holidays to you,

Brandon
  
Back to top
IP Logged