0

Microsoft Dynamics AX (now part of Dynamics 365 Finance & Operations) was and still is a multi-legal-entity (multi-company) ERP system. Go ahead and start your journey now to upgrade your knowledge on what x++ is used for in D365 FinOps modern ERP with the help of Dynamics Edge.

x++ changecompany vs crosscompany
x++ changecompany vs crosscompany

In Dynamics AX / Finance & Operations Data generally being partitioned by company (also called legal entity). That is meaning most of your Dynamics 365 Finance and Operations CrossCompany vs ChangeCompany X++ queries and operations are scoped to the current company context. To work with data across company boundaries, X++ (the AX/Finance & Ops programming language) provides two key constructs: crossCompany and changeCompany. These allow developers to access or manipulate data in other company contexts, but in different ways. Below, we explain what each does, provide real-world examples, and then compare and contrast them (including usage in AX 2009, AX 2012, and the latest Finance & Operations).

What is crossCompany?

In X++, the crossCompany keyword allows a select query to retrieve data from multiple companies (including the option of all companies) in a single go. When you use crossCompany in a select statement, AX will return records from all specified company partitions without needing to manually switch context. By default, if no specific companies are listed, it will fetch records from all companies. You can also limit the scope by providing a container of company IDs, so the query only returns data from those particular legal entities. Importantly, crossCompany is only used with read (select) operations – it cannot be used to insert or update records across companies.

Real-world scenario: Imagine a global business wants to generate a consolidated report of all customers across all its subsidiaries (legal entities). Using crossCompany in an X++ select query, a developer can fetch customer records from every company at once, rather than running separate queries per company. This is useful for reporting or data analysis – for example, listing all vendors from all country offices to identify duplicates or global spend. In one X++ job or report query, crossCompany can retrieve, say, every vendor from all company partitions, producing output that includes the vendor’s account and the company they belong to. This single-pass approach is efficient for read-only data aggregation across many companies.

What is changeCompany?

The changeCompany construct in X++ allows you to change the current execution context to a different company (legal entity) for a block of code. In practice, you call changeCompany("CompanyID") with a target company’s identifier, and within the curly-braced block that follows, any database operations run as if the code is logged into that company. This means you can select, insert, update, or delete data in that other company’s context. Unlike crossCompany, which is limited to queries, changeCompany works for all data operations (CRUD). However, it operates on one company at a time – you must specify a single company each time you use it (you cannot fetch or affect multiple companies simultaneously in one changeCompany block). To work with multiple companies, you would typically loop through a list of company IDs and call changeCompany for each in turn.

Real-world scenario: Consider an organization that needs to perform an action in each of its companies, such as initializing settings or creating a record in all legal entities. With changeCompany, a developer can programmatically loop through each company. For example, you could iterate through all company IDs in the system and within each iteration use changeCompany(companyId) { ... } to, say, create a new customer or copy a configuration record in that specific company. Each iteration temporarily switches the context, performs the insert/update, then moves on. This is crucial for scenarios like intercompany operations or data synchronization: e.g. if a new product needs to be created in several companies, you can write X++ code that uses changeCompany to create the product in company A, then company B, and so on, all in one execution. Without changeCompany, you’d have to manually log into each company’s session or use separate service calls. Essentially, changeCompany enables multi-company automation by handling one company at a time, including write operations that crossCompany cannot do.

Key Differences Between crossCompany and changeCompany

