Customization Analysis Report (CAR)

This article describes how to generate a Customization Analysis Report for your model. It also describes some best practice rules that are included in the report, and provides suggestions for fixing errors and warnings that are associated with these rules.

What is the Customization Analysis Report?

The Customization Analysis Report is a tool that analyzes your customization and extension models, and runs a predefined set of best practice rules. The report is one of the requirements of the solution certification process. The report is in the form of a Microsoft Excel workbook.

How to generate the report

To generate the Customization Analysis Report, run the following command in a development environment.

xppbp.exe -metadata=<local packages folder> -all -model=<ModelName> -xmlLog=C:\BPCheckLogcd.xml -module=<PackageName> -car=<reportlocation>

Example

xppbp.exe -metadata=C:\Packages -all -model="MyAppSuiteCustomizations" -xmlLog=C:\temp\BPCheckLogcd.xml -module="ApplicationSuite" -car=c:\temp\CAReport.xlsx

The xppbp.exe tool is located in c:\packages\bin or I:\AosService\PackagesLocalDirectory\bin.

Issues List

This section describes all best practice rules (errors, warnings, or informational messages) that can appear on the Issues List page of the report and provides suggestions for fixing the issues. Issues are of the metadata or code type. For all code issues, keep in mind that, if the warning or error occurs in a method that you've overlaid, the lines of code that violate the rule might belong to a model in a lower layer. In that case, you're not responsible for fixing warnings and errors in code that isn't yours.

BPCheckPackReturnsConnull

Description This rule applies to all classes that implement the SysPackable interface. It makes sure that the Pack method doesn't return Connull().
Error message Container pack method returns connull in a Runbase derived class
Issue type/severity Code/Warning
How to fix it Update the return value of the Pack method, or return Super() when applicable.

BPCheckParametersModified

Description This rule fails if a parameter of a method is modified inside a method.
Error message Parameter 1% in method %1 are modified inside the method
Issue type/severity Code/Warning
How to fix it Refactor your code. Parameters must be modified by the caller, not within the called method.

BPCheckSQLCode

Description This rule fails if your X++ code contains direct SQL code.
Error message SQL code found in method %1
Issue type/severity Code/Warning
How to fix it Refactor your code to use X++ to access the database.

BPCheckNestedLoopInCode

Description This rule fails if it finds a while select loop nested within a loop.
Error message Nested data access loop found in %1 method
Issue type/severity Code/Warning
How to fix it Refactor your code to use joins instead of nested data access loops. If you can't refactor the code without altering the business logic of your method, document an exception when you submit your Customization Analysis Report to Microsoft.

BPCheckInsertMethodInLoop

Description This rules fails if it finds a call to the method insert nested inside a loop. We recommend that you use InsertRecordList. This rule doesn't apply to InMemory tables.
Error message Insert method can be replaced with RecordInsertList in method %1
Issue type/severity Code/Warning
How to fix it Refactor your code to use set-based operations, such as InsertRecordList.

BPCheckSelectwithJoin

Description This rule fails if it finds nested select statements that aren't joined.
Error message Nested select statement in %1 method can be joined
Issue type/severity Code/Warning
How to fix it Refactor your code to use joins instead of a nested select statement. If you can't refactor the code without altering the business logic of your method, document an exception when you submit your Customization Analysis Report to Microsoft.

BPFunctionCallwithSelect

Description This rule fails if a function call is found within a select statement.
Error message Function call found in select statement in method %1
Issue type/severity Code/Warning
How to fix it Assign the function’s return value to a local variable before you call the select statement, and use the local variable in the select statement.

BPCheckinvalidExecuteQuery

Description This rule fails if a call to addRange is found after a call to super() in the ExecuteQuery method.
Error message Add range after super() should not be added in ExecuteQuery method for form %1
Issue type/severity Code/Warning
How to fix it Refactor your code to avoid this pattern.

BPCheckInvalidInitFormMethod

Description This rule makes sure that you don't initialize form controls and data sources in a form’s init method before you call super(). It fails if it finds a statement that uses element or this before the call to super() (this.aMethod() or element.aMethod()). An informational message is shown only for some allowed patterns, such as initializing number sequences (numberSeqPreInit).
Error message Form element statements should not be used before super() in init method of form %1
Issue type/severity Code/Info or Warning
How to fix it Refactor your code to access form controls and data after the call to super(). If your code doesn't initialize any form control and doesn't access any form data sources before super(), document an exception when you submit your Customization Analysis Report to Microsoft.

