CFL has several functions that are not general purpose (as those above) but specific to layout of pages and signs on a roll or sheet. Though the calculation can be (and have been) done using the general formulas, these occur so often that CFL has special functions to manage them.

See Also cfl_function_-_calculatelayoutonsheet and cfl_function_-_calculatelayoutonroll.

In order to determine the optimal layout, Control must calculate the layout with both a portrait and landscape orientation. Each of these orientations is tiledTiling refers to putting multiple copies horizontally and vertically next to each other across the sheet. or paneledPaneling refers to splitting a copy across multiple sheets. if the items dimenstions are larger than the sheet dimensions. The total amount of material used for the required number of printsWe'll use prints to mean signs, copies, prints, or whatever is being produced. is calculated and the orientation with the minimum material usage (that also satisfies other requirements passed in) is chosen.

This concept, though simple, involves complex calculations that formerly took over 30 independent variables to compute and record. Hence, this function has been well received!

I would recommend experimenting on a new product while you are learning and avoid changing anything on your existing products until you are satisfied with your results.

One common mistake is also to forget the distinction between GetVariablePropertyValue and GetVariablePropertyText. The former must be used to pull number and yes/no values, while the latter must be used to pull text values.

We are going to create a basic layout here. There are some additional options to this function we won't explore in this How-To, but the names of the parameters and documentation at cfl_function_-_calculatelayoutonsheetshould be sufficient to help you refine it to your needs.