Both crossCompany and changeCompany let you work with data across company boundaries, but they differ in syntax, capabilities, and typical use cases. Below are the core differences:

  • Syntax and Usage Context: crossCompany is a keyword used inline in select statements, whereas changeCompany is used as a block structure with curly braces encompassing X++ code. For example, you might write select crossCompany * from CustTable; versus using changeCompany("USMF") { ... } with a block of code. The former modifies a query, the latter changes execution context for a code segment.
  • Read vs. Write Operations: crossCompany applies only to data retrieval (SELECT). You can perform queries across multiple companies, but you cannot directly insert/update/delete using crossCompany. In contrast, changeCompany allows full CRUD operations under the target company’s context. If you need to create or modify records in another company, you must use changeCompany (or an equivalent context change), since cross-company write operations are not allowed otherwise. In fact, Finance & Operations will throw errors like “Insert operations are not allowed across companies” unless you switch context. Microsoft’s documentation explicitly notes that for cross-company create/update/delete, you should use the changeCompany keyword to change the current company context.
  • Scope of Companies: crossCompany can target multiple companies at once. By default it runs the query for all companies, or you can specify a set of companies (using a container or query ranges) to restrict it. This means one query execution can return a unified result set containing records from many legal entities. On the other hand, changeCompany works one company at a time – you specify a single company’s ID in each call. If your goal is to iterate through several companies, you will call changeCompany repeatedly (e.g. in a loop) for each company. There is no built-in way to do a single changeCompany on multiple companies simultaneously – you must handle them one by one.
  • Result Handling: When using crossCompany, the result of a select query is a combined dataset. For example, a select crossCompany * from VendTable might return vendors from all companies, and each record carries its company identifier (DataAreaId) so you know which company it came from. In contrast, with changeCompany, since you execute code separately per company, you typically handle results or operations within each company’s context. If you need a combined result from changeCompany loops, you have to aggregate it yourself (e.g. storing results from each iteration). Essentially, crossCompany is better for returning a unified multi-company view, whereas changeCompany is used to perform actions in isolation per company (though you could accumulate results as needed).
  • Performance Considerations: Because crossCompany pulls data in one go (often translating to a SQL query with an IN clause listing all the specified companies), it can be efficient for reading widely — but it might also retrieve a lot of data and could become heavy if many companies are involved. In scenarios where only one company’s data is needed, using crossCompany is unnecessary overhead. In fact, developers observed in AX 2009 that a crossCompany query targeting a single company still incurred the overhead of a cross-company call (SQL IN ()) and could become a bottleneck with many companies configured. In such cases, a simple changeCompany loop for that one company was more straightforward and performant. Microsoft addressed one such issue in AX 2012 R2 by replacing a single-company crossCompany call with changeCompany in standard code. On the other hand, if you truly need data from dozens of companies, a single crossCompany query may outperform a loop of many context switches. The best choice can depend on the volume of data and number of companies: crossCompany yields one combined query (with filtering by company in SQL), whereas changeCompany might issue separate queries per company inside a loop.
  • Code Maintainability: Using crossCompany can be succinct for read-only queries across firms – one query can replace what would otherwise be several. It also integrates with query objects (you can set a query’s .allowCrossCompany(true) and even add specific company ranges) making it convenient for reporting scenarios. changeCompany, however, offers more fine-grained control; inside a changeCompany block, you can execute multiple operations, business logic, and even multiple queries under that company context. It’s essentially like programmatically logging into each company and performing a sequence of actions. The code for changeCompany might be longer (due to looping and context management), but it is necessary when updates or complex logic per company are needed.

Real-World Scenario Comparisons

To solidify the differences, consider a couple of scenarios:

  • Scenario 1: Global Data Retrieval – Suppose the CFO wants a consolidated list of all open purchase orders across all subsidiaries in an AX/Finance & Operations deployment. A developer could write an X++ query using crossCompany to select from the PurchaseOrder table and retrieve all open orders in one result set. The output might include a field for company, so you can see which company each order belongs to. This single job can quickly scan every company’s data and present a merged view. Attempting the same with changeCompany would mean iterating through each company, querying its open orders, and merging results in code. That approach is more complex and slower due to multiple context switches. Thus, crossCompany is ideal for such read-only reporting across many legal entities.
  • Scenario 2: Multi-Company Operations – Now imagine an IT administrator needs to create a new fiscal calendar or enable a feature in all companies. This is a write operation that must happen within each company’s context. Using changeCompany in a loop is the straightforward solution: the code switches to company A, performs the creation (e.g. adds a record or updates a setting), then switches to company B and does the same, and so on. Trying to use crossCompany here is not even an option, because you cannot do cross-company inserts/updates directly. Similarly, for an intercompany transaction scenario (like creating a sales order in one company that triggers a purchase order in another), a developer would use changeCompany to create the related record in the other company’s environment during the process. This ensures each transaction is properly recorded under the correct legal entity context.

In summary, use crossCompany when you need to read data across multiple companies in one sweep (for example, consolidated reporting or searches across companies), and use changeCompany when you need to perform transactions or detailed processing in another company’s context (for example, creating or updating records, or any case where writes across company boundaries are required). Both have been supported since at least AX 2009 and AX 2012, and they continue to be relevant in Dynamics 365 Finance & Operations. In newer versions (Finance & Ops), the underlying principles remain the same: queries default to the current company, but crossCompany can override that for multi-company reads, and changeCompany is the tool for any cross-company writes or context-specific logic. By understanding these tools and their proper use cases, developers and power users can effectively handle multi-entity data scenarios in Dynamics AX/Finance and Operations.

Have a Question ?

Fill out this short form, one of our Experts will contact you soon.

Call Us Today For Your Free Consultation