BPCheckEmptyLoop

Description This rule fails if it finds loops that have no statements.
Error message Empty loop found in method %1 in class %2
Issue type/severity Code/Warning
How to fix it Remove the loop from your code.

BPCheckLockQueryRange

Description This rule fails if the code calls AddRange in the init method of the form, and doesn't set the range as locked or hidden.
Error message Range should be locked or hidden in form %1
Issue type/severity Code/Warning
How to fix it Add QueryBuildRange.status(RangeStatus::Locked) or QueryBuildRange.status(RangeStatus::Hidden) after the call to AddRange.

BPCheckSkipStatementValidation

Description This rule reports an informational message if it finds a set-based operation that doesn't have Skip statements.
  • When update_recordset is found, the rule checks for skipDataMethods(true). The rule applies only when the update method on the table is overridden.
  • When insert_recordset is found, the rule checks for skipDataMethods(true). The rule applies only when the insert method on the table is overridden.
  • When delete_from is found, the rule checks for skipDeleteActions(true). The rule applies only when the insert method on the table is overridden.
This is an informational message that highlights the need to call skip methods to take full advantage of the performance gains of set-based operations. If skip methods aren't used, the execution falls back to a row-by-row operation.
Error message Set-based operation must invoke Skip statements in method %1 in class %2; otherwise, execution will fall back to a row by row operation.
Issue type/severity Code/Information
How to fix it Use skipDataMethods(true) or skipDeleteActions(true) when applicable.

BPCheckNoTTSTryBlock

Description This rule fails if it finds a try statement within a tts block that isn't handled correctly.
Error message Tts block with Try statement does not explicitly catch exceptions in method %1
Issue type/severity Code/Warning
How to fix it The following examples show when the rule will fail or pass. Use these examples as guidelines to refactor your code.
ttsbegin;
try {
}
// fail
catch {
}
try {
}
// pass
catch(Exception::UpdateConflict) {
}
try {
}
// pass
catch(Exception::UpdateConflictNotRecovered) {}

BPCheckEmptyTableMethod

Description This rule checks for table methods that have no source code. Empty table methods cause record-set operations on the table to fall back to a row-by-row operation.
Error message %1 table has an empty %2 method
Issue type/severity Code/Warning
How to fix it Remove this method from your code.

BPCheckBatchJobsEnabled

Description This rule makes sure that all classes that extend RunBaseBatch have a canGoBatch method that returns true.
Error message Custom job is not batch-enabled in class %1
Issue type/severity Code/Warning
How to fix it The canGoBatch method must return true for all batch classes.

BPCheckDisplayMethodCached

Description For each control that is bound to a data method, this rules fails if one of these conditions is met:
  • The Cache Data Method property is set to Auto, the corresponding table display/edit method doesn't have the SysClientCacheDataMethodAttribute, and the init method of the data source doesn't use CacheAddMethod.
  • The Cache Data Method property is set to No, and the init method of the data source doesn't use CacheAddMethod.
Error message Display method %1 in form %2 not cached
Issue type/severity Code/Warning
How to fix it You can fix this warning by using one of the following patterns:
  • Set the Cache Data Method property to Yes.
  • Set the Cache Data Method property to Auto, and mark the data method of the table with the SysClientCacheDataMethodAttribute attribute. Here is an example.

    [SysClientCacheDataMethodAttribute(true)]
    Display TransDate myDateMethod()
    {
        ...
    }
  • Use CacheAddMethod in the init method of the form to mark the method as cached.

BPCheckSQLQueryInInit

Description This rule fails if a data access query that has a while loop is found in the init method of a form. This pattern could cause performance issues when the form is initalized.
Error message SQL query with while loop was found in init method of form %1
Issue type/severity Code/Warning
How to fix it Refactor your code to avoid this pattern.

BPCheckNewQueryWithForm

Description This rule fails if it finds the new Query() statement in the init or executeQuery method of a form.
Error message Data source query overridden in form method %1
Issue type/severity Code/Warning
How to fix it Refactor your code to avoid this pattern.

