Onepax Business Consulting


These days it is somewhat of a rarity working with a client who runs the Progress 4GL (AKA OpenEdge) version of the product. The majority of people seem to use the SQL based version of SyteLine because that is where all of the new features are added plus Microsoft SQL as a database engine is blazingly fast if properly cared for.  Interestingly enough, the biggest reason I see the older versions still out there are because of internal resources who know this language construct very well and would find it a burden to both learn the new language and rewrite everything all over again in it.  There is no definitive right or wrong stance on this however it’s worth pointing out that those who are entitled to software upgrades and don’t take advantage of it will not be able to take advantage of all the new features that keep getting added to the software.

I started at the very end of the 90’s performing software deployments, upgrades, migrations and everything else years before the SQL version came out so I had to familiarize myself with how to get this software to work within may disparate environments such as Linux/AIX/HPUX/SCO/BSD/Windows and one of the most frequent challenges every customer faced was getting various printers to work for a variety of reports.

In the early days, printing on impact printers were the norm and there were really two options: continuous feed perforated paper for 80 column and green bar for wide column.  Fonts were for the most part fixed spaced and there really wasn’t a need to mess with font size because the paper was all designed for the default 10/12 point spacing.  The 4GL versions of SyteLine consequently did not need to use the printing subsystem so the best choice was to make printing OS agnostic.

Because printing was so simple, Infor chose to use the PCL language construct to allow printing straight from the software to the device and then provided a way to embed various changes via a starting string and ending string.  While not all printers are able to communicate via PCL the majority of business printers out there today still do making this technology still viable.  With the cost of continuous feed paper and green bar increasing in price and the speed of modern laser printers getting faster with each year it makes sense for those who have not yet retired some of their impact printers to consider it as an option.

SyteLine start strings for PCL will always start via the escape code “~E” and will be followed by a sequence of alphanumeric code to send commands.   There are many references online for PCL control codes but my goal is to go over just a few basic ones for those who are not familiar and then people reading this can  add their own additional codes to suit their environment.



~E(s16H SIXTEEN CHARACTERS PER INCH (replace 16 with 10,12,14,20 to make smaller or larger)

~E&a0L SET LEFT MARGIN 0 COLUMNS (increase from 0 to move margin right)

~E&l1E SET TOP MARGIN 1 LINE (increase from 1 to move margin down)

~E&l66P SET PAGE LENGTH TO 66 LINES PER PAGE (increase up or down)

~E&l1X PRINT 1 COPY (increase the value of 1 to desired number)

~E&l3A CHANGE PAPER SIZE TO LEGAL (2 for letter and 1 for executive)

~E&l8D PRINT 8 LINES PER INCH (increase up or down)

~EE RESET SETTINGS BACK TO DEFAULT (typically this is the SyteLine ending string)

Syteline does not provide unlimited room for adding codes via the start string however there is a way to shorten the start string so that more codes can be included.  You can combine more than one command which start with the same two characters after the Escape by changing the last letter of the first part to lower case and leaving off subsequent two character prefixes:

~E&l1O~E&l66P~E&l2X can be shortened to ~E&l1o66p2X (note the ending character is left uppercase)

There are plenty of resources online for additional options such as specifying which paper tray should be used as input and which output tray the completed job ends up in.  THIS SITE has plenty of useful information and downloads to help further specify PCL options.   Spend some time in the SyteLine printer defaults on your test database to get everything to your liking and then deploy to production when ready.  Good luck and hopefully some readers will now have the information needed to print like a pro.


  December 24, 2015      Comments (0)

As an application engineer I find that there are certain circumstances where having a GUI screen to perform a task is not always possible/practical.  There are many times that the client has given me access to the database server but not the application server and there are simply times I am going through upgrade steps and simply don’t have a working environment yet to perform tasks via the front end.   This week I needed to perform a SyteLine 7 to SyteLine 9 upgrade that put me in such a situation and I had to get creative to find a workaround.  For this customer one of the upgrade steps was to purge out all user scoped versions of forms from SyteLine 7 (not very many folks will spend time going through the process of FormSync and nor would I) however the newest version of FormSync was displaying nondescript errors on the delete operation.  T-SQL to the rescue!

On a side note, I want to point out that I absolutely love what Infor has done with new SyteLine Infor CloudSuite and believe whole heartedly that no other company gives as much built in functionality for the cost per license.  It is a very stable and mature product and it’s few and far between that I am forced to work around an obstacle from the back end.  Secondly, I enjoy writing neat scripts to streamline my interaction with the ERP system and will almost always jump at the opportunity even when my plate is full.

For this task I wanted to whip up something that I could use in the future as part of the SQL cleanup process of removing user scoped forms automatically without having to ever open FormSync.   My advice to everyone is to utilize the great tools that Infor provides to maintain your database health however I do realize that there are cases when fixing from the back end is a better route to go (assuming you know what you are doing and the logic is sound).  As always I provide this “as is” and is meant for educating and not to replace functionality which is already available via the product.

Note: I wrapped the code in a BEGIN / ROLLBACK TRAN so that results can be viewed without actually causing true deletions of forms.  When I ran it, I used a COMMIT TRAN instead so that it would really delete the unneeded form.  Download Code Here



 @FormID INT
,@FormName nvarchar(50)
,@Scope INT

set @Scope = 3 --scope 1 for SITE, scope 2 for GROUP, scope 3 for USER
if @Scope < 1 or @Scope > 3
  RAISERROR('SCOPE MUST BE 1, 2 or 3',20,1) with LOG

DECLARE FormDelCur cursor local static for
SELECT Forms.ID, Forms.Name FROM Forms WHERE 
  [ScopeType] = @Scope
  --AND [Name] = N'JobOrders' 

open FormDelCur
fetch next from FormDelCur into @FormID, @FormName

while @@FETCH_STATUS = 0
   DELETE FROM FormEventHandlers WHERE FormID = @FormID
   DELETE FROM FormComponents WHERE FormID = @FormID
   DELETE FROM ActiveXComponentProperties WHERE FormID = @FormID
   DELETE FROM Variables WHERE FormID = @FormID
   DELETE FROM FormComponentDragDropEvents WHERE FormID = @FormID
   DELETE FROM DerivedFormOverrides WHERE FormID = @FormID
   DELETE FROM ActiveXScripts WHERE [Name] = @FormName AND [ScopeType] = @Scope
   DELETE FROM ActiveXScriptLines WHERE [ScriptName] = @FormName AND [ScopeType] = @Scope
   print 'Successfully deleted form ' + @FormName + ' with ' + CASE when @Scope = 1 then 'SITE SCOPE'
                                                                    when @Scope = 2 then 'GROUP SCOPE'
								    when @Scope = 3 then 'USER SCOPE'
   fetch next from FormDelCur into @FormID, @FormName
   print 'Unable to delete form ' + @FormName + 'with ' + CASE when @Scope = 1 then 'SITE SCOPE'
                                                               when @Scope = 2 then 'GROUP SCOPE'
							       when @Scope = 3 then 'USER SCOPE'
   fetch next from FormDelCur into @FormID, @FormName
close FormDelCur
Deallocate FormDelCur

  December 4, 2015      Comments (0)