In the world before cloud, this approach was in most respects fairly straightforward to implement for both SAP and the customer. In some respects, it was similar to a contract. There were certain things that SAP provided and certain steps and procedures that customers followed. Imagine a simple scenario where a screen in an SAP application contains two fields: revenue and cost. It would not be too presumptuous to guess that an end user would request an additional field to be added to the display. Let's assume that they did so by requesting a new field to display profit. And let's assume that the profit would be calculated not only using revenue and cost, but also a special numerical factor used by the customer. Since this factor is customer-specific, there isn't a field to hold it in any of the underlying database tables that the application is using.
To implement this type of scenario, SAP would provide what were known as exits to customers. These exits would be located at multiple layers throughout the "stack". Let's look at those layers one by one, starting with the lowest layer: the data layer. In our simple scenario, a developer would use a "table append" to add a new field to a database table representing the numerical factor mentioned previously. Once activated, this field would be available to be read and also to be stored. The table append effectively provided customers with a universal exit concept to adjust the definition of any provided SAP table to meet their unique business requirements.
The next stack layer that needed an exit to be provided by SAP would be the highest – the visual layer. It is here that the new field (profit, in our simple scenario) would be visualized. Visual layer exits consisted mainly of two types: Screen exits and menu exits. In our simple scenario, a developer would utilize a screen exit to add the new field to the screen, and possibly a menu exit to add a new command, which, upon being selected by the end user, would perform the calculation of profit.
The final stack layer that needed an exit would in some ways be the most important. This is because a new field added at the data layer of the stack and seen at the visual layer of the stack would contain a value that would need to be potentially read, used, updated, and maybe even deleted from time to time. These operations would need to be implemented using ABAP code. Thus, code exits that were implemented at the middle (that is, code) layer between the data and the UI were created by SAP. Again, in our simple scenario, a developer would first confirm that a code exit existed to perform any needed operations on the field and then the exit would be implemented with the necessary customer-specific code.
As a result, the customer would have the standard functionality delivered by an application, enhanced with the additional functionality they desired. One important aspect of this approach was that the entire process of utilizing exits was managed by a defined system process. Exits had to be activated. The specific implementation of the exit had to pass all relevant syntax and consistency tests. Development of exits happened in a dedicated development system and were tested in a testing system before being released to end users in the production system. Another important aspect of this approach was that, generally speaking, the development of exits could utilize any SAP object in the system without restriction. For example:
- Any SAP table could be used for reading and writing records
- Any SAP function module could be called
- Any SAP class (and methods thereof) could be used
One final (and important) point. If a customer determined that no exit was available (or was unusable), they could exercise the following two choices:
- Perform a modification of SAP objects in a manner to achieve the desired functionality.
- Copy SAP objects. The new object would be customer-owned and thus could be changed accordingly.
As mentioned earlier, a system delivered that features the benefit of customer adjustments as part of its design has to balance certain benefits and certain costs. In other words, when the time comes to apply patches or to upgrade the system, any extensions implemented could theoretically become a problem because the new or updated code from the software vendor could make an extension unstable or even unnecessary. Testing would be necessary to ensure that this was not the case. Nevertheless, even taking that into account, the costs of managing that testing process were reasonable against the benefits and flexibility of extensions. Generally speaking, customer adjustments done as the implementation of exits were less problematic on upgrades as the existence of the exits was known by SAP and could be accounted for. Modifications of SAP objects and/or copies of SAP objects could potentially be much more problematic and had to be tested thoroughly after a patch was applied or an upgrade took place.
This approach has sustained SAP and customers for many decades. From SAP R/3 in all of its versions up to and through SAP Business Suite, through service packs and enhancement packs. However, one reason that this approach has been successful was that systems were almost always located in customer data centers and thus were 100% maintained by customers themselves. What one customer was doing in their system was completely separate from what other customers were doing in theirs. However, a "game changer" occurred. That change was the evolution of SAP ERP to SAP S/4HANA.