Create Variables

  1. Create the following number input variables. (In some cases, you can pull the information from other places as noted below, but I'm going to use the variables in this example.)
    • Quantity (Entered by user)
    • ImageHeight (Entered by user)
    • ImageWidth (Entered by user)
    • ImageGap (The space between prints, needed for cut or bleed. Often ignored (0) or entered by the user.)
    • SheetHeight (Commonly pulled from user input, a Part UDF, or a selection list property.)
    • SheetWidth (Commonly pulled from user input, a Part UDF, or a selection list property.)
    • PrintMargin (The non-printable border/space around each print. Zero if not used.)
  2. Create the following Yes/No input variables.
    • TwoSided (TRUE if the print is to be done on both sides of the sheet.)
  3. Create the following text variable to store the results of the calculation.
    • SheetLayout (Used to store the results of the layout calculations.) Enter the following formula in the Default value formula.


  • Everything after the double-slashes is a comment. It isn't required but you'll thank yourself later if you record what you are doing today.
  • Although we aren't doing so in this simple example, you can use any valid CFL statement for each of these parameters. You don't have to create variables for each value that is passed in unless it makes sense to (usually because the user can override it).
    SheetLayout,    // Variable to store the results in
    ImageHeight,    // Image Height
    ImageWidth,     // Image Width
    Quantity,       // Quantity
    TwoSided,       // Whether to print the (same) image on both sides
    SheetHeight,    // Sheet Height
    SheetWidth,     // Sheet Width
    ImageGap,       // Gap across the height (length) of the roll
    ImageGap,       // Gap across the width of the roll
    PrintMargin,    // Margin at the top of each print
    PrintMargin,    // Margin at the bottom of each print
    PrintMargin,    // Margin at the left side of each print
    PrintMargin,    // Margin at the right side of each print
    0,      // Margin at the top of each sheet
    0,      // Margin at the bottom of each sheet
    0,      // Margin at the left of each sheet
    0,      // Margin at the right of each sheet
    0,      // Overlap Amount - Amount of material to overlap when paneling
    True,   // Can Rotate - If true, calculate rotated and non-rotated to find optimal
    True,   // Can Tile - If true, calculate multiple across if they fit
    True    // Avoid Paneling - If true, always choose a non-paneled solution if possible
  1. Create the following calculated number variables and set the formulas as indicated. Set the units to the appropriate units for the variable.
    • PrintedScrapArea = GetVariablePropertyValue(SheetLayout,“TotalScrapArea”,0)
    • PrintedTotalArea = GetVariablePropertyValue(SheetLayout,“TotalProducedArea”,0)
    • PrintedSheets = GetVariablePropertyValue(SheetLayout,“LayoutSheets”,0)
  2. Create the following text variable to provide information to display to the user.
    • RollPrintLayoutNotes. The formula for this variable should read:

code format="vb"

“Printing Material Layout”

+CHAR(13) + CHAR(10)

+CHAR(13) + CHAR(10)

+CHAR(13) + CHAR(10)+ “Is Rotated : ” + IF GetVariablePropertyValue(SheetLayout,“IsRotated”, False) THEN “Yes” ELSE “No” ENDIF

+CHAR(13) + CHAR(10)+ “Is Paneled : ” + IF GetVariablePropertyValue(SheetLayout,“IsPaneled”, False) THEN “Yes” ELSE “No” ENDIF

+CHAR(13) + CHAR(10)+ “Number Up : ” + GetVariablePropertyText(SheetLayout,“PrintsPerSheet”,“0”)*

+CHAR(13) + CHAR(10)+ “Number Wide : ” + GetVariablePropertyText(SheetLayout,“PrintsWide”,“0”)

+CHAR(13) + CHAR(10)+ “Number Height : ” + GetVariablePropertyText(SheetLayout,“PrintsHighPerPanel”,“0”)

+CHAR(13) + CHAR(10)

+CHAR(13) + CHAR(10)+ “ Printed Area = ” + DisplayVariableValue(PrintedTotalArea, -2)

+CHAR(13) + CHAR(10)+ “+ Scrap Area = ” + DisplayVariableValue(PrintedScrapArea, -2)

+CHAR(13) + CHAR(10)+ “= Total Area = ” + ToString( (PrintedTotalArea+PrintedScrapArea) In UnitArea, 2) + “ ” + UnitAreaName

+CHAR(13) + CHAR(10)

+CHAR(13) + CHAR(10)+ “= Sheets = ” + DisplayVariableValue(TotalSheets, -2)

+CHAR(13) + CHAR(10)

Create Product

  • Create a product that uses these variables
  • Set the price formula to charge a certain rate for printed area and a certain rate for the scrap.
    • Example: PreDiscountPrice = (10 * PrintedTotalArea in SqFeet) + (2 * PrintedScrapArea in SqFeet)
  • Create a product layout if desired.
  • Create a pricing form that uses these variables (requires Control Customizable) and set the product to use this Pricing Form. Make sure the RollPrintLayoutNotes variable is displayed in a memo large enough to see the results as you work.

Hint: If you are just creating this for testing and don't want to bother with a polished Pricing form, or if you don't have Control Customizable, you can use the “Variable Grid” pricing form. This pricing form creates a grid of all of the variables in a product (arranged alphabetically) that you can use while you are testing and debugging.
A sample pricing form text is below (you can copy the text below and paste it into the “Advanced” tab in pricing form entry and then click the lightning button to generate it.

Test the Product

  1. Create an order.
  2. Add the product you created above to the order.
  3. Enter different sizes. Confirm that the rotation, tiling, and paneling property all work as you expect.
    • Example 1

ImageHeight = 24, ImageWidth = 12, PrintMargin = 0 MaterialWidth = 48, MaterialHeight = 86, ImageGap = 0 Quantity = 100 Result: In this case, whether rotated or not, the image fits optimally with no wasted space.

  • Example 2

Change ImageGap = 1 so that now we have spacing between the images. Result: Because of the additional spacing between prints, we can ….

  • Example 3

ImageHeight = 22, ImageWidth = 28, PrintMargin = 0 MaterialWidth = 36, MaterialHeight = 48, ImageGap = 0 Quantity = 100 Result:

Some additional ways to expand the Layout functions include:

  • Add an option to prevent rotation.
  • Consider Two Sided Printing.
  • Use the calculations to tie into the Material, Ink (for digital), Labor, etc.
  • Add error checking to the product.
  • Add the material as a Dynamic Part selection list and pull the paper width from selection list properties.
  • Add the material as a Dynamic Part selection list and pull the paper width from Part UDFs.
  • Add the machine as a Dynamic Part selection list and pull the margins from Part UDFs.

Contributor: Cyrious Software Date: 8/10/2009 Version: Control 4.2+

You could leave a comment if you were logged in.