CabMasterPro User Guide
In This Topic
    Syntax
    In This Topic
    Formula syntax is the structure or order of the elements in a formula. Formulas in CabMasterPro consist of operands and operators. Each operand can be a constant or literal value, a named item, or the result of a function.

    Property Names Any non-reserved word that starts with a letter, e.g. cabinet_width
    Literal Values An actual string or number, e.g. "some text" or 52mm
    Operators Combines two values in some way, e.g. minus, +, <=, OR
    Constants A built-in fixed (non-modifiable) value, e.g. TRUE, DarkRed, LIBRARY_FOLDER
    Functions A pre-defined formula which usually takes parameters and returns a value, e.g. Sqrt(9)
    Control Structures Loops and branches controlling the flow of execution through a formula, e.g. If-Then-Else

    Property Names

    Any formula can refer to the value of a drawing property or other property, depending on where it is in a drawing. For example, a formula in the Drawing Properties can only access other drawing-level properties, but a Page Property can access drawing and page-level properties.

    If you want one property to contain the same value as another, enter the name of the other property as the formula. The property that contains the formula is known as a dependent property, because its value depends upon another property. Whenever the property that the formula refers to changes, the property that contains the formula also changes. The formula Height * 5 multiplies the value of the property 'Height' by 5. The formula will recalculate whenever the value of the property 'Height' changes.

    Comments

    C-style comments in middleware formulas are allowed. For example, /*comment*/ and //to-end-of-line

    Formulas can be multiline, like this...

    Cabwidth /*the width*/ - 2 * endthk
    + if nn>3 then (nn-3)*xxallowance // some optional allowance

    In the above two line formula, there's an embedded comment /*the width*/ which is between the opening /* and the closing */

    There is also a comment on line two which starts with // and goes to the end of the line.
    Both of these comments are preserved when you save the formulas, but are only there to help explain the purpose of the formula, and are completely ignored when evaluating the formula.

    These two comment styles are exactly as you would use in C-language programming, for those familiar with that.

    Drawing Property Names

    Information in your Drawing Property sheets is available for use in both custom reports and formulas.

    Drawing property names refer to named values in the Drawing Properties. The names you use for properties are not case dependent. However, they must begin with a letter, and can contain only letters, digits, spaces, and underscores. When CabMasterPro encounters a name in a formula, it looks at the drawing properties for an entry with the same name. If there is no matching entry in the drawing properties, then the program prompts you for a value, and appends it to the list of custom properties for the drawing.

    Usually CabMasterPro uses the value associated with the name directly in the formula. In the previous example, the name 'Overall_Depth' has a value 600mm, 'Door_Thickness' is 18mm, and 'Tops_Overhang' is 20mm. So the result is 600mm - 18mm - 20mm = 562mm, as displayed in the depth edit box.

    It is possible to have another formula associated with a name, rather than a simple value. In this case, the value should be of type Formula. CabMasterPro will evaluate the value as another formula, and use the result in the original formula. For example, we might define some custom drawing properties as follows:

    Name Type Value Formula
    Door_Thickness Length 18mm None
    Tops_Overhang Length 20mm None
    Standard_Depth Length 600mm None
    Extra_Deep Length Calculated Standard_Depth + 100mm
    Extra_Narrow Length Calculated Standard_Depth - 100mm

    If we use a formula such as Extra_Deep - Door_Thickness - Tops_Overhang, CabMasterPro will first look up 'Extra_Deep' and get the formula Standard_Depth + 100mm. Because this is a formula value, CabMasterPro will then evaluate Standard_Depth + 100mm as 600mm+100mm giving 700mm. CabMasterPro will then continue with the original formula and evaluate it as 700mm - 18mm - 20mm, giving 662mm.

    Object Property Names

    Most properties of cabinets and other objects are accessible in formulas. See the Cabinet Properties formula section.

    Examples:

    Variable Types

    When you store a variable, you can force it to be a specific type, such as Number, Length, Money, String, and so on. Even Number may not be specific enough - you may want a variable to be a Whole Number, in which case 1  2  or  3 would be allowed, whereas 1.5 would not.

    Using very specific types is a powerful way of ensuring your formulas are robust. For example, storing a variable used in a cabinet as a Length instead of a Number means that if it has a value of 1 inch it will stay that way. If you switch to metric, it will be displayed as 25.4mm (or 2.54cm for centimetres). Storing it simply as the number 1 would mean that cabinets that look right in imperial measure could suddenly look very strange if you switch to metric, as the number would then be interpreted as 1 mm.

    Conversion Issues

    In older versions of CabMasterPro, types were much more limited. All variables had to be stored on the "Custom Properties" page. When you load an older drawing or library, it automatically converts all the old custom questions and answers to the All Answers page of the "Answers & Setup" category group. If you read an old drawing, or start a new drawing with an old library, you will see this if you select File menu > Prepare / Drawing Properties. Formulas are evaluated during this conversion process and provided they are valid, are placed in the "Formula" column, with the calculated results in the "Value" column.

    CabMasterPro may not be able to evaluate all of your old custom formulas. That is because variables they depend on might not have a value in the context of the whole drawing. They might be things like section heights or component fields like 'cost'. For example, there is a variable called 'retail_price' used in components in our distribution library. It had the formula value if(comp_level_pricing,cost*markup[category],0). In this formula, both 'cost' and 'category' come from fields in the same component, and may be different from one component to the next. So 'retail_price' cannot be treated as a formula at drawing or library level. Instead, evaluation is delayed until the formula is used. To do this, it is stored as a String with a leading equals sign. Then when 'retail_price' is used, the leading '=' forces it to be evaluated as a formula instead of being used as a literal string.

    Changing Variables

    There used to be only one way of changing the value of a variable. Now custom (user defined) variables can be changed via Friendly Pages. You can still change them directly by editing their values in the All Answers page. If a variable does not have a value at all, its initial value can be set via the Friendly pages 'Default' column. Once a variable has a value for a drawing (or library), the 'Default' column in the friendly pages is no longer used. You can only change the value by altering it with a Friendly page edit box or directly editing the value in 'All Answers'.

    User Defined Functions

    User defined functions allow you to specify a formula with parameters. The parameters are substituted for %1,%2,%3 and so on for all parameters. A simple example is you can define a string variable in 'All Answers' as follows:

    Name Type Value
    ADD String %1 + %2

    Then use it with parentheses to indicate a function. Try typing this new variable into 'All Answers', then edit the formula behind a text label to say ADD(3,4). CabMasterPro will interpret the string as a function of two parameters, evaluate it with parameters 3 and 4 to get 3 + 4 = 7 and display 7 as the answer.

    This can be done with more complicated formulas also, for example if you wanted a function which would abbreviate a string by taking the first 5 letters if it is one word or the first 4 from the first word and the first 3 from the second word if it's multiple words the following user defined function could be done:

    Name Type Value
    ABBREVIATE String let i=find(" ",%1);if i=0 then left(%1,5) else left(%1,4)&left(mid(%1,i+1),3)

    So if you were to call this using abbreviate("Functions") it would return "Funct", or abbreviate("User-defined Functions") would return "UserFun".

    Deferred Evaluation

    By default, if you were to specify a formula in a specific context (such as Drawing Level), the formula would be evaluated at that level and then the result would be available to lower levels. Deferred evaluation allows you to specify a formula but not actually evaluate it in the context where it is defined, instead evaluating it in the context where it is used.

    For example, if you wanted to set the Text of all of your cabinets in the library to be the Type, Code, Description you could put the following formula into every cabinet in the Text field: type&", "&code&", "&desc. However, such formulas may get complicated and having it in every cabinet makes it hard to maintain. So instead you would define a deferred evaluation formula at Drawing level which is based on the cabinet level values, then use this value at the cabinet level (at which point, when used, will be evaluated in that context).

    To do this you would simply add a string at library level with a colon ':' followed by the formula to be deferred

    Name Type Value
    deferredText String :type&", "&code&", "&desc

    At Drawing level the variables type and code and desc do not actually have a meaning, so if you put this as a normal formula they would be undefined now. But, since it is deferred, CabMasterPro will not try to evaluate it at this level. At the cabinet level you would set the Text value to be equal to the formula:deferredText

    And at this stage it will be evaluated to be used, and at the cabinet level Type and Code and Desc are all defined so it will evaluate correctly. The advantage of this comes up when you want to modify it later. For example, if you decided that you'd prefer the text to just be the type and code and not the description you would simply change the library level variable to:

    Name Type Value
    deferredText String :type&", "&code


    And the change would update all the cabinets, as opposed to having to modify them all separately.