BPCheckSelectForUpdateAbsent

Description This rule fails if Select ForUpdate is used to select records, but an update isn't being performed. This rules doesn't apply to tables that are enabled for Optimistic Concurrency Control (OCC).
Error message Select ForUpdate not implemented in method %1
Issue type/severity Code/Warning
How to fix it Use Select instead of Select ForUpdate, or set the OCC Enabled property to Yes on the table.

BPCheckTablePropertyMismatch

Description This rule fails when the table belongs to a table group but doesn't have the appropriate Cache Lookup value. The rule fails if one of these conditions is met:
  • The Table Group property is set to Main, and the Cache Lookup property is set to NotinTTS or EntireTable.
  • The Table Group property is set to Group or Parameter, and the Cache Lookup property is set to NotinTTS.
  • The Table Group property is set to WorksheetHeader, WorksheetLine, or Transaction, and the Cache Lookup property is set to Found, FoundAndEmpty, or EntireTable.
Error message %1 table has an invalid combination of table group and cache lookup
Issue type/severity MetaData/Warning
How to fix it Set an appropriate Cache Lookup value on the table.

BPCheckMissingDeleteActions

Description This rule validates that the value of either a delete action or the On Delete property of a table relation isn't equal to None. The rule isn't triggered when the related or current table is a tempDB, in memory table, reference table, staging table, or parameter table.
Error message Delete actions missing in table %1 which is related to table %2 with relation name %3
Issue type/severity MetaData/Warning
How to fix it Set a delete action value that isn't equal to None.

BPCheckAddressModel

Description This rule fails if a table field is of the AddressZipCodeId or AddressStateId type. These types indicate that the code didn't uptake the newer Address framework.
Error message Field %1 of table %2 is not part of address location model
Issue type/severity MetaData/Warning
How to fix it Replace these types with any other appropriate EDT type in the Directory model.

BPCheckDimensionModel

Description This rule fails if a table field is of the Dimension or LedgerAccount type. These types indicate that the code didn't uptake the newer Financial Dimension framework.
Error message Field %1 of table %2 is not part of financial dimension framework
Issue type/severity MetaData/Warning
How to fix it Replace these types with any other appropriate EDT type in the Dimensions model.

BPCheckNumberofNewFields

Description This rule verifies that no more than 10 fields were added to a table during the process of customizing or extending that table. This rule doesn't apply to staging tables.
Error message Number of new fields in table %1 is greater than
Issue type/severity Metadata/Warning
How to fix it Refactor your schema and create related tables instead of adding too many fields to an existing table.

BPCheckEnumUpgradeIssue

Description This rule fails when the following condition is met: When you customize an enum (overlayer), new enum values are less than the maximum existing value + 10. This rules doesn't apply to extensible enums.
Error message Enum %1 will have upgrade issues
Issue type/severity MetaData/Warning
How to fix it Use larger enum values, or extend the enum.

BPCheckPassiveJoinUse

Description This rule validates that, when a form allows for pre-loading of data, the link type of tab page data sources is passive. The rule fails if all the following conditions are met:
  • A form has the AllowPreLoading property set to Yes.
  • A tab page on the form is bound to a top-level data source.
  • The data source’s Join Source property is set.
  • The data source’s Link Type property isn't set to Passive.
Error message New message suggest: “Use passive joins on data sources %1 bound to a tab page control in form %2”
Issue type/severity MetaData/Warning
How to fix it Set the AllowPreLoading property to No on the form, or use passive joins on the data source. Passive joins require that you explicitly program when the query of a tab page is run.

BPCheckAltenateKeyAbsent

Description This rule verifies that tables that have a unique index have at least one alternate key.
Error message Table %1 does not have an alternate key
Issue type/severity MetaData/Warning
How to fix it Set the Alternate Key property to Yes on a unique index of the table.

BPCheckBaseTableModified

Description This rule discourages the customization (overlayering) of a list of specific base tables that are shipped by Microsoft. Examples are the SourceDocumentHeader and SourceDocumentLine tables.
Error message %1 is a base table and must not be modified
Issue type/severity MetaData/Warning
How to fix it Don't customize the table.