S4D400 Introduction to ABAP Programming for SAP S/4HANA . . PARTICIPANT HANDBOOK INSTRUCTOR-LED TRAINING . Course Version: 20 Course Duration: 5 Day(s) e-book Duration: 8 Hours 15 Minutes Material Number: 50151411 SAP Copyrights, Trademarks and Disclaimers © 2020 SAP SE or an SAP affiliate company. All rights reserved. No part of this publication may be reproduced or transmitted in any form or for any purpose without the express permission of SAP SE or an SAP affiliate company. SAP and other SAP products and services mentioned herein as well as their respective logos are trademarks or registered trademarks of SAP SE (or an SAP affiliate company) in Germany and other countries. Please see http://global12.sap.com/corporate-en/legal/copyright/index.epx for additional trademark information and notices. Some software products marketed by SAP SE and its distributors contain proprietary software components of other software vendors. National product specifications may vary. These materials may have been machine translated and may contain grammatical errors or inaccuracies. These materials are provided by SAP SE or an SAP affiliate company for informational purposes only, without representation or warranty of any kind, and SAP SE or its affiliated companies shall not be liable for errors or omissions with respect to the materials. The only warranties for SAP SE or SAP affiliate company products and services are those that are set forth in the express warranty statements accompanying such products and services, if any. Nothing herein should be construed as constituting an additional warranty. In particular, SAP SE or its affiliated companies have no obligation to pursue any course of business outlined in this document or any related presentation, or to develop or release any functionality mentioned therein. This document, or any related presentation, and SAP SE’s or its affiliated companies’ strategy and possible future developments, products, and/or platform directions and functionality are all subject to change and may be changed by SAP SE or its affiliated companies at any time for any reason without notice. The information in this document is not a commitment, promise, or legal obligation to deliver any material, code, or functionality. All forward-looking statements are subject to various risks and uncertainties that could cause actual results to differ materially from expectations. Readers are cautioned not to place undue reliance on these forward-looking statements, which speak only as of their dates, and they should not be relied upon in making purchasing decisions. © Copyright. All rights reserved. iii Typographic Conventions American English is the standard used in this handbook. The following typographic conventions are also used. This information is displayed in the instructor’s presentation Demonstration Procedure Warning or Caution Hint Related or Additional Information Facilitated Discussion User interface control Example text Window title Example text © Copyright. All rights reserved. iv Contents vii Course Overview 1 Unit 1: 2 9 Lesson: The Development Model in SAP S/4HANA Unit 2: 10 21 39 Unit 3: Unit 4: Unit 5: Unit 6: Unit 7: Using Internal Tables Lesson: Internal Table Types Lesson: Working with Internal Tables Unit 8: 131 139 141 149 157 Using Structures Lesson: Using Structures 107 113 130 Calling Reusable Procedures Lesson: Understanding Reuse Lesson: Using Classes Lesson: Using Function Modules 96 106 Debugging in ABAP Lesson: Debugging in ABAP 78 82 86 95 Working with Variables in ABAP Lesson: Working with Variables 70 77 The ABAP Development Environment Lesson: ABAP Development Tools for Eclipse Lesson: Working with Development Objects 40 69 The Development Model in SAP S/4HANA Open SQL Lesson: Understanding Open SQL Lesson: Creating Database Tables Lesson: Reading Data from the Database Lesson: Preview: Core Data Services in SAP S/4HANA Unit 9: 158 161 © Copyright. All rights reserved. Object-Orientation in ABAP Lesson: A Short History of ABAP Lesson: Modeling a Class v 171 Unit 10: 172 179 183 189 192 198 Lesson: Creating Classes Lesson: Creating Objects Lesson: Calling Methods Lesson: Using Constructors Lesson: Using Factory Methods Unit 11: 199 216 221 Creating and Using Classes Using Inheritance Lesson: Inheritance in ABAP Lesson: Special Features of Inheritance Unit 12: 222 © Copyright. All rights reserved. Using Interfaces Lesson: Using Interfaces vi Course Overview TARGET AUDIENCE This course is intended for the following audiences: ● Development Consultant ● Technology Consultant ● Developer IT Adminstrator IT Support ● Developer ● Development Consultant ● Technology Consultant © Copyright. All rights reserved. vii © Copyright. All rights reserved. viii UNIT 1 The Development Model in SAP S/4HANA Lesson 1 The Development Model in SAP S/4HANA 2 UNIT OBJECTIVES ● Understand the Development Model in SAP S/4HANA © Copyright. All rights reserved. 1 Unit 1 Lesson 1 The Development Model in SAP S/4HANA LESSON OBJECTIVES After completing this lesson, you will be able to: ● Understand the Development Model in SAP S/4HANA The Programming Model Figure 1: Evolution of ERP SAP S/4HANA is SAP's new suite of business software, in which the letter 'S' stands for both Suite and Simple. Throughout the history of SAP software, systems and processes became more and more complicated, and the way in which users interacted with the software was always oriented more towards highly-specialized power users than to occasional users. SAP therefore recently decided to present a new product, simplified both in its implementation and in its user experience. At the same time, SAP S/4HANA has retained the programming language – ABAP – that it used in R/2 and R/3. © Copyright. All rights reserved. 2 Lesson: The Development Model in SAP S/4HANA Figure 2: SAP S/4HANA Simplicity From an IT value perspective, SAP S/4HANA creates unique opportunities to dramatically simplify the landscape and reduce TCO with SAP HANA as the great simplifier. Business users can leverage a simple and role-based user experience based on modern design principles, minimizing training efforts while increasing productivity. Guided configurations ease creating settings in the areas of system administration up to application customizing. Enterprises can now significantly reduce their data footprint and work with larger data sets in one system to save hardware costs, operational costs, and time. Here are key facts on SAP S/4HANA: ● Faster analytics and reporting ● Less process steps ● ERP, CRM, SRM,SCM, PLM co-deployed ● All data: social, text, geo, graph, processing ● No locking, parallelism ● Actual data (25%) and historical (75%) ● Smaller total data footprint ● SAP Fiori UX for any device © Copyright. All rights reserved. 3 Unit 1: The Development Model in SAP S/4HANA Figure 3: From SAP HANA to SAP S/4HANA SAP S/4HANA is the next-generation business suite from SAP powered by the SAP HANA platform. This in-memory database, combined with platform features like real-time analytics and the ability to process geospatial data provides faster, more powerful data processing and has been the catalyst that has enabled much of the simplification that you will find in SAP S/ 4HANA. Figure 4: Systems as a Black Box When an end user interacts with a software system, we say that, to them, it is a "black box". This means that they make input into the system, and results come out, but they have no access to or knowledge of the internal workings of the system itself. The vast majority of desktop and mobile applications are black boxes – we can use them, but we cannot configure, manipulate, or program them. © Copyright. All rights reserved. 4 Lesson: The Development Model in SAP S/4HANA Figure 5: Systems as a White Box To a programmer, a system is a white box (or sometimes called a glass box). They are responsible for all of the programming activities from start to finish, which typically means implementing a user interface layer, an application logic layer, and a database layer. The advantage of this is, of course, that the developer has full control over the behavior of the system. However, it is inefficient inasmuch as there are many repetitive tasks that he or she must perform. The user interface layer always involves visualizing data from the application layer, often in very similar ways. After all, the greater the similarity between different screens in the system, the greater the familiarity will be to the end user, and familiarity in turn promotes productivity. Database programming is also repetitive, as programmers spend a lot of time on four key operations, namely reading data from the database, creating new records, and updating or deleting existing ones. Figure 6: Programming with Frameworks and APIs © Copyright. All rights reserved. 5 Unit 1: The Development Model in SAP S/4HANA A modern and complex software system, such as SAP S/4HANA, has a programming model that is somewhere in between the black box and the white box approach. Clearly, programmers need to be able to implement their own applications and extensions to existing features, but at the same time, they should not have to spend too much time on all of the repetitive tasks. The way to approach this is for a system to provide frameworks. A framework is a subsystem within the overall software system that takes on a particular task by generating and processing code for a particular function. However, a framework can only do this in a very generic way, as it cannot guess what particular details a specific application will need. Consequently, while a framework is doing its job, it will very often provide a phase of the operation in which you can write your own code to complement the generated code and complete the task according to your own specifications. In order to access the information that the framework is processing, there is almost always an application programming interface (API) which is a set of functions that you can use to find out the current state of the application and to influence what the framework does next. The advantage of frameworks and APIs is that the system can provide a generic solution for the parts of a process that are always the same, which leaves programmers free to concentrate on the best way to solve their own individual problems. Figure 7: Tasks for an ABAP Developer In SAP S/4HANA, SAP has adopted the model of framework-supported development. Unlike the classic SAP Business Suite, in which ABAP programmers had to deal with every aspect of an application, many parts of an application can now be implemented without explicitly using ABAP code. The user interface layer of SAP S/4HANA is primarily implemented using SAPUI5. Data is exchanged using SAP Gateway and the OData protocol. SAPUI5 is a framework that can be manipulated and extended using JavaScript. Therefore, ABAP does not play a role in this particular area. However, the user interface of an application in SAP S/4HANA may also be implemented using conventional screen or Web Dynpro technology in the case of applications that have been adopted from the SAP Business Suite and not reimplemented using SAPUI5. These applications could be SAP standard applications, but could also be your own custom © Copyright. All rights reserved. 6 Lesson: The Development Model in SAP S/4HANA developments from a previously used Business Suite system. Web Dynpro and conventional screens both use ABAP in their implementations. The database layer of a new SAP S/4HANA application will use Core Data Services to define the data model and the Business Object Processing Framework (BOPF) to process changes to data in the database. This is the approach that you should take when designing new applications, but you should also be aware that existing applications that have not been redesigned and reimplemented will use an all-ABAP approach to the database layer. The application layer in SAP S/4HANA is used to perform calculations and validations on data that has either been read from the database or input into the system. Here ABAP still plays a strong role, and the relevant frameworks will normally provide a point at which you can implement your own code. Figure 8: ABAP Programming in This Class The emphasis of this class is entirely on ABAP programming. ABAP programming in the new SAP S/4HANA model has two major drawbacks for beginners; firstly, the ABAP code that you write is encapsulated in routines that are called automatically by different frameworks. Consequently, it is not possible to write meaningful code without understanding how these frameworks work. Secondly, the user interface layer of the programming model does not use ABAP techniques at all. To help you to focus on developing your ABAP skills, you will be writing programs using the ABAP Development Tools for Eclipse that run on the application server. Instead of using the Fiori Launchpad, you will start them directly from the development environment. User input and output is handled by routines that we have provided – all you need to do is to follow the instructions to call them from your programs. Once you have mastered enough ABAP, you can go on to learn the user interface side of things. Equally, it is possible that other teams or team members will be responsible for front-end development while you and your colleagues concentrate on developing back-end business logic. Much of what you learn will involve processing data locally within a program. However, you will also learn about Open SQL, ABAP's set of commands for communicating with the database, to allow you to read the contents of database tables. © Copyright. All rights reserved. 7 Unit 1: The Development Model in SAP S/4HANA LESSON SUMMARY You should now be able to: ● Understand the Development Model in SAP S/4HANA © Copyright. All rights reserved. 8 UNIT 2 The ABAP Development Environment Lesson 1 ABAP Development Tools for Eclipse 10 Lesson 2 Working with Development Objects 21 UNIT OBJECTIVES ● Use the ABAP Development Tools in Eclipse ● Understand software logistics in ABAP ● Create a simple ABAP program © Copyright. All rights reserved. 9 Unit 2 Lesson 1 ABAP Development Tools for Eclipse LESSON OBJECTIVES After completing this lesson, you will be able to: ● Use the ABAP Development Tools in Eclipse ABAP Development Tools In Eclipse Figure 9: ABAP Development Tools in Eclipse (ADT) In the past, SAP had its own SAPGUI-based development environment, the ABAP Workbench. As well as providing integrated access to all ABAP development objects, it was particularly valued by developers for features such as versioning and the where-used list, which shows exactly where a particular object has been reused by other objects. As time moved on, SAP needed to provide development environments for products and tools that were not SAPGUI-based, such as the SAP NetWeaver Developer Studio for Java development, the MaxDB administration console, or the SAP HANA Studio. These all use the popular cross-platform environment Eclipse. Eclipse is a development environment, originally conceived for Java, that is extensible and can support development for any platform. Eclipse itself is a framework for which vendors including SAP - can provide plug-ins that support development in a given language. Despite the fact that ABAP already had the SAPGUI-based ABAP Workbench, SAP decided to produce the ABAP Development Tools for Eclipse in recognition of the fact that an SAP development project today may reach beyond pure ABAP into the HANA or SAP UI5 space. © Copyright. All rights reserved. 10 Lesson: ABAP Development Tools for Eclipse Developers then need to access artefacts from the SAP HANA, SAP UI5 and ABAP spaces, preferably from within the same tool. Eclipse provides this common ground, and ABAP developers have the choice between working with the ABAP Development Tools for Eclipse (ADT) and the classic SAPGUI-based ABAP Workbench. In this course, you will be working with ADT. Note that, although the functions and features of ADT and the ABAP Workbench are similar, they are not identical. In particular, there are some kinds of ABAP development objects that can only be edited in ADT. In the S/4HANA environment, this applies particularly to Core Data Services views. Figure 10: Perspectives and Views The Eclipse application is a framework within which you can perform many very different tasks. Software vendors extend the framework by providing plug-ins for different programming languages. Consequently, you can program in Java, C, C++, PHP, JavaScript and, of course, ABAP - all from the same application. However, because different languages and platforms have different requirements, you will use different toolsets within the same Eclipse window. Each of these toolsets is called a perspective and a complete programming environment usually comprises several perspectives - one for normal development, one for debugging, and probably further perspectives for special tasks. A perspective fills the entire Eclipse window and enables you to perform a particular task, such as ABAP development. The different component tools that make up the perspective are called views. The main view is normally a source code editor, but there will also be further views showing the structural outline of a program, errors from the program check, and so on. © Copyright. All rights reserved. 11 Unit 2: The ABAP Development Environment Figure 11: Creating an ABAP Project In order to work in your system, you must first create an ABAP Project in ADT. The project corresponds to logging onto the backend system. You can only work with objects when you are actually logged on. When you create an ABAP Project, you normally choose an entry from SAPLogon. However, you could also specify the connection details for a system individually. When you create the project, you log on using your user and password for the backend system. You must also specify a logon language. This is not the language of the ADT user interface, which is always English, but the original language that your development objects will have in the backend system. Increasingly, companies are using English as their original development language, although this is by no means mandatory. Closing Eclipse simultaneously logs you off from the system. When you re-open Eclipse, you must log back on. The simplest way to do this is to double-click the project in the Project Explorer. © Copyright. All rights reserved. 12 Lesson: ABAP Development Tools for Eclipse Figure 12: Eclipse and SAPGUI Editors ABAP requires a lot of different editors for all kinds of different objects. Some have a state-ofthe-art implementation in Eclipse. This is particularly the case for heavily-used source-code based tool such as the ABAP Editor for ABAP programs and the Class Builder for creating classes. Other tools, which may be heavily form-based instead of source-code based or that are considered legacy tools do not have an Eclipse implementation. Instead, when you open an object that requires one of these tools, the classic SAPGUI user interfaces appears. However, the object still appears in-place in the Eclipse perspective and is fully-integrated into the navigation of your session. As time goes on, you will find that more and more SAPGUI-based editors - although not all of them - are being replaced with Eclipse-based ones. © Copyright. All rights reserved. 13 Unit 2: The ABAP Development Environment Figure 13: Opening Objects Using the Project Explorer There are different ways to open objects in the ABAP Development Tools workbench. One way is to access them through their package. Every development object in the SAP system belongs to a package, which is a container for objects that logically belong together. In an ABAP project, you can add packages that you use frequently to your favorites list, and you can then browse them in the project explorer. Double-clicking an object opens it in the editor area. Each new object that you open is displayed in its own new tab. Figure 14: Object Search © Copyright. All rights reserved. 14 Lesson: ABAP Development Tools for Eclipse If you do not know the package of an object, you can use the search function. Press Ctrl + H in ADT to open the search dialog. You can then look for objects that fit a particular pattern. You can restrict the search area as follows: ● Project: The system searches the current project, which is the current system. ● Workspace: The system searches all projects in the workspace. This means that the search area covers multiple systems if you have projects in your workspace that log onto different systems. You can also restrict the search to just your favorite packages. Figure 15: Open Object Dialog If you know the name of an object, or a part of its name, you can also use the Open Object dialog. To do this, press Ctrl + Shift + A and then enter a part of the object name in the filter field. Here, you can also restrict the search to particular object types. To restrict the object type, enter type: after your search string, followed by the kind of object that you are looking for. Common types are: prog: Program devc: Package tabl: Database table clas: Class For a full list of object types, you can enter type: in the filter field and then press Ctrl + Space. This opens a dropdown list of all types. © Copyright. All rights reserved. 15 Unit 2: The ABAP Development Environment Figure 16: First-Aid for ADT When you begin to work with ADT, there are a few things that can seem unusual or go slightly wrong. The first is the number of tabs that opens. Every time you navigate to a new development object, ADT displays it in a new tab. The consequence of this is that, very soon, you can lose track of where you are. In the figure, there are seven visible tabs, with another eight open, but not visible in the toolbar. To close all open tabs in one go, use the keyboard combination Ctrl + Shift + W. If there is unsaved content in any of the tabs, ADT prompts you to save your work. Another problem that can occur in ADT is that you might close an important view by mistake. For example, in the figure above, the Project Explorer has disappeared. To fix this problem, you can reset any perspective in Eclipse to a predefined arrangement of views. To do this, Choose Window → Perspective → Reset Perspective from the menu and confirm the security prompt. © Copyright. All rights reserved. 16 Lesson: ABAP Development Tools for Eclipse Using SAP GUI Transactions in ADT Figure 17: Using SAP GUI Transactions in Eclipse There are certain tools that you will need to use during a development project but that do not have an equivalent implementation in Eclipse. This is often the case when you need to use a transaction from the area of system administration to check what is happening behind the scenes when you run a program. In order to avoid having to log onto the SAP system using SAP GUI as well as ADT, you can use the keyboard shortcut Ctrl + 6 to open a new SAP GUI window in-place in ADT. When you do this, you must specify the ABAP project to which the window should apply. ADT then opens a SAP GUI window with the system, client, user, and logon language of the ABAP project. In this window, you work normally as if you had logged onto the system using SAP GUI. You can enter transaction codes in the command field. Note that to access the menu of the SAP GUI window, you must click the Menu button to the left of the command field. © Copyright. All rights reserved. 17 Unit 2: The ABAP Development Environment Figure 18: The Repository Information System One of the SAP GUI transactions that you will probably use when you are working with ADT is the Repository Information System. This is a tool that allows you to search for different kinds of development objects according to various criteria. Since there are over 4 million different development objects in an SAP S/4HANA system, this is a very useful tool! To start the Repository Information System, open a SAP GUI window in ADT (Ctrl+6) and enter transaction code SE84. In the tree on the left-hand side of the screen, double-click on the type of object for which you want to search. In this example, we are looking for a function module. Function modules are useful in ABAP development as they provide a particular function (such as a calculation or reading data from the database) in re-usable form. This means that every other program in the system can use the function module instead of having to reproduce the corresponding code themselves. This example assumes that we are writing a program in which we need to know on which day of the week a particular date falls. To do this, we have to guess what the function module might be called. Using wildcards (the * characters) we can search for function modules whose names contain the words DATE and DAY (bear in mind that the names of function modules are generally English). You will find out more about function modules later in the course. © Copyright. All rights reserved. 18 Lesson: ABAP Development Tools for Eclipse Figure 19: Restricting The Search Area As there are so many objects in the system, you will often want to restrict your search to a particular area. SAP systems are divided into application components, each of which covers a broad area of the system such as Controlling, Financial Accounting, Sales and Distribution, and so on. Since each of these areas is itself still very large, they are divided into subcomponents. In the example above, you can see CO for controlling, CO-PA underneath it as the subcomponent for profitability analysis, and two further levels of subdivision below that. Each development object in the system is ultimately assigned to one of these components. If you want to search a particular application component, enter its name in the Application Component field. If you want to search a larger area – perhaps the entire area CO-PA, enter CO-PA* in the Application Component field. This will search every application component whose name begins with CO-PA. © Copyright. All rights reserved. 19 Unit 2: The ABAP Development Environment Figure 20: The Hit List When you execute the search in the Repository Information System, the system produces a hit list of objects that meet the selection criteria. This list is often extensive, but still a greatly reduced set of objects compared with the total number in the system (here there are 28 function modules in the hit list from a total of over 400,000 in the system as a whole). To examine the definition of one of the objects from the list, double-click it in the list. Note that if the object type has an Eclipse-based editor, the system will use it even though you are working in a SAP GUI window. This would be the case here with function modules. LESSON SUMMARY You should now be able to: ● Use the ABAP Development Tools in Eclipse © Copyright. All rights reserved. 20 Unit 2 Lesson 2 Working with Development Objects LESSON OBJECTIVES After completing this lesson, you will be able to: ● Understand software logistics in ABAP ● Create a simple ABAP program Working with Packages and Change Requests Figure 21: Working with Objects – The System Landscape Your SAP system landscape consists of more than one system. Your business operations are conducted in the production system. However, this system must only ever be used to process live business data, which means that testing or development of new programs are strictly forbidden. For this reason, you will have at least one more system for development, but probably more than that. The classic SAP system landscape consists of a development system, where development can take place without disturbing (or being disturbed by) other activities. Your finished programs will, of course, be required in the production system, but it is customary and good practice to test them in a dedicated test system first. Following a successful test, they can then be transferred into the production system and put into active use. In theory, it is possible to do without a test system and perform tests in the development system. However, this does not provide a particularly stable testing environment. Equally, it is possible to have a system landscape that contains a stable and regulated validation or © Copyright. All rights reserved. 21 Unit 2: The ABAP Development Environment preproduction system after the test stage. This is often found in highly regulated industries such as the manufacture of medicines or medical equipment. In order to move objects between systems in an orderly fashion, SAP systems are connected using the Change and Transport System. Configuring this system is a job for the system administrators, but as an ABAP developer, you will come into daily contact with it whenever you create or modify a program or other development objects. In order to transport objects between systems, you must assign each object that you create to a package and a change request. Figure 22: Packages in the ABAP Project Packages in an SAP system have two major functions. The first, in common with packages in other programming environments or folders in operating systems, is to group together objects that are logically related. For example, all of the sample programs for this class are grouped together in a package DEVS4D400. The second function of a package is to determine how the objects that belong to it will be transported into other systems. This is determined by the transport layer. The transport layer is like a route map that describes which systems will receive the objects once they are ready. Transport layers are configured by the system administrators. When you create a new package, you merely select one of the predefined layers. © Copyright. All rights reserved. 22 Lesson: Working with Development Objects Figure 23: Adding an Existing Package to Your Favorites If you need to look regularly at the objects in a particular package, you can add it to your favorites list in ADT. To do this, right-click the Favorite Packages node in the Project Explorer and choose Add a Package… Enter the beginning of the name of the package that you want to find. ADT filters the results as you type. Once you can see the package in the list, double-click it or select it and choose OK. ADT adds the package to your favorites list. If you now expand the package name, you can see all of the development objects that belong to it. To open an object, double-click it. Figure 24: Working with Objects – Packages Within a system, you have access to all of the objects delivered by SAP. This means that you can reuse them in your own applications or just look to see how a particular program works. © Copyright. All rights reserved. 23 Unit 2: The ABAP Development Environment You should not, however, make changes to SAP programs, as these changes have to be reconciled with new versions of these objects that might be shipped by SAP later. This principle also applies to packages – if you want to create a new program of your own, you must assign it to a package of your own, and all customer-specific objects must reside in the customer namespace. To create an object in the customer namespace, you simply use Z or Y as the first letter of the object's name. SAP developers are not allowed to ship objects whose names begin with these letters, and so we have a simple but effective way of avoiding naming collisions. Figure 25: Working with Objects – Change Requests When you create a new ABAP program, it exists in the development system but not in your test or production system. In order to ensure that the program reaches these systems, you must assign it to a change request. This is a compulsory step in creating the object. Change requests are subdivided into tasks. A task gives one developer the right to assign his or her objects to the change request. If you are working as a team on a particular project, you should create one change request with a separate task for each developer. This ensures that everyone's objects are transported together at the appropriate time. You can assign any number of objects to a change request. In the development phase of a project, you may end up with hundreds of objects in a single request. Later on, in the maintenance phase, you may need to make a quick correction to a single object. You would then have a much smaller request containing just that object. Once you have completed and tested the program, you release the change request. This is a signal to the Change and Transport System that the request can be imported into the test system. This action creates the new programs in that system. Once you have tested the objects in the test system, you can again release the request, which makes the objects available for import into the production system. Now your end users can use your program. © Copyright. All rights reserved. 24 Lesson: Working with Development Objects Figure 26: Changing Objects Now let us look at what happens to an ABAP program that has already been released and transported. Let us suppose that you need to add a new feature to the program. You do this in the development system. Now you have a new version of the program in the development system, but the old version in the test and production systems. Luckily, the Change and Transport System will not allow this to happen: As soon as you make a change to an existing program, you must assign the object to a change request. This ensures that your changes to the program will be logged and transported into the test and production systems. Figure 27: Lifecycle of an Object The lifecycle of an object therefore looks like this. When you create a new object, you must assign it to a package. Although it is technically possible to reassign it to a different package © Copyright. All rights reserved. 25 Unit 2: The ABAP Development Environment later, you will not often do this in practice. Once you have saved the new object, there will never be a moment in its lifetime in which it is not assigned to a package. You must also assign the object to a change request to ensure that your changes are transported into the correct systems. Once you have completed and tested your objects, you release the change request to trigger the transport into the next system. When you next change the object, you must assign it to a new request. Thus an object may belong to many change requests during its lifetime, and there will also be periods during which it is not assigned to a request. Creating an ABAP Program Figure 28: Creating an ABAP Program Once you have created a package in the customer namespace – one whose name begins with Z or Y – you can go on to create your first program. The easiest way to do this is to right-click the package name in the Package Explorer and choose New → ABAP Program . You may also use the keyboard shortcut Ctrl + Shift + N, which opens the Create ABAP Repository Object dialog box. If you do this, enter Program in the field marked Type Filter Text . You can then select ABAP Program from the resulting list. In the dialog box that follows, check that the suggested project and package are correct, and change them if they are not. The name of the program must begin with Z or Y. After that, it may contain the letters A-Z, the digits 0-9, and the underscore characters. Accents, umlauts, and any other special characters are not allowed. ABAP does not distinguish between upper and lower case in program names. Regardless of how you enter the name, the system converts all letters to upper case. Once you have entered the name and description of the program, choose Continue . You must now choose a change request for your program. The dialog box shows a list of all change requests in which you are already involved. Normally you would choose one of these requests. However, if there is not a suitable request in the list, you can create one at this point. © Copyright. All rights reserved. 26 Lesson: Working with Development Objects Figure 29: The Keyboard Shortcut Ctrl + Shift + N The keyboard shortcut Ctrl+Shift+N is very useful, as it opens a dialog box from which you can create any ABAP development object. When the dialog box appears, you must first check that the object will be created in the correct project (check the Project field and change it if necessary using the Browse button). You can then expand the tree to find the kind of object that you want to create and double-click it to continue. However, you can also start typing the name of the kind of object you want to create into the filter field as shown above; once you have typed the letters prog into the field, the filter only shows the object type ABAP Program. Once you are familiar with the different object types that you need regularly, this is a very quick means of navigation. Figure 30: The ABAP Editor Once you have created your program, it will appear in the ABAP Editor. Each ABAP development object that you open is displayed in its own tab in the Editor area. © Copyright. All rights reserved. 27 Unit 2: The ABAP Development Environment By default, the ABAP Editor should appear as displayed in the figure, The ABAP Editor. However, since users can customize the display (see the figure, Customizing the Editor Experience), it may look slightly different. A new ABAP program contains a generated statement REPORT <program_name>. This is a marker that indicates the beginning of the program. You may not place any other ABAP statements before it. The text in the illustration that does appear before REPORT is a block of comment lines. Comments are notes for humans inside program code – the system ignores them, but we can use them to remind ourselves what the program does at a particular point. There are two ways to write a comment in ABAP: The first is to use the * character at the very beginning of the line. Then, the entire line is marked as a comment. The second way is to use the ″ character anywhere in a line. The system then marks the rest of the line from this point onwards as a comment. Figure 31: Customizing the Editor Appearance Eclipse allows developers a lot of flexibility to customize the appearance of its various perspectives and views and in this respect, ADT is no exception. As with other tools, you can find many settings by choosing Window → Preferences . This opens a dialog box with a lot of different settings; you will find the relevant ones under General and ABAP Development. Remember that you can use the Type Filter Text input field to help you to locate a particular setting. Some settings – particularly the settings for automatic code formatting and advanced static code checks – are project-specific. This means that you must configure them for each project separately in the Project Properties. You can open this dialog box by right-clicking a project name and choosing Properties . Alternatively, place the cursor on the project name and press Alt + Enter. © Copyright. All rights reserved. 28 Lesson: Working with Development Objects Writing Simple ABAP Code Figure 32: The Simplest ABAP Method Call The simplest thing you can do in ABAP is to call an existing piece of code that someone else has written. There are various ways of doing this, depending on how the code was written in the first place, but here we show you how to call a method. A method is a function, and it always belongs to a class. To call the method, you must specify both the name of the class and the name of the method. This is because there may be more than one class with a method with that particular name. You join the name of the class and the name of the method together using the component selector, which is an arrow made up of the equals sign followed by the greater than sign. A method call always concludes with parentheses. The opening parenthesis joins onto the method name with no space. Inside the parentheses, there must always be at least one space. Normally you would specify the parameters of the method in the parentheses. This means passing values to the method that it needs to perform its function and receiving results back from it. The method in the example has no parameters, so the parentheses remain empty. This may be uncommon, but it is also not unusual. At the end of every ABAP statement (the name for a single instruction in ABAP), there is always a period. All of the methods of the class cl_s4d_output are static methods. Later on, you will learn about instance methods, how they differ from static methods, and how to use them. © Copyright. All rights reserved. 29 Unit 2: The ABAP Development Environment Figure 33: Useful Editor Functions for Method Calls To find out more about the method that you want to call, place the cursor anywhere in the method name. You can then choose one of the following functions: Press F2 to open the method documentation in a popup window in the Editor. This is useful if you just want a quick look at the method definition. As soon as you click outside the popup window, it disappears again. Press Alt + F2 to open the method documentation in a separate tab below the Editor. The same documentation appears, but does not disappear again until you close the tab yourself. If you position the cursor on a different method name, the display changes to the documentation of that method. Press F3 to open the source code of the method. This opens the corresponding class in a new tab in the Editor area so that you can examine how it is implemented. Note that you can do this not only for your own code, but also for all SAP source code as well. To return to your own program, click the corresponding tab or use the Alt + Left Arrow key combination to go backwards along your navigation path. Whenever you navigate to the definition of an object using the F3 key, ADT opens a new tab. These tabs do not close automatically when you leave them. Consequently, you can end up with lots of tabs open, which can be confusing. To close all open tabs in one go, use the key combination Ctrl + Shift + W. If any tabs contain unsaved changes, ADT will prompt you to save them first. © Copyright. All rights reserved. 30 Lesson: Working with Development Objects Figure 34: Testing a Program In order to test your program, you must first activate it. This creates a version of the program that the ABAP runtime system can understand. To activate the program, use the lighted match icon or the keyboard shortcut Ctrl + F3. You can only do this if your program is correct. The next section shows you what to do if there are errors. To run the program, use the Run icon or press F8. This starts a SAPGUI window in a new tab in ADT. The methods of class cl_s4d_output display various kinds of output in a dialog box. To close the dialog box, use the Close button in the top right-hand corner. Note that the SAPGUI window that opened automatically when you ran the program remains open even once you have finished. You will need to close this tab by hand (or use the keyboard shortcut Ctrl + Shift + W to close all open tabs). Figure 35: Correcting Errors If there are errors in your program, you will not be able to activate it. ADT signals errors in your code by placing a white cross on a red background at the beginning of the line containing © Copyright. All rights reserved. 31 Unit 2: The ABAP Development Environment the error. Each error is described in the Problems tab, which appears below the Editor pane. Equally, if you position the mouse over the error icon in the Editor, the same message will pop up. In ADT, you can decide how the Editor should handle errors. By default, errors are signaled automatically. This is helpful, but also has the disadvantage that the error symbol appears even when you are typing a correct statement just because you haven't typed the period at the end yet. If you find this annoying, you can tell the Editor not to display errors automatically. In this case, you must choose the Check function yourself in order to display any errors that you have made. To switch off the automatic error display, choose Window → Preferences , followed by ABAP Development → Editors → Source Code Editors . Now deselect the option Automatic syntax check on all open ABAP source editors. Figure 36: Using Code Completion A useful tool in ADT is the code completion utility. If you enter the beginning of the name of a class and press Ctrl +Space, ADT shows a list of all classes whose names begin with that sequence of characters. After the component selector, you can do the same to see a list of methods. Once you have highlighted the method that you want to call, press Shift + Enter. Instead of entering just the name of the method in your source code, this key combination inserts the method name and the full signature, that is, all of the – as parameters – that you can exchange with the method. © Copyright. All rights reserved. 32 Lesson: Working with Development Objects Figure 37: Calling a Method with an Importing Parameter In this example, the method that we call has a parameter called iv_text. The first code snippet in the figure shows the result of the code completion. However, we must also pass a value to iv_text to tell the method what text should be displayed. The second code snippet shows how we can do that to make the method display the text Hello World. The vertical pipe characters | denote the beginning and end of a string template. In their simplest form (as here) string templates just contain a static string of characters. However, as you will see later, they are actually very powerful and can contain variables and embedded functions as well. Figure 38: Method Signature Here we have a further example for a method. Its task is to work out on which day of the week a particular date falls. In order to do this, it needs the calling program to tell it which date is required. This information is passed to the method, so the method regards it as an importing parameter. © Copyright. All rights reserved. 33 Unit 2: The ABAP Development Environment The method also provides a result, namely the day of the week on which the specified date falls. This information comes from the method and is given to the calling program. Consequently, the method regards it as an exporting parameter. Now, look at the method call on the left-hand side of the figure. From the point of view of the program, a piece of information that is passed to the method is an exporting value, while results, which are exported from the method, are imported into the program. Note that you can leave out the word EXPORTING in the method call if there are no other kinds of parameters involved. This is exactly what happened in the previous figure. LESSON SUMMARY You should now be able to: ● Understand software logistics in ABAP ● Create a simple ABAP program © Copyright. All rights reserved. 34 Unit 2 Learning Assessment 1. In order to log onto an SAP system using ABAP Development Tools for Eclipse, you must first create a corresponding entry in the SAP Logon. Determine whether this statement is true or false. X True X False 2. Which of the following details must you supply to log onto an SAP system using ADT? Choose the correct answers. X A Client X B User X C Password X D Package 3. Which of the following are characteristics of a package in the ABAP Workbench? Choose the correct answers. X A Packages group logically-related objects. X B All of the objects in a package have the same original language X C Packages determine how the objects contained in them will be transported X D Objects in a package can only be used by other objects from the same package. © Copyright. All rights reserved. 35 Unit 2: Learning Assessment 4. Which of the following statements about development objects is correct? Choose the correct answer. X A A development object is always assigned to exactly one package at any one time. All of the changes during its lifetime are assigned to the same change request. X B A development object may be assigned to more than one package at any one time. All of the changes during its lifetime are assigned to the same change request. X C A development object is always assigned to exactly one package at any one time. Changes to the object at different times are assigned to different change requests. X D A development object may be assigned to more than one package at any one time. Changes to the object at different times are assigned to different change requests. © Copyright. All rights reserved. 36 Unit 2 Learning Assessment - Answers 1. In order to log onto an SAP system using ABAP Development Tools for Eclipse, you must first create a corresponding entry in the SAP Logon. Determine whether this statement is true or false. X True X False That is correct. You can use an SAP Logon entry to connect to a system, but you may also enter the details manually. 2. Which of the following details must you supply to log onto an SAP system using ADT? Choose the correct answers. X A Client X B User X C Password X D Package 3. Which of the following are characteristics of a package in the ABAP Workbench? Choose the correct answers. X A Packages group logically-related objects. X B All of the objects in a package have the same original language X C Packages determine how the objects contained in them will be transported X D Objects in a package can only be used by other objects from the same package. © Copyright. All rights reserved. 37 Unit 2: Learning Assessment - Answers 4. Which of the following statements about development objects is correct? Choose the correct answer. X A A development object is always assigned to exactly one package at any one time. All of the changes during its lifetime are assigned to the same change request. X B A development object may be assigned to more than one package at any one time. All of the changes during its lifetime are assigned to the same change request. X C A development object is always assigned to exactly one package at any one time. Changes to the object at different times are assigned to different change requests. X D A development object may be assigned to more than one package at any one time. Changes to the object at different times are assigned to different change requests. © Copyright. All rights reserved. 38 UNIT 3 Working with Variables in ABAP Lesson 1 Working with Variables 40 UNIT OBJECTIVES ● Declare appropriately typed variables in ABAP ● Work with variables in ABAP ● Work with non-variable data objects © Copyright. All rights reserved. 39 Unit 3 Lesson 1 Working with Variables LESSON OBJECTIVES After completing this lesson, you will be able to: ● Declare appropriately typed variables in ABAP ● Work with variables in ABAP ● Work with non-variable data objects Declaring Variables Figure 39: Declaring Variables A variable in an ABAP program is a reserved section of the program memory. It has a given size and type, which determine how much information can be stored in it and what kinds of information are allowed. It also has a name that allows you to store information in it and retrieve information from it during the program. The name of a variable may be up to 30 characters long. It may contain the characters A-Z, the digits 0-9, and the underscore character. The name must begin with a letter or an underscore. You can declare variables at the beginning of a program. These are called global variables, because they are then available throughout the program. This is, however, not always good style, and later on you will learn about other ways of declaring variables. The ABAP programming guidelines recommend that you prefix the names of global variables with the letter g to make them easily recognizable in your program. © Copyright. All rights reserved. 40 Lesson: Working with Variables Depending on the type that you choose, you may also need to specify the length of the variable and, for some numeric types, the number of decimal places, explicitly. Figure 40: Sources of ABAP Types You can specify the type of a variable in different ways: ● ABAP has a set of 13 predefined simple types. ● If you want to define a specific type and reuse it in different places in the same program, you can create a type definition within a program. ● If you want to define a specific type and reuse it in multiple programs, you could define it in a global class or a global interface. These kinds of type definitions are purely technical – they consist of a type, a length, and a number of decimal places. However, in an SAP System you often need a complete definition of the type of a particular business entity – for example, a material number. As with any other type, this has a type and a particular length. However, in addition, these entities also have a semantic definition, including: ● Field labels that appear on the user interface ● A mechanism for displaying possible input values to the user ● A mechanism for validating entries These types are defined as Data Elements within the ABAP Dictionary. © Copyright. All rights reserved. 41 Unit 3: Working with Variables in ABAP Figure 41: Predefined Complete ABAP Types The table shows a list of the predefined complete ABAP types. These types are known as complete because you cannot override their set length of number of decimal places. The types I and INT8 are for whole numbers. As a rule, you should use type I, but if you need integers outside of its value range, you can use INT8. The types DECFLOAT16 and DECFLOAT34 are decimal floating point numbers. You should use them when you need an extremely large value range or very high precision (16 or 34 decimal places respectively). For normal business logic, you should use type P (see the following section). Type D represents a date. In ABAP, the date always has the format YYYYMMDD (without separators). The system converts this format according to the current locale before the value is displayed on the user interface. Likewise, when the user enters a date, the system converts it into the ABAP format before you start to process it. Type T represents the time. In ABAP, this has the format HHMMSS (without separators in 24 hour format). If the current locale uses 12 hour format, the system converts the values automatically. Type STRING is a character string of variable length. The ABAP runtime system allocates and releases memory to optimize the management of string variables. You cannot influence this behavior directly. Type XSTRING is similar, but is a byte string instead of a character string. The maximum length of a string is governed by settings that the system administrator makes. However, in practice, we talk about strings being unlimited in length. © Copyright. All rights reserved. 42 Lesson: Working with Variables Figure 42: Predefined Incomplete ABAP Types The types listed above are incomplete types. This means that you can specify the length as part of the declaration. In the case of type P, you may also specify a number of decimal places. Type C is a character field. You specify its length in characters; the runtime system then assigns double the number of bytes in order to accommodate the field. Type N is a numeric string. This is a sequence of digits that you do not want to regard as a number and perform calculations with. For example, this could be a personnel number or cost center. Type X contains a sequence of bytes. Type P is a packed number and is explained in more detail in the next figure. Note that in older coding you may still see the following syntax: DATA gv_char(5) type C. The number in parentheses is, in this case, the length of the variable. You may also see this: DATA gv_var. The variable seemingly has neither a type nor a length, but this is not allowed in ABAP. Variables without a type and length have the default type C and default length 1. These syntax variants are still allowed for compatibility reasons, but do not use them in your own code. © Copyright. All rights reserved. 43 Unit 3: Working with Variables in ABAP Figure 43: Packed Numbers in Detail Type P is a packed number. Packed numbers are known as such because each byte contains two digits. One half byte is required to store the information as to whether the number is positive or negative. Thus the length of a packed number is twice its length minus 1. A packed number that is 8 bytes long can contain up to 15 digits. Packed numbers may also have up to 14 decimal places. You specify these using the DECIMALS addition in the DATA statement. The statement DATA gv_number TYPE P LENGTH 3 DECIMALS 2. declares a packed number with 5 digits. Of these, two come after the decimal point. Consequently, the maximum value of this variable would be 999.99. The decimal separator in a packed number is always the period. If the current locale calls for a comma, the runtime system formats the variable automatically for the user interface. Figure 44: Types in the ABAP Dictionary – Data Elements © Copyright. All rights reserved. 44 Lesson: Working with Variables In an SAP system, there are thousands of business entities, such as country code, plant, material number, fiscal year, cost center, and so on. Technically, it would be possible to define these entities in every single program using the built-in ABAP types that you have just seen. However, this would be extremely labor-intensive and error-prone. Instead, SAP provides the ABAP Dictionary, which is a central store for important data types and also the tool that you use to create database tables. In the ABAP Dictionary, single business entities are described by data elements. Above, you can see the data element that describes an airline. The type is defined just once in the entire system, and every program or method parameter that needs the definition of an airline can use it. This ensures consistency throughout the system. Before you change one of these central objects, you must take care to find out what effect the changes will have on other objects and programs (and the effects will often be far-reaching). However, once you have decided that the change is necessary, you only need to alter one object and the change will be reflected in every other object in the system that uses it. An example of this is the lengthening of the material number type (MATNR) in SAP S/4HANA: In the classic Business Suite, material numbers were 18 characters long. In SAP S/4HANA, they are 40 characters long. Without centrally-defined data elements, SAP would not even have been able to consider making this change. Figure 45: Types in Classes As well as built-in types and ABAP Dictionary types, you will also find type definitions in classes. To find out if a class contains type definitions, use the Overview function (F2) or open the class definition and search for the TYPES keyword. To define a variable in a program with reference to a type from a class, use the syntax <class name>=><type name> as shown above. © Copyright. All rights reserved. 45 Unit 3: Working with Variables in ABAP Figure 46: Initial Values of Variables Every variable in ABAP has an initial value that depends on its type: ● The initial value of a numeric variable is always zero. ● The initial value of a character field is a string of spaces. ● The initial value of a string is a single space. ● The initial value of byte fields are analogous to character fields, but with the character Hex 00 instead of space. ● The initial values of types D, T, and N have the digit zero at every position. Figure 47: Which Numeric Type to Use? © Copyright. All rights reserved. 46 Lesson: Working with Variables Figure 48: ABAP Statements with Keywords The DATA statement is an example of an ABAP statement that uses a keyword. In ABAP, there is a set of reserved ABAP words that each have a particular function within the language. The ABAP words in the example above are DATA, TYPE, LENGTH, and DECIMALS. An ABAP word that is used at the beginning of a statement is called a keyword. ABAP words that occur later on in the statement are called additions. Additions may be either obligatory or optional. Sometimes, using one particular addition in a statement will mean that you cannot subsequently use certain other additions within the same statement. Not all ABAP statements use keywords. Often, you can use an expression instead. An expression is a combination of values, functions, and operators that are processed by the system and yield a particular result. You can assign this result directly to a variable, or reuse it in a larger, nested expression. There are, however, tasks that you can only perform using statements. Examples of these are declaring variables (using the DATA statement) and communicating with the database using Open SQL. © Copyright. All rights reserved. 47 Unit 3: Working with Variables in ABAP Figure 49: Using the ABAP Documentation ABAP has comprehensive documentation that you can access directly from the ABAP Editor. To do so, place the cursor on a keyword and press F1. ADT then displays the appropriate context-sensitive documentation. Figure 50: Chained Statements One of the syntactical features of ABAP is the way in which you can write chained statements. If you have more than one statement that begins in the same way, you can write the common opening part once only, followed by a colon. You then write the rest of each statement, with each part separated by a comma. The syntactical and runtime behavior of both variants is identical. If you want to write a chained statement, you must use a colon after the opening part of the statement. However, using a colon does not mean that you must then use a chained statement. So, for example, the following is syntactically correct: DATA: gv_var TYPE string. © Copyright. All rights reserved. 48 Lesson: Working with Variables Figure 51: Using Variables in Method Calls This example shows a method that has an exporting parameter. The documentation of the method shows that there is a parameter ev_text with type string. It is important to note here that the direction of the parameter depends on the point of view of the method or the caller. From the point of view of the method, ev_text is a value that is passed from the method to the caller and is therefore exported. The caller sees this the other way round – a value that is passed from the method to the program will be imported by the program. Hence the exporting parameters of the method correspond to importing parameters of the method call in the program. When you call the method, the system displays a dialog box in which you can enter your name. The text that the user enters is the export parameter of the method. Figure 52: Declaring a Variable for Use in a Method Call If you want to use the text returned by the method in your program, you must declare an appropriately typed variable. Since the export parameter of the method has type string, you must use the type string in your program as well. © Copyright. All rights reserved. 49 Unit 3: Working with Variables in ABAP Once you have assigned the method parameter to the variable, you can reuse it in the program – for example, by passing it to another method, as shown here. Assigning Values to Variables Figure 53: Initializing a Variable with a Set Value When you declare a variable it has the correct initial value for its data type. However, if you want a variable to have a different value when it is created, you can specify it in the DATA statement using the VALUE addition. In this example, gv_int2 has the value 12 instead of zero. Figure 54: Assigning a Value to a Variable You can assign a value to a variable using the expression <variable> = <value>. The value can be static – as in the example gv_Int1 = 10 – or you can specify the name of a variable whose value should be copied into the target variable. © Copyright. All rights reserved. 50 Lesson: Working with Variables Figure 55: Deleting the Contents of a Variable The CLEAR statement resets the contents of a variable to the initial value appropriate to its type. Note that the type is always reset to the initial value, even if you created the variable using VALUE and assigned it a different starting value. Figure 56: Simple Expressions The value of a variable can also be the result of an expression. An expression is a combination of values, operators, and functions that the runtime system processes to calculate a result. This example is a simple addition: The contents of gv_Int2 and gv_int3 are added together and the result placed in gv_int1. For basic arithmetic, ABAP provides the operators + for addition, - for subtraction, * for multiplication and / for division. In complex expressions involving more than one operator, multiplication and division take precedence over addition and subtraction. Expressions with identical precedence are processed from left to right. © Copyright. All rights reserved. 51 Unit 3: Working with Variables in ABAP Additionally, you can use the operators DIV for whole-number division and MOD for the wholenumber remainder of a division. Thus, 6 DIV 4 is 1, and 6 MOD 4 is 2. Figure 57: Built-In ABAP Functions ABAP has a range of built-in functions for various tasks. Many of these are used for string processing, but here you can see an example of a numeric function. You use the ipow function to raise a number to a whole-numbered power. The function has two arguments – base for the base number and exp for the exponent. The syntax for using these functions is similar to that of a method call – the function name is followed by parentheses, and after the opening parenthesis, you must type at least one space. Then follow the named arguments, to which you assign values using the notation argument = value. The result of the function is a value, which is then placed into the variable on the lefthand side of the expression. Using Control Structures in ABAP Figure 58: Conditional Branching with IF © Copyright. All rights reserved. 52 Lesson: Working with Variables Sometimes, you only want to process a certain section of your program under a certain condition. To do this, you use the IF statement. In its simplest form, you test a condition – here, for example, the variable gv_value must have the value 1 – and if the condition is true, the statements between IF and ENDIF are processed. If not, the system leaves them out and jumps to the statement following ENDIF. You can refine this behavior further by using the keyword ELSE. In the second example, the same condition is tested, and if it is true, the statements between IF and ELSE are processed. After this, the system jumps to ENDIF. However, if the condition is not true, the system jumps straight to ELSE and, instead, processed the statements between ELSE and ENDIF. Figure 59: Conditional Branching with IF and ELSEIF IF blocks can be complex. In this case, we test a first condition with IF. If the condition is true, then the statements directly following it are processed up to the next ELSEIF statement. After this, the system jumps to ENDIF. If the first condition is not true, the system jumps directly to the next ELSEIF statement. If this condition is true, the statements directly following it are processed until the next ELSEIF, ELSE or ENDIF statement. For as long as the conditions specified after IF and ELSEIF are not true, the system keeps jumping to the next condition and testing it. As soon as the system has processed one block within the structure, it jumps to ENDIF and does not process any further blocks. If there is an ELSE block, it must be the last block in the structure and it will be processed if no preceding condition was true. If there is no ELSE block, the system may exit the structure without having processed a single block. You can nest IF structures. This means that within an IF, ELSEIF, or ELSE block, you can have any number of further IF structures. Each inner structure must conclude with ENDIF before the block in which it is contained ends. © Copyright. All rights reserved. 53 Unit 3: Working with Variables in ABAP Figure 60: Logical Expressions in ABAP When you use IF conditions, you are not restricted to testing whether one value is equal to another. Instead, you can use logical expressions. A logical expression is a combination of operands and operators that the runtime system evaluates when the program is executed. The result is either true or false. In ABAP, you can use the common symbols for logical operators. There is also a set of abbreviations that you can use. These are: EQ - Equals NE - Not Equal LT - Less Than LE - Less Than or Equal GT - Greater Than GE - Greater or Equal A particularly useful expression is IS INITIAL. With it, you can test whether a variable has the initial value appropriate to its type. You can combine more than one logical expression using the expressions AND and OR. You can also invert a condition using NOT. In the last example on the illustration, the runtime system first checks that gv_value does not have an initial value. If the value is not initial, it goes on to check that gv_carrid has the value LH. If both expressions are true, then the whole expression is true. If the first expression that the system evaluates is not true, it does not process any further parts of the same expression. If you link expressions using OR then only one of the linked expressions must be true. However, all of the linked expressions may be true. ABAP does not contain an exclusive OR function. © Copyright. All rights reserved. 54 Lesson: Working with Variables Figure 61: Case Distinction in ABAP The CASE statement allows you to test the value of a variable quickly and efficiently for equality with another value. It thus replaces a long string of IF … ELSEIF statements. After CASE, you write the variable whose value you want to test. The first statement after CASE must always be WHEN. After WHEN comes a value. If the variable in the CASE statement has the value in the WHEN statement, the system processes the corresponding block. Similarly to IF, only one block can be processed in a CASE structure. You can provide a WHEN OTHERS block, which will be processed if none of the other values for which you tested match up. If you use a WHEN OTHERS block, it must be the last block in the structure. CASE only tests for equality. You cannot use AND or NOT with CASE. You may, however, group values together using OR, as shown in the figure above. © Copyright. All rights reserved. 55 Unit 3: Working with Variables in ABAP Figure 62: Loops in ABAP There are two kinds of loop in ABAP. A DO loop is repeated indefinitely. Since endless loops cause the program to hang, you must provide a way out of the loop. To do this, test an attainable exit condition, and if it is met, break out of the loop with the EXIT statement. EXIT terminates the loop processing and resumes the program after the ENDDO statement. If you know how many loop repetitions you need, you can specify the number in the statement DO n TIMES. n may be either a literal (as in the illustration above) or an integer variable containing the number of repetitions. The loop will then be repeated up to this number of times. (You can still exit the loop processing prematurely using the EXIT statement.) DO loops are always processed at least once (at least up to the point at which you test the exit condition). By contrast, ABAP also has WHILE loops. In this case, a logical condition is tested at the entry to the loop. If the condition is met, the loop is processed. If it is not met, the entire loop is skipped. After each repetition of the loop, the system tests the condition again. If the condition is met once again, the loop processing continues. This process is repeated until the condition is not met, when the loop processing terminates and the program resumes after the ENDWHILE statement. © Copyright. All rights reserved. 56 Lesson: Working with Variables Figure 63: System Variables System variables are a set of variables in ABAP that provide information about the current state of the system. They are managed by the runtime system and available to all programs at all times. You do not have to declare the system variables in your program. Every system variable begins with the prefix sy- . You can see the whole list in the ABAP Dictionary if you display the data type SYST. Although there are 171 different system fields, you do not need very many of them on a day-to-day basis. A lot of system fields are obsolete, while many more are reserved for internal use in the runtime system. The figure shows some of the system fields that you might use. You can read data from the system fields at any time. You must not write your own data into system fields. If you do, you may adversely affect the system behavior. You may also lose your data as it could be overwritten by the runtime system at any time. Some system fields are counters or indexes – for example, sy-index is the index of the current loop pass in a DO or a WHILE loop. All index fields in ABAP start at 1. The field sy-subrc is the return code field. Return codes are set by many ABAP statements to indicate whether the statement was successful or not. When a statement is executed successfully, sy-subrc has the value 0. If an error occurs when the statement is processed, sysubrc has a value unequal to zero. The documentation of ABAP statements describes whether the statement sets a value of sy-subrc (and, indeed, of other system fields), and what values are set in what situations. As an example, let us take the SELECT statement, which reads data from the database. When the runtime system executes a SELECT statement, it sets a value of sy-subrc. If sy-subrc is zero, it means that at least one row was returned by the query. If there are no rows in the database that match the query, sy-subrc has the value 4. At the same time, the statement sets a value for the further system field sy-dbcnt. This value of this field corresponds to the number of rows read from the database by the SELECT statement. © Copyright. All rights reserved. 57 Unit 3: Working with Variables in ABAP Figure 64: Errors During Methods So far we have seen how methods can have importing and exporting parameters so that we can supply them with information and receive results from them. However, sometimes a method cannot do what we asked it to do. In this case, it triggers an exception. In the example, we called a method whose task was to divide iv_int1 by iv_int2. Since iv_int2 is zero, this will not be possible. Dividing by zero in ABAP leads to a runtime error. To prevent this happening, the method correctly and sensibly checks the import parameters before it starts to do anything. When it finds out that the second value is zero, it triggers an exception. This terminates the method, and communicates to the calling program that an error has occurred. If the calling program ignores the exception, a runtime exception will occur. Figure 65: Finding Out About Errors © Copyright. All rights reserved. 58 Lesson: Working with Variables To find out which exceptions a method can raise, use the object documentation in ADT and look for the RAISING clause. This is the name of the exception, and you will need it in order to react to the error in your program. Figure 66: Reacting to Errors with TRY and CATCH To react to exceptions that methods raise, use a TRY…ENDTRY block. You write the TRY statement before the method call that could potentially raise an exception. Next comes the method call itself and any further statements that should only be processed if the call is successful (for example, displaying a valid result). After that comes the CATCH statement. In it, you write the name of the exception to which you want to react. If the method triggers this exception, the program will jump into the corresponding CATCH statement and process all of the statements from there until the end of the block, which is marked in this case by the ENDTRY statement. You can write more than one CATCH block to react differently to different errors. Note that not all methods use this technique for processing their exceptions. There is another, older, technique that you will learn more about later on. © Copyright. All rights reserved. 59 Unit 3: Working with Variables in ABAP Simple String Processing Figure 67: String Templates String templates are similar to literals but provide you with enhanced features. In their simplest form, they are a string literal, enclosed between vertical pipes. However, you can also use variables as placeholders, which are then replaced at runtime by the value of the variable. To use a variable as a placeholder in a string template, use curly braces to enclose the name of the variable. The spaces after the opening brace and before the concluding brace are mandatory. The space before the opening brace in the example is optional, and will be displayed as a blank space at runtime. There is a wide range of formatting directives that you can use in string templates. For full information, place the cursor inside a string template in the Editor and press F1. This displays the full documentation for string templates. Figure 68: Joining Strings © Copyright. All rights reserved. 60 Lesson: Working with Variables You can join fields together using the concatenation operator &&. You can join any combination of variables and literals, and the system assigns the result to the variable that you entered on the left-hand side of the equals sign. The constituent parts of the expression are joined with no space or other separator between them. If you need spaces or another separator character, you must remember to insert it yourself as part of the expression as shown in the second example. If you want to join several elements together and insert a separator character between each pair, you can use the older CONCATENATE statement. In this example, you would write: CONCATENATE gv_part1 gv_part2 INTO gv_string SEPARATED BY space. If you use the CONCATENATE statement, you may not use numeric fields (types I, P, DECFLOAT16, DECFLOAT34 or F). This restriction does not apply to the && operator. Figure 69: Splitting Strings To split a string into its constituent parts, use the SPLIT statement. In it, you specify a separator character at which the string should be split. This splitting Hello World at the space character yields two results Hello and World. In order to use SPLIT correctly, you must know how many fragments will result from the operation and specify exactly this number of fields. If you specify too few fields, the entire remainder of the source string will be placed into the last field. If the last field has a fixed length and is not long enough, the string will be truncated. If you specify too many fields, the surplus fields remain untouched by the operation. You may not use numeric fields in the SPLIT statement. © Copyright. All rights reserved. 61 Unit 3: Working with Variables in ABAP Figure 70: Finding Text To search a variable for a particular pattern, use the find function. This has the following arguments: val: The field in which you want to search sub: The string for which you want to search occ: The occurrence of the string for which you are searching. 1 is the first occurrence, 2 the second, and so on. If you want to search backwards from the end of the string, use negative values. case: Use this argument to specify whether the case of the search string should match exactly. X means match case, space means that the case is not important. The function returns the offset of the position at which the search string begins. This is its position in the string. An offset of 0 means that the search string occurs at the very beginning of the string. Here, the offset is 6. An offset of -1 indicates that the search string was not found. Figure 71: Replacing Text The replace function is similar to find. However, the return value in this case is the modified string. © Copyright. All rights reserved. 62 Lesson: Working with Variables You use the occ argument to specify which occurrence of the search string should be replaced. Once again, positive values count from the beginning of the string, negative values from the end. A third option with replace is to specify occ = 0. This replaces all occurrences of the search string. Working wIth Non-Variable Data Objects Figure 72: Literals Not all of the information that you use in a program is contained in variables. In the figure are some examples of literals. Literals have no name, which means there is no way of changing their value when the program is running. To use an integer as a literal, you just write the number. However, numbers containing decimal places must be enclosed in quotation marks, otherwise the decimal point would be interpreted by the system as the end of the statement. Character strings that you use as literals must be enclosed in quotation marks to distinguish them from the names of variables. Literals must begin and end in the same line of code. Figure 73: Constants Constants allow you to create a named data object that represents a particular value. © Copyright. All rights reserved. 63 Unit 3: Working with Variables in ABAP The advantage of this is that the name can reflect the particular purpose of the value, making the program easier to understand. You define constants using the CONSTANTS statement. The syntax of CONSTANTS is almost identical to that of DATA. You must, however, set a value for the constant using the VALUE addition. You may not change the value of a constant during the program. Figure 74: Text Elements If you use text literals directly in your source code, they cannot be discovered and translated using SAP's built-in translation tools. Consequently, if you are working in a multilingual environment, you must store texts so that they can be translated. In ABAP programs, this means using the text pool. In the text pool, you assign a three-character ID to a text and store it in the original language of your program. The text pool is accessible to the translation tools, so your texts can then be translated into other languages as required. To open the text pool of an ABAP program, right-click on the source code in the Editor and choose Open Other -> Text Elements . As there is no native Eclipse editor for the text pool, the text elements appear in a SAP GUI window. Text elements are only visible once you have activated them. LESSON SUMMARY You should now be able to: ● Declare appropriately typed variables in ABAP ● Work with variables in ABAP ● Work with non-variable data objects © Copyright. All rights reserved. 64 Unit 3 Learning Assessment 1. In ABAP, every variable has a fully-defined type. Determine whether this statement is true or false. X True X False 2. [Question]Which of the following data types are incomplete (and therefore support the LENGTH addition to the DATA statement)? Choose the correct answers. X A STRING X B P X C I X D C 3. Below you will see some data types and the initial values of variables that are declared with that type. Which of the combinations of data type and initial value are correct? Choose the correct answers. X A Type P. Initial value undefined. X B Type I. Initial value 0 X C Type C. Initial value a single space. X D Type D. Initial value ‘19700101’. 4. In an IF structure with multiple ELSEIF statements, more than one branch will be processed if more than one prerequisite condition is met. Determine whether this statement is true or false. X True X False © Copyright. All rights reserved. 65 Unit 3: Learning Assessment 5. Which of the following statements are true about CASE structures? Choose the correct answers. X A You can link values with AND. X B You can only test values for equality. X C You can link values with OR. X D WHEN OTHERS is compulsory. 6. You are using TRY..ENDTRY to handle errors. If you want to handle any error in a single CATCH statement, which statement would you use? Choose the correct answer. X A CATCH OTHERS. X B CATCH cx_root. X C CATCH cx_static_check. X D CATCH cx*. © Copyright. All rights reserved. 66 Unit 3 Learning Assessment - Answers 1. In ABAP, every variable has a fully-defined type. Determine whether this statement is true or false. X True X False 2. [Question]Which of the following data types are incomplete (and therefore support the LENGTH addition to the DATA statement)? Choose the correct answers. X A STRING X B P X C I X D C 3. Below you will see some data types and the initial values of variables that are declared with that type. Which of the combinations of data type and initial value are correct? Choose the correct answers. X A Type P. Initial value undefined. X B Type I. Initial value 0 X C Type C. Initial value a single space. X D Type D. Initial value ‘19700101’. 4. In an IF structure with multiple ELSEIF statements, more than one branch will be processed if more than one prerequisite condition is met. Determine whether this statement is true or false. X True X False © Copyright. All rights reserved. 67 Unit 3: Learning Assessment - Answers 5. Which of the following statements are true about CASE structures? Choose the correct answers. X A You can link values with AND. X B You can only test values for equality. X C You can link values with OR. X D WHEN OTHERS is compulsory. 6. You are using TRY..ENDTRY to handle errors. If you want to handle any error in a single CATCH statement, which statement would you use? Choose the correct answer. X A CATCH OTHERS. X B CATCH cx_root. X C CATCH cx_static_check. X D CATCH cx*. © Copyright. All rights reserved. 68 UNIT 4 Debugging in ABAP Lesson 1 Debugging in ABAP 70 UNIT OBJECTIVES ● Debug ABAP code © Copyright. All rights reserved. 69 Unit 4 Lesson 1 Debugging in ABAP LESSON OBJECTIVES After completing this lesson, you will be able to: ● Debug ABAP code Debugging an ABAP Program Figure 75: The Need for Debugging There is no way around the fact that errors occur in programs. However, they manifest themselves in different ways. When a user starts a faulty application, it may crash, something unexpected may happen, or nothing at all may happen. From the user's point of view, at user interface level, it is impossible to say just how and why this error occurred. As a developer, you now need to examine the program more closely – line-by-line in fact – to establish just what statements and combinations of values in the different program variables caused the error. This is where the Debugger comes in. © Copyright. All rights reserved. 70 Lesson: Debugging in ABAP Figure 76: Starting the Debugger To debug an ABAP program, you set a breakpoint then run the program normally. When the program reaches the breakpoint, the system interrupts it and opens the ABAP Debug perspective in ADT. You can then execute each subsequent statement individually to see what effect it has on the program. You can also inspect the contents of all of the variables in the program to see if any of the values are unexpected. Breakpoints are user-specific and are persistent – they remain active even after you have logged off from ADT and back on again. To prevent the debugger from starting at a breakpoint you must either delete it (using the Toggle Breakpoint function) or deactivate it using the corresponding function in the context menu. Figure 77: The Debug Perspective in ADT When you debug an ABAP program using ABAP Development Tools, you use the Debug perspective. This is a customized version of the standard Eclipse Debug perspective, and it contains views and functions that are particularly important for debugging. The most important is, of course, the Source Code view. This displays the source code of your program and highlights the current position in the program. Also crucial is the Variable view (not selected in the figure, The Debug Perspective in ADT), which shows the current values of variables. Next to it above, you see the Breakpoints view. Breakpoints are points in the program at which normal processing is interrupted and the system shows you the Debugger so that you can analyze the state of the program at exactly that moment. © Copyright. All rights reserved. 71 Unit 4: Debugging in ABAP Figure 78: Using the Debugger When the debugger starts, you will see the current line highlighted in the source code display. This is the next line that will be executed when you restart the program. In the top right-hand corner of the screen are two important views – variables and breakpoints. In the variable view, you can see all of the global variables in the program listed under Globals. As there may be a lot of these variables, you can also display the values of selected variables that you need to inspect by entering the name of the variable in the <Enter variable> field. You can also display a variable in this area by placing the cursor on it anywhere in the source code display and pressing Ctrl + Shift + I. As well as setting breakpoints in the Editor, you can also set more in the Debugger. Place the cursor in the left-hand margin of the source code editor, right-click, and choose Toggle Breakpoint . To continue processing the program you have two options: ● Execute the next statement by pressing the F5 key. This executes the next statement and stops again. ● Continue the program by pressing the F8 key. This continues running the program until it encounters another breakpoint. If there are no more breakpoints, the program continues until it is finished. © Copyright. All rights reserved. 72 Lesson: Debugging in ABAP Figure 79: Special Breakpoints Breakpoints that stop at a particular line are not always useful. Sometimes you know that you want to stop at a particular statement without necessarily knowing where the statement occurs in your source code. You can do this by setting a statement breakpoint. To do this, switch to the Breakpoints tab in the Debug perspective and click on the menu button highlighted in the figure. Choose Add Statement Breakpoint . A dialog box appears in which you can choose the relevant ABAP statement or function. The statement for an authorization check is AUTHORITY-CHECK, so you would highlight this and choose OK. Your program will then stop whenever it encounters an authorization check. Significantly, this does not only apply to the program that you are currently working in, but to all modularization procedures (like methods) that it calls. Figure 80: Watchpoints © Copyright. All rights reserved. 73 Unit 4: Debugging in ABAP If an unexpected value of a variable is causing you problems, you can track its value during the course of the program using a watchpoint. To set a watchpoint on a variable, right-click it in the source-code display and choose Watchpoint . This creates a watchpoint, which you can then see in the Breakpoints view. Whenever the value of the variable changes, the program will stop in the Debugger. Set If you only want to stop when the variable reaches a particular value, you can set a condition. For example, you could enter > 200, and the program would only be interrupted whenever the value of gv_result changed to a value greater than 200. Figure 81: Altering the Program Flow When you are debugging a program, you will sometimes want to see what the program would have done under different circumstances. There are two ways that you can do this – by changing the value of a variable and by jumping to a particular line in the program. Suppose you have just identified the source of an error in your program – you realize that you should have initialized the value of a variable using CLEAR, but you forgot. To see whether the program would have worked properly in that case, you can change the value of the variable directly in the Debugger. The program then continues with the value that you set. To change the value of a variable, right-click it in the variable display and choose Value. A dialog box appears in which you can then enter the new value. Change In another example, you may have written a branch of code that is processed in response to a particular error. However, you cannot accurately produce the error situation in your test. You can, however, still execute the code to see how it reacts. To do this, position the cursor on the line at which you want to start and choose the Jump To Line function. The system resumes processing at the line in which you positioned the cursor. You should only ever use these functions in a development system, as theoretically they can cause data inconsistency and present a security risk. LESSON SUMMARY You should now be able to: ● Debug ABAP code © Copyright. All rights reserved. 74 Unit 4 Learning Assessment 1. Which of the following tasks can you perform both in the ABAP Perspective and in the Debug Perspective? Choose the correct answers. X A Set a watchpoint. X B Set a breakpoint for all occurrences of a particular statement. X C Set a breakpoint on a particular line. X D Activate changes to your program. © Copyright. All rights reserved. 75 Unit 4 Learning Assessment - Answers 1. Which of the following tasks can you perform both in the ABAP Perspective and in the Debug Perspective? Choose the correct answers. X A Set a watchpoint. X B Set a breakpoint for all occurrences of a particular statement. X C Set a breakpoint on a particular line. X D Activate changes to your program. © Copyright. All rights reserved. 76 UNIT 5 Calling Reusable Procedures Lesson 1 Understanding Reuse 78 Lesson 2 Using Classes 82 Lesson 3 Using Function Modules 86 UNIT OBJECTIVES ● Understand the benefits of reusing procedures ● Use an existing global class ● Use existing function modules © Copyright. All rights reserved. 77 Unit 5 Lesson 1 Understanding Reuse LESSON OBJECTIVES After completing this lesson, you will be able to: ● Understand the benefits of reusing procedures The Benefits of Reuse Figure 82: Software Development Without Reuse Software development today attaches great importance to reusing components wherever possible. The figure above shows what two programs would look like if they do not reuse anything. In program 1, code block B occurs identically in two different places in which it is required. To make matters worse, it is also duplicated at other points in other programs. Programs that are developed in this way are larger than they need to be. Each time the coding block is duplicated, the program size increases by the size of the block. There is also no way of knowing just how often and at what points the block has been used. Consequently, if the behavior of "code block B" needs to be changed, a developer must examine a large number of programs to establish just which parts of which programs need to be adjusted. © Copyright. All rights reserved. 78 Lesson: Understanding Reuse Figure 83: Software Development with Local Reuse Now let us look at what happens if code block B is stored as a reusable procedure within a single program. Instead of duplicating the coding, it is stored once only in the program and called when required. This makes the code easier to maintain, because it only exists once, and makes the program itself easier to understand because it contains fewer lines of code. Figure 84: Software Development with Global Reuse If a particular block of code is required by more than one program, you can store it centrally in a special container. From here, it is available to all other programs in the system. Global reuse in ABAP is implemented using methods and function modules. The container for a method is a global class, and the container for a function module is a function group. © Copyright. All rights reserved. 79 Unit 5: Calling Reusable Procedures Figure 85: Calling Reusable Procedures When you use reusable procedures, there are certain principles that apply: The container is loaded into the memory area of the calling program. Each program that calls a reusable procedure has its own copy of the container in its own program memory. This makes it impossible for one program to interfere with the running of another. One side cannot see the data of the other. A program that calls a reusable procedure has its own data. Equally, the called procedure – and its container – may have their own data. Importantly, neither side can access the data of the other side directly. Were this to be allowed, it would become impossible to guarantee the consistency of the data. Keeping data consistent requires that access to that data is restricted as much as possible. Data can only be exchanged using parameters. In order to perform a function, reusable procedures require information from their caller. They also need to deliver results that they have calculated. Data exchange between a procedure and its caller is regulated by the definition of parameters as part of the procedure definition. This is a kind of contract between the procedure and a potential caller that describes the information that a procedure requires and the results that it can provide. Only this information can be exchanged between the caller and the called procedure. © Copyright. All rights reserved. 80 Lesson: Understanding Reuse Figure 86: Global Reusable Procedures in ABAP In ABAP, for historical reasons, there are two different kinds of global reusable procedure. Methods are functions that belong to a global class. Function modules are functions that are logically related and belong to the same function group. As a rule, if you are creating a new application, you should use classes and methods. However, for certain tasks, you cannot replace function modules. See the documentation of the CALL FUNCTION statement for full details. LESSON SUMMARY You should now be able to: ● Understand the benefits of reusing procedures © Copyright. All rights reserved. 81 Unit 5 Lesson 2 Using Classes LESSON OBJECTIVES After completing this lesson, you will be able to: ● Use an existing global class Understanding the Definition of a Class Figure 87: Identifying Global Classes There are different ways to locate a particular class. If the class belongs to one of your favorite packages, you can expand the object list until you find it. You will find classes in the branch Source Code Library. If you know part of the name of the class, you can use the key combination Ctrl + Shift + A to open the Open ABAP Repository Object dialog box. Alternatively, you can use Ctrl + H to open the Search dialog. In the search dialog box, you have the added feature that you can restrict the search to your favorite packages. If you have a program open in the Editor that uses the class, you can navigate to it using the F3 key. © Copyright. All rights reserved. 82 Lesson: Using Classes Figure 88: Inspecting the Structure of a Class When you open a class in ADT, you see its source code in the Editor. Later on, you will learn how to create your own classes. However, for now you are just going to use functions provided by an existing global class in the form of static methods. One of the main principles of object-oriented design is to restrict access to the components of classes. By doing so, a class can, for example, stipulate that data may only be changed from within the class itself and not from outside. The aim of this is to ensure data consistency. Likewise, access to functions may also be restricted. If you look at the class definition, you will see three statements: PUBLIC SECTION, PROTECTED SECTION, and PRIVATE SECTION. When you write a program that is going to use the class, you only have access to the PUBLIC SECTION. In the public section of this class, there are four CLASS-METHODS statements. Each of these defines a static method, which is a function like the ones you have used already in this class. The four methods in this class implement the four arithmetic functions addition, subtraction, multiplication, and division. You can see the components of the class both in the Editor and in the Outline view. The green dot in the outline view indicates that the methods are public. To navigate from an element in the outline view to the actual method definition in the source code, right-click the component name and choose Navigate To Declaration. © Copyright. All rights reserved. 83 Unit 5: Calling Reusable Procedures Figure 89: Signature of a Method Methods can have parameters and exceptions which, together, make up their signature. IMPORTING parameters are values that are passed from the caller to the method. They may be obligatory (default) or optional. The method is not allowed to change the values of importing parameters. A method may have any number of importing parameters. EXPORTING parameters are values that are passed from the method back to the caller. They are always optional. A method may have any number of exporting parameters. CHANGING parameters are values that are passed from the caller to the method. They may be obligatory (default) or optional. The method is allowed to change the values and, at the end of the method, the changed value is passed back to the program. A method may have any number of changing parameters. A RETURNING parameter is a special return value that can be passed from a method back to its caller. The caller can assign the value directly to a variable or use it in an expression without first having to receive it via the signature in the method call. A method may only have one returning parameter. RAISING is the section of the method signature that lists the exceptions that the method can trigger in case of an error. Note that instead of RAISING, method can – for historic reasons – have an EXCEPTIONS section. This is for methods that use an older form of exception handling. Since this is very commonly found in function modules and works in exactly the same way for function modules and methods alike, we will deal with this technique in the section on function modules. When a program and a method exchange information, the system does not normally pass copies of the data. Instead, it merely informs the method of the address in memory of the corresponding variables. This approach is more efficient in terms of performance and memory consumption and is called call by reference. Methods can pass copies of the data if necessary. This is called call by value. Note that returning parameters are always called by value. © Copyright. All rights reserved. 84 Lesson: Using Classes Figure 90: Calling a Public Static Method This code example shows how to call the method defined in the previous figure by observing the following rules: You must supply all obligatory parameters: Since none of the importing parameters of the method were defined with the words OPTIONAL or DEFAULT, you can infer that they are obligatory and must therefore be supplied in the EXPORTING section of the method call. The parameter name is on the left-hand side of the equals sign, the variable that you want to pass to the method on the right. You must use corresponding types in the method call: The importing parameters iv_int1 and iv_int2 are integers, therefore the variables that you pass to them must also be integers. The parameter ev_result has type P with length 16 and 2 decimal places, and the variable gv_result must also have this type. You could define the variable using the built-in ABAP type P, but since the class already provides a corresponding type, it is easier to use it. You should take all possible exceptions into account: The signature of the method indicated that the exception cx_s4d400_zerodivide could occur. Therefore you should write a TRY… CATCH…ENDTRY block so that the error will be handled if it occurs. If there is no corresponding catch block and the method triggers the exception, the program will terminate with a runtime error. LESSON SUMMARY You should now be able to: ● Use an existing global class © Copyright. All rights reserved. 85 Unit 5 Lesson 3 Using Function Modules LESSON OBJECTIVES After completing this lesson, you will be able to: ● Use existing function modules Function Groups And Function Modules Figure 91: Function Groups and Function Modules A function group is a container program in which you can create function modules. Each function module provides a single reusable function that can be called by any other program, function module, or method in the system. Function groups can also contain data that can be accessed by all of the function modules in the group. The data is, however, not visible outside the function group. People often ask why ABAP has both function groups with function modules and classes and methods. The answer, as so often in ABAP, is historical. Function modules predate classes and methods by several years and were introduced to allow developers to create globally reusable units of code. Classes and methods came along later when object-orientation was introduced into ABAP. At one level, you can use methods just like function modules (a function module is almost identical to a public static method in a class). However, objectorientation allows you to do much more than you can with function modules, and you will learn about this later on. Even though SAP would recommend today that you work with classes and methods, you do not always have the choice – many essential functions in the SAP System are implemented using function modules, and where these exist, it makes sense to reuse them. This applies both to simple tasks in ABAP programs (for example, there is a function module that allows © Copyright. All rights reserved. 86 Lesson: Using Function Modules you to find out on which day of the week a particular date falls, another for performing currency conversions, and so on) and to the definition of OData Services in SAP Gateway, where an existing function module might provide a useful Create or Update operation that you would otherwise have to code yourself. Figure 92: Interface of a Function Module Function modules can have parameters and exceptions which, together, make up their interface. Interfaces of function modules and signatures of methods are essentially the same, but use different terms. This is because the term interface was already in use for function modules when classes were introduced into ABAP. Unfortunately, the term interface has a different meaning in object-orientation and SAP adopted the industry standard term signature for method parameters. IMPORTING parameters are values that are passed from the caller to the function module. They may be obligatory (default) or optional. The function module is not allowed to change the values of importing parameters. A function module may have any number of importing parameters. EXPORTING parameters are values that are passed from the function module back to the caller. They are always optional. A function module may have any number of exporting parameters. CHANGING parameters are values that are passed from the caller to the function module. They may be obligatory (default) or optional. The function module is allowed to change the values and, at the end of the module, the changed value is passed back to the program. A function module may have any number of changing parameters. EXCEPTIONS is the section of the interface in which the function module lists the errors that it can trigger. These are not exception classes that you handle with TRY… CATCH… ENDTRY control structures, but an older form of exception handling. Function modules usually have this kind of exception. It is possible (but unlikely) that you will encounter more modern function modules that make use of the newer exception handling concept. © Copyright. All rights reserved. 87 Unit 5: Calling Reusable Procedures Figure 93: Calling a Function Module You call a function module using the CALL FUNCTION statement. In it, you must specify the name of the function module in quotes, and in upper case. The code completion is available to help you – type the beginning of the name of the function module and press Ctrl + Space to see a list of function modules that fit the pattern you entered. From the list, press Shift + Enter to insert the rest of the name of the function module and the full interface definition into your program. Since the name of a function module has to be unique system-wide, you do not need to use the name of the function group in the CALL FUNCTION statement. Figure 94: The System Field sy-subrc One very important system field is sy-subrc. This is the return code field, which tells us if a particular statement was successful. If sy-subrc has the value zero, the statement was successful. If the value if sy-subrc is unequal to zero, this means that an error has occurred. You can query the value of sy-subrc using an IF statement to find out if the preceding statement was successful or not. © Copyright. All rights reserved. 88 Lesson: Using Function Modules To find out whether a particular statement sets a value of sy-subrc, and what values are set in what circumstances, consult its documentation. Figure 95: sy-subrc and Function Modules Function modules also use sy-subrc to communicate to their caller that an error occurred. When a function module ecounters an error, it reacts by stopping processing. This is because it cannot normally know how to resolve the error by itself. It then communicates the fact that an error occurred to its calling program. It does this using the system field sy-subrc. When you call a function module, you list its possible exceptions in the EXCEPTIONS section of the CALL FUNCTION statement. Here, you assign a numeric value to each exception that you need to process. If the corresponding exception occurs, the system assigns that numeric value to sy-subrc. Thus, by finding out the value of sy-subrc after the function call, you will know whether the statement was successful – in this case, sy-subrc will have the value zero – or that it contained an error, in which case sy-subrc will have the corresponding numeric value. When you assign values to exceptions, you can use the same value for more than one exception. This allows you to define groups of exceptions that should all be processed in the same way. There is also a generic exception OTHERS. It does not occur in the interface of function modules, but you can always use it in the EXCEPTIONS part of the CALL FUNCTION statement. OTHERS stands for any exception of the function module that you have not listed explicitly. If a function module raises an exception and you do not catch it, either explicitly by name or implicitly using OTHERS, the system will trigger a runtime error. © Copyright. All rights reserved. 89 Unit 5: Calling Reusable Procedures Figure 96: Error Handling Using Classic Exceptions If a function module triggers an exception, the same thing happens as with class-based exceptions, namely that the function module terminates and control returns to the calling program. The remaining code in the function module is not processed. The system places the numeric value corresponding to the exception (you did this in the CALL FUNCTION statement) in the system field sy-subrc. By finding out the value of sy-subrc, you can find out whether the function call was successful or not. LESSON SUMMARY You should now be able to: ● Use existing function modules © Copyright. All rights reserved. 90 Unit 5 Learning Assessment 1. Which of the following are modularization techniques in ABAP? Choose the correct answers. X A Stored procedures. X B Function modules X C Include programs. X D Methods of global or local classes. 2. Programs exchange data with modularization units by means of an interface. It is not possible for one side to directly access the data of the opposite side. Determine whether this statement is true or false. X True X False 3. The name of a function module need only be unique within its function group. Determine whether this statement is true or false. X True X False 4. Which of the following statements regarding the interface of a function module are true? Choose the correct answers. X A All of the changing parameters are mandatory. X B There may be any number of importing parameters. X C There must be exactly one exporting parameter. X D Exporting parameters are always optional. © Copyright. All rights reserved. 91 Unit 5: Learning Assessment 5. Which of the following happens when a function module triggers an exception? Choose the correct answer. X A The function module continues processing and triggers the exception at the end of the module. X B The function module triggers the exception and, at the same time, a runtime error. X C The function module terminates and returns control to its calling program. X D The function module checks whether any other exceptions need to be triggered along with the first error that has already been discovered. © Copyright. All rights reserved. 92 Unit 5 Learning Assessment - Answers 1. Which of the following are modularization techniques in ABAP? Choose the correct answers. X A Stored procedures. X B Function modules X C Include programs. X D Methods of global or local classes. 2. Programs exchange data with modularization units by means of an interface. It is not possible for one side to directly access the data of the opposite side. Determine whether this statement is true or false. X True X False 3. The name of a function module need only be unique within its function group. Determine whether this statement is true or false. X True X False 4. Which of the following statements regarding the interface of a function module are true? Choose the correct answers. X A All of the changing parameters are mandatory. X B There may be any number of importing parameters. X C There must be exactly one exporting parameter. X D Exporting parameters are always optional. © Copyright. All rights reserved. 93 Unit 5: Learning Assessment - Answers 5. Which of the following happens when a function module triggers an exception? Choose the correct answer. X A The function module continues processing and triggers the exception at the end of the module. X B The function module triggers the exception and, at the same time, a runtime error. X C The function module terminates and returns control to its calling program. X D The function module checks whether any other exceptions need to be triggered along with the first error that has already been discovered. © Copyright. All rights reserved. 94 UNIT 6 Using Structures Lesson 1 Using Structures 96 UNIT OBJECTIVES ● Use structure types ● Use structure variables © Copyright. All rights reserved. 95 Unit 6 Lesson 1 Using Structures LESSON OBJECTIVES After completing this lesson, you will be able to: ● Use structure types ● Use structure variables Working with Structure Types Figure 97: The Story So Far – Simple Variables Up until now, you have been using simple variables, each of which can store a single piece of information. Here, for example, there are two variables, one for an airline code, the other for a flight number. These two variables are completely independent of one another, and are therefore not suitable for storing different pieces of information that belong together. Here, the flight number only makes sense in conjunction with the airline. In other examples, you may need to read a record from the database and need to hold all of this information together. In ABAP, the solution is to use a structure. © Copyright. All rights reserved. 96 Lesson: Using Structures Figure 98: Using a Structure A structure is an ABAP variable with a name and a structured type. It is subdivided into components, each of which also has a name and a type. You can address both the structure as a whole and the individual components. Importantly, you can use each component in exactly the same way that you would use a standalone elementary variable. You will often find structured types in the ABAP Dictionary, and sometimes in global classes. You may also define them locally in a program. Figure 99: Types in the ABAP Dictionary © Copyright. All rights reserved. 97 Unit 6: Using Structures Figure 100: Type Definition in the ABAP Dictionary There are two ways to edit a type definition in the ABAP Dictionary: You can either use the source-code based Eclipse editor or the classic SAPGUI editor. In ABAP systems with Release 7.50 or higher, the source code editor appears by default. If you want to switch to the SAPGUI-based editor, right-click in the editor and choose Open With -> SAPGUI . In either case, the structure definition consists of a series of components. Each component has a name, which must be unique within the structure, and a type. The type is usually a data element, but can be a built-in ABAP Dictionary type. A structure can have any number and combination of components according to your requirements. Structures can contain other structures as components (nested structures). Figure 101: Type Definition in an ABAP Program You can also define structured types in an ABAP program using the TYPES statement. The structure definition begins with the statement TYPES BEGIN OF <name> and ends with TYPES END OF <name>. In between, you name each component and specify its type. Here, each of the types is a data element from the ABAP Dictionary. However, you could also use built-in ABAP types. © Copyright. All rights reserved. 98 Lesson: Using Structures Declaring and Using Structures Figure 102: Working with Structure Components To declare a structured variable, use the DATA statement and specify a type that is a structure. This may come from the ABAP Dictionary (as in this case) or be a local typed defined in your program. Note that if you use a local type, the type definition must come before the point in your program at which you attempt to use it. In a freshly declared structure, each component has the initial value that corresponds to its type. To address a single component of a structure, you write the name of the structure variable (in this case gs_flight), followed by a dash (more correctly known as the component selector), followed by the name of the component. You can do this anywhere in an ABAP program where a variable is allowed. ADT provides code completion for structures: After the dash, you can press Ctrl + Space to open the code completion dialog and see what components the structure has. The statement CLEAR <structure>-<component> resets the component to its own initial value. The statement CLEAR <structure> resets the value of each individual component to its own initial value. © Copyright. All rights reserved. 99 Unit 6: Using Structures Figure 103: Filling a Whole Structure Using VALUE If you want to fill a whole structure, you can address each component individually as you saw in the previous figure. However, you can also use a VALUE expression to fill the structure. The expression fills the structure and assigns the filled structure to a variable – in this case gs_flight. The pound sign (#) tells the ABAP system to create a structure with the same type as the target variable gs_flight. In the parentheses, you list the components of the structure that you want to fill (it does not have to be all of them) and assign a value to them. The value can be either a literal or the contents of a variable. When you fill a structure in this way, the runtime system deletes all existing values from the structure before refilling it with the values from your expression. Figure 104: Using the BASE Expression To avoid the entire structure being deleted when you use the VALUE expression, you can add the BASE expression to it. The meaning of this expression is: "Take the structure gs_flight, change the value of the seatsocc component, and assign the reult back to the structure gs_flight". © Copyright. All rights reserved. 100 Lesson: Using Structures Figure 105: Copying Data Between Structures In ABAP, you may only copy the contents of one structure directly into another structure using the notation <target structure> = <source structure> if the two structure types are compatible. This is generally only the case if both structures have the same type. If the structures have different types, as is the case here, you will see a syntax error if you attempt the assignment. When you copy data between structures, you usually want to copy information from one field into the corresponding field of the target structure – carrid to carrid, connid to connid, and so on. To achieve this in ABAP, use the CORRESPONDING expression. This assigns values from gs_flight to the corresponding, that is, identically named components of gs_conn. You must remember the following points: ● The fields must have identical names. ● The components do not have to be in the same position or sequence in the two structures. ● If the fields have different types, ABAP converts the value according to a predefined set of rules. The possible outcomes of this conversion are: ● The conversion is successful and no data is lost (for example, when an integer is converted into a string). ● The conversion is technically successful, but data gets lost on the way (for example, if you assign the contents of a character field to another, shorter, character field, the contents of the field will be truncated). ● The conversion fails (for example, if you assign a sequence of letters and symbols to a numeric field). When you use the CORRESPONDING expression in this way, the target structure is initialized before being refilled with the result of the expression. If you want to keep the contents of the target structure and just merge new values into it, you use the BASE expression in exactly the same way as you learned with VALUE. © Copyright. All rights reserved. 101 Unit 6: Using Structures Note that in older programs you will also see the statement MOVE-CORRESPONDING <source> TO <target>. This statement has the same effect as <target> = CORRESPONDING #( BASE <target> SOURCE ). Figure 106: Merging Data from Multiple Structures Using the CORRESPONDING and BASE functions, you can combine data from multiple structures into a single large structure. This example fills the structure gs_info first with the components carrid and carrname from gs_carrier, then with carrid, connid, and fldate from the structure gs_flight. Note that CARRID is filled twice, because it occurs in both source structures. Figure 107: Structures In The Debug Perspective © Copyright. All rights reserved. 102 Lesson: Using Structures To display a structure in the debug perspective, you double-click the name of the structure as you would any normal variable. When the structure appears in the Variables view, click the arrow to expand the display and show the individual components. You can change the value of individual components in exactly the same way as you would with any other variable. If you double-click the name of a structure component such as gs_connection-carrid, the individual component appears by itself in the Variables view. You can then treat it like any other variable. LESSON SUMMARY You should now be able to: ● Use structure types ● Use structure variables © Copyright. All rights reserved. 103 Unit 6 Learning Assessment 1. You can declare structure types both in the ABAP Dictionary and in an ABAP program. Determine whether this statement is true or false. X True X False 2. You want to copy data between two structures. The structures have different types, but some of the components have identical names. The target structure already contains data, which you do not want to lose during the copy operation. Which of the following functions would you use? Choose the correct answer. X A VALUE with BASE. X B VALUE without BASE. X C CORRESPONDING with BASE. X D CORRESPONDING without BASE. © Copyright. All rights reserved. 104 Unit 6 Learning Assessment - Answers 1. You can declare structure types both in the ABAP Dictionary and in an ABAP program. Determine whether this statement is true or false. X True X False 2. You want to copy data between two structures. The structures have different types, but some of the components have identical names. The target structure already contains data, which you do not want to lose during the copy operation. Which of the following functions would you use? Choose the correct answer. X A VALUE with BASE. X B VALUE without BASE. X C CORRESPONDING with BASE. X D CORRESPONDING without BASE. © Copyright. All rights reserved. 105 UNIT 7 Using Internal Tables Lesson 1 Internal Table Types 107 Lesson 2 Working with Internal Tables 113 UNIT OBJECTIVES ● Understand internal table types ● Work with internal tables © Copyright. All rights reserved. 106 Unit 7 Lesson 1 Internal Table Types LESSON OBJECTIVES After completing this lesson, you will be able to: ● Understand internal table types Attributes of Internal Tables Figure 108: Structures and Internal Tables While structures are useful in ABAP for managing a single data record, you often need to manage several related data records in a single variable. This is necessary, for example: ● When you read multiple records from the database and need to store them in your program. ● When the user has entered more than one line of data on the user interface (for example, line items in a purchase order). ● When you want to display multiple records in a table on the user interface. ● When you need to export data to a file. In ABAP, you use internal tables whenever you need to manage more than a single line of data. As such, they take on the role that arrays, chained lists, recordsets, or collections play in other languages. © Copyright. All rights reserved. 107 Unit 7: Using Internal Tables One of the biggest advantages of internal tables is that the runtime system takes care of memory management automatically. When you declare an internal table, the runtime system calculates an appropriate initial memory allocation for it. When you add more data to the table, the table grows automatically. When you empty the table, the system automatically releases excess memory. In other words, you do not have to worry about managing the size of the table yourself. However, this does not mean that the size of an internal table has no limits. If the table requires more memory than the program session is allowed to use, a runtime error will occur. Every internal table is characterized by its line type, its access type, and its key attributes. Figure 109: Line Type of an Internal Table The line type of an internal table describes what columns the table has. In the majority of cases, the line type is a structure, which means that every line in the internal table contains a column with the name and type of the corresponding structure component. As well as being a simple field, a column of an internal table could be a nested structure or even a nested internal table. Sometime, instead of using a structure, you will need an internal table with just a single column. In this case, the column does not have a name in the same way that a component of a structure does, but ABAP assigns it the pseudo-name table_line. © Copyright. All rights reserved. 108 Lesson: Internal Table Types Figure 110: Access Type of an Internal Table Every internal table has one of three access types. The access type determines how data is stored in the table and, based on how it is stored, how the system reads the table to retrieve the data. The different approaches to retrieving the data can make significant performance differences. In a standard table, the contents are not stored in a particular sort order. By default, new records are appended to the end of the table. In order to retrieve data from the table, the system must read it sequentially, which can lead to long retrieval times if the table is very large. In a sorted table, the contents of the table are always sorted according to the table key in ascending order. When you insert a new record into the table, the system ensures that it is placed at the correct position. Since the data is always sorted, the system can retrieve records more efficiently than from a standard table (as long as you follow particular rules). Hashed tables are managed using a special hash algorithm. This ensures that the system can retrieve records very quickly even if the table is extremely large. However, this performance gain only works in very particular cases. In this class, we will concentrate on standard tables. The other kinds of tables and how to program efficiently with internal tables is covered in the Advanced ABAP class. Figure 111: Key Attributes of Internal Tables Every internal table has a key. In standard tables, the key does not play a particularly significant role. For sorted and hashed tables, the key is very important as it determines the way in which the data will be managed in the table. Crucially, sorted and hashed tables are only faster for data retrieval if you use the key properly. © Copyright. All rights reserved. 109 Unit 7: Using Internal Tables If you do not explicitly specify the key components in your table definition, it will have a default key. This consists of all non-numeric columns of the table line type. A further attribute of the table key is its uniqueness. You will sometimes want to allow duplicate entries in an internal table, and sometimes you will want to ensure that the key is unique. Here, the following rules apply: ● Duplicates are always allowed in standard tables. ● Duplicates are never allowed in hashed tables. ● In a sorted table, you must choose when you define it whether the key is to be unique or non-unique. Internal tables may also have secondary keys. Secondary keys are a way of improving the performance of data retrieval from internal tables. You will find more information about secondary keys in the ABAP syntax documentation or the Advanced ABAP class. Figure 112: Addressing Internal Tables – Key and Index Access There are two ways to access a line of an internal table – by index and by key. Index access means addressing a line of the internal table by its line number. Key access means addressing a line of the internal table by looking for particular values in particular columns. The columns in which you search may be key columns, but can just as easily be non-key columns. In either case, we still speak of "key access". Index access is the most frequent way to access a standard table. Key access is the more common way to access a sorted table. Hashed tables do not have an index, therefore index access is not allowed. © Copyright. All rights reserved. 110 Lesson: Internal Table Types Internal Table Types Figure 113: Internal Table Type in the ABAP Dictionary You can define internal table types in the ABAP Dictionary. This makes them reusable in any other object, such as a program or as the type of a parameter of a function module or method. There is no native Eclipse editor for creating internal table types. Consequently, the SAPGUI editor opens when you create, edit, or display a table type. There are five tabs in the editor: Attributes: This contains the package assignment and the date of the last change to the object. Line Type: Here you enter the name of the ABAP Dictionary structure that you want to use to define the line type of the internal table. To create a single-column table, you would enter the name of a data element instead. Initialization And Access: On this tab, you specify whether you want to create a standard, sorted, or hashed table. Primary Key: Here you specify the key components of the table line. Normally you enter a list of column names. In exceptional cases, you can create either a default key or specify that the entire table line should make up the key. Secondary Keys: On this tab, you may define secondary keys for the internal table type. © Copyright. All rights reserved. 111 Unit 7: Using Internal Tables Figure 114: Internal Table Type in an ABAP Program If you only need your internal table type within a single program, you can create it locally using the TYPES statement. The definition in this figure is identical to the previous definition from the ABAP Dictionary. It is good programming style to define the type first and then to create a variable that refers to the type. However, for compatibility reasons in ABAP, you will also see the following: DATA gt_flights TYPE STANDARD TABLE OF d400_s_flight WITH NON-UNIQUE KEY carrid connid fldate. This incorporates the complete type definition into the declaration of the variable. Although you "save" a line of code by rolling the type definition and the variable declaration into one statement, this approach has the disadvantage that you cannot reuse the type definition in other variables or in parameter definitions. A popular short notation for declaring internal tables is: DATA gt_flights TYPE TABLE OF d400_s_flight. At first glance, there is much information that is missing from this declaration – there is no explicit definition of the access type or the key of the internal table. The shortened syntax defines a standard table with a default key (comprising all non-numeric components in the table line). The key is non-unique, as is always the case with standard tables. In very old ABAP coding, you may also see the following obsolete form for declaring internal tables: DATA <table> TYPE <line> OCCURS 0. LESSON SUMMARY You should now be able to: ● Understand internal table types © Copyright. All rights reserved. 112 Unit 7 Lesson 2 Working with Internal Tables LESSON OBJECTIVES After completing this lesson, you will be able to: ● Work with internal tables Filling an Internal Table Figure 115: Filling an Internal Table There are various ways in which you can fill an internal table with data. Sometimes, the data will be returned as the result of a call to a function module or method. Very often, the table is filled with data when you execute a SELECT statement to retrieve data from the database (you will learn about this in the next unit). The third way is to add individual lines to an internal table in a program. © Copyright. All rights reserved. 113 Unit 7: Using Internal Tables Figure 116: Adding a Line to an Internal Table – Use a Structure The simplest way to add a new line to an internal table is to take a variable whose type corresponds to the line type of the internal table and fill it with the appropriate values. Normally, this variable will be a structure. In the example, we have used the VALUE operator to fill the structure. It would equally be possible to fill the individual components of the structure using the syntax <structure>-<component> = <value>. Once you have filled the structure, you can add it to the internal table. Figure 117: Adding the Structure to an Internal Table To insert the contents of the structure into the internal table, use the VALUE operator again. When you use VALUE to fill an internal table, there are at least two sets of parentheses. The outer parentheses enclose the entire expression. The inner parentheses describe the © Copyright. All rights reserved. 114 Lesson: Working with Internal Tables contents of a single line of the table. In this case, the line is described by the structure that we filled in the last code example. The result of this expression is an internal table with a single line. Before filling the table, the system deletes any existing contents from the table. Figure 118: Using BASE to Preserve the Existing Contents In order to add new lines to an internal table without deleting the existing contents, you use the BASE addition. This tells the system to use the contents of (in this case) gt_flights and to add the contents of the structure gs_flight to it. When you use VALUE in this way, the system always ensures that the new record is inserted at the correct position in the table. In a standard table, the system appends the record to the end of the table. In a sorted table, the system inserts the new line in the correct sort order. Figure 119: Adding Lines Without Using a Structure © Copyright. All rights reserved. 115 Unit 7: Using Internal Tables It is also possible to add lines to an internal table without using a structure. In the example on the left-hand side of the figure, we fill a structure and use it in the VALUE expression. However, at the position where we used gs_flight, we can also use a component-bycomponent description of a structure, which is what we have done on the right-hand side. The effect on the internal table is the same in both cases. There is, however, one difference in the program: In the left-hand example, we can carry on using the structure by addressing its name gs_flight. The structure that we have described on the right-hand side has no name, so we cannot subsequently use it later on in the program. Neither of these variants can be considered "better" than the other. As is so often the case in programming, they are merely different ways to achieve the same result. Figure 120: Filling One Internal Table from Another To copy data between identically named fields of two internal tables, use the CORRESPONDING operator. This works similarly to CORRESPONDING for structures – in each line of the internal table, the system copies data between identically named fields. If the target internal table contains data before the statement, the system deletes it. If you want to retain the data and add the contents of the source table to the target, use the form <target> = CORRESPONDING #( BASE ( <target> ) <source> ). © Copyright. All rights reserved. 116 Lesson: Working with Internal Tables Reading an Internal Table Figure 121: Reading a Line By Index When you read a single line of an internal table that has a structure as its line type, the result is a structure of the same type. In ABAP, this is often referred to as the work area. The way in which you access an internal table in ABAP depends on whether you want to read a single line or multiple lines, and whether you want to identify the lines by their index (line number) or key (particular values in particular columns). To access a single line of a table, you use a table expression. This consists of the name of the internal table and, in brackets, the identification of the line that you want to read. The result of a table expression is a single line of the table. In the table expression, there is no space between the name of the internal table and the opening bracket. There must, however, be at least one space after the opening bracket and before the closing bracket. To identify a line of the table by its line number, write the line number in the brackets. You may give the line number as a literal as displayed here or you could use an integer variable. If the corresponding line of the internal table does not exist, the system triggers an exception. If you do not handle the exception, a runtime error occurs. You will see in a moment how the exception handling works. This kind of table expression is relatively new in ABAP. In older programs, you will see the statement READ TABLE <table> INTO <target> INDEX <line>, which corresponds exactly to <target> = <table>[ <line> ]. © Copyright. All rights reserved. 117 Unit 7: Using Internal Tables Figure 122: Reading a Line by Key To identify a line by its key (by values in particular columns), you also use a table expression, but in the brackets you specify the value for which you want to search. Once again, you must leave a space after the opening bracket, after which you list the key specification in the form <column> = <value>. You can specify any number of columns in any combination. Note that there is no "AND" and no comma after each column and value. The result of the table expression is either an exception (because the line does not exist in the table) or a single line. It is, of course, possible that more than one line of the table satisfies the search criteria. In this case, the system returns the first entry that it finds in the table and then stops the search. There is no indication to you in the program that other matching entries exist. If you suspect that more than one line of the internal table will match your search criteria, you must use a technique that can process multiple lines. You will learn about this in a moment. This kind of table expression is relatively new in ABAP. In older programs, you will see the statement READ TABLE <table> INTO <target> WITH KEY <key_specification> or READ TABLE <table> INTO <target> WITH TABLE KEY <key_specification> which both correspond to <target> = <table>[ <key_specification> ]. © Copyright. All rights reserved. 118 Lesson: Working with Internal Tables Figure 123: Reading a Single Component of a Line A table expression of the form <table>[ <line specification> ] identifies a single line of an internal table. In the previous examples, we have assigned the result of the expression directly to a structure variable that has the same type as the line type of the internal table. However, you do not always need the entire line. If this is the case, you can use the table expression to address a single component of the result structure. You do this simply by adding a dash after the table expression, then specifying the name of the component that you want to address. Once you have typed the dash, you can use the code completion to display a list of components. Figure 124: Correct Error Handling If the line that you want to read using a table expression does not exist, the runtime system triggers an exception cx_sy_itab_line_not_found. You should always use a TRY…CATCH… ENDTRY block to process this exception, otherwise a runtime error will occur. If you just want to test whether a line exists, do not use this technique – there is a special function for this purpose. © Copyright. All rights reserved. 119 Unit 7: Using Internal Tables Figure 125: Checking Whether a Line Exists The line_exists( ) function allows you to check whether a particular line exists in an internal table as part of a logical expression. In the parentheses, you write a table expression in exactly the same way as if you wanted to read the line. The system checks whether the line exists and sets the expression to true or false accordingly. This function only checks whether or not the line exists. It does not read the line. Figure 126: Reading Multiple Lines by Index Table expressions only read a single line. To read multiple lines of an internal table, you use a LOOP…ENDLOOP structure. During the loop, the lines of the internal table are placed successively into a work area that has the same type as the line type of the internal table (normally a structure). Between LOOP and ENDLOOP, you write the statements that process © Copyright. All rights reserved. 120 Lesson: Working with Internal Tables each table line. When the system reaches the ENDLOOP statement, it jumps back to LOOP and processes the next line. The simplest form of LOOP … ENDLOOP is LOOP at <internal table> INTO <work area>. with no further additions. This implements a loop over the entire internal table in which each line is processed sequentially. If you want to loop over a part of the internal table, you can specify a starting and a finishing line. LOOP AT <internal table> into <work area> FROM <start> TO <finish> starts processing at the given line and finishes at the line specified in <finish>. If you leave out <start>, the system starts at the beginning of the internal table. If you leave out <finish>, the system continues processing to the end of the internal table. Figure 127: Reading Multiple Lines by Key To process multiple lines of an internal table by specifying key fields, you use LOOP AT <internal table> INTO <target> WHERE <condition>. The where condition can contain any number of constituent expressions joined using AND and OR. Within the expressions, you can use not just the equals operator but also greater than, greater than or equal to, less than, less than or equal to, unequal, and between. Figure 128: How Many Lines Are in the Table? © Copyright. All rights reserved. 121 Unit 7: Using Internal Tables To find out how many lines an internal table contains, use the lines( ) function. In the parentheses, you specify the name of the internal table that you want to inspect. The return value of the function is an integer. Modifying and Deleting Table Entries Figure 129: Modifying a Whole Line by Key If you want to write changes from a structure back into an internal table, use the MODIFY TABLE <internal table> FROM <work area> statement. The system reads the key values of the table line from the work area and uses them to identify the line of the table that needs to be modified. It then overwrites the table line with the contents of the work area. Figure 130: Modifying a Whole Line by Index © Copyright. All rights reserved. 122 Lesson: Working with Internal Tables To overwrite a particular line of the internal table, you can use the statement MODIFY <internal table> FROM <work area> INDEX <line>. This overwrites the specified line with the contents of the structure. Figure 131: Modifying a Table Entry Directly You can modify the contents of a single field in a single line of an internal table very easily using a table expression. In the table expression you identify the line of the table with which you want to work, using either the line number (as shown here) or a key expressions. You then append the name of the field that you want to change and assign the new value after the equals sign. Figure 132: Modifying Table Entries in a Loop There will often be times when you need to modify the contents of every line of an internal table. To do this, you implement a loop over the entire table, which places each line of the © Copyright. All rights reserved. 123 Unit 7: Using Internal Tables table successively into a work area. Within the loop, you change the contents of the structure components, and you must then write the changes back into the internal table before the ENDLOOP statement. If you do not do this, the changes will be lost when the current line is overwritten by the next line. When you process an internal table in a loop, the system knows which line it is currently working on. Consequently, you can use a special short form of the MODIFY statement in this context, namely MODIFY <internal table> FROM <work area>. The line number of the line that you want to modify is missing from the statement, but the system knows to modify the current line within the loop processing. If you use this short form outside of LOOP…ENDLOOP, the system does not know which line to modify and triggers a runtime error. Figure 133: Deleting Table Entries To delete an entry from an internal table, you must once again choose whether you want to identify it by its key or its index. In the key access at the top of the figure, the system reads the key values from the work area and uses them to identify the line of the internal table that should be deleted. In the index access, the system simply deletes the line of the internal table that you specify. Deleting a line from an internal table causes a gap in the line numbering. The system closes this gap automatically by moving subsequent lines up in the table. © Copyright. All rights reserved. 124 Lesson: Working with Internal Tables Figure 134: Deleting the Entire Contents of an Internal Table To delete the entire contents of an internal table, use the CLEAR statement exactly as you would with a simple variable or structure. The statement deletes the contents of the internal table and releases excess memory. After the CLEAR statement, the table still exists and you can refill it. The system restores the amount of memory reserved for the table to an initial size. The initial size is calculated so as to allow you to fill the table again without it taking too long, but at the same time not to take up too much memory. LESSON SUMMARY You should now be able to: ● Work with internal tables © Copyright. All rights reserved. 125 Unit 7 Learning Assessment 1. When you declare an internal table type, you must specify the number of lines that the table should have. Determine whether this statement is true or false. X True X False 2. Which of the following attributes are essential parts of the definition of an internal table type? Choose the correct answers. X A Storage type X B Line type X C Access type X D Key components 3. To add lines to an internal table, you can use the VALUE expression. Which of the following statements regarding the VALUE expression are true? Choose the correct answers. X A You can only add one line to the table at a time. X B You can specify the contents of the line(s) that you want to add either in the form of a structure or as a series of single values. X C The existing contents of the internal table will be overwritten unless you use the BASE addition. X D The lines that you want to add can be taken directly from an internal table. © Copyright. All rights reserved. 126 Unit 7: Learning Assessment 4. For which operations can you use the table expression itab[ <line-spec> ]? Choose the correct answers. X A To read a line. X B To insert a new line. X C To delete a line. X D To modify a line. 5. What is the effect of the statement CLEAR itab? Choose the correct answer. X A The contents of the table are deleted. X B The contents of the table are deleted and surplus memory is released. X C The table object is completely destroyed and can no longer be addressed in the program. X D The contents of the first line of the table are deleted. © Copyright. All rights reserved. 127 Unit 7 Learning Assessment - Answers 1. When you declare an internal table type, you must specify the number of lines that the table should have. Determine whether this statement is true or false. X True X False 2. Which of the following attributes are essential parts of the definition of an internal table type? Choose the correct answers. X A Storage type X B Line type X C Access type X D Key components 3. To add lines to an internal table, you can use the VALUE expression. Which of the following statements regarding the VALUE expression are true? Choose the correct answers. X A You can only add one line to the table at a time. X B You can specify the contents of the line(s) that you want to add either in the form of a structure or as a series of single values. X C The existing contents of the internal table will be overwritten unless you use the BASE addition. X D The lines that you want to add can be taken directly from an internal table. © Copyright. All rights reserved. 128 Unit 7: Learning Assessment - Answers 4. For which operations can you use the table expression itab[ <line-spec> ]? Choose the correct answers. X A To read a line. X B To insert a new line. X C To delete a line. X D To modify a line. 5. What is the effect of the statement CLEAR itab? Choose the correct answer. X A The contents of the table are deleted. X B The contents of the table are deleted and surplus memory is released. X C The table object is completely destroyed and can no longer be addressed in the program. X D The contents of the first line of the table are deleted. © Copyright. All rights reserved. 129 UNIT 8 Open SQL Lesson 1 Understanding Open SQL 131 Lesson 2 Creating Database Tables 139 Lesson 3 Reading Data from the Database 141 Lesson 4 Preview: Core Data Services in SAP S/4HANA 149 UNIT OBJECTIVES ● Understand Open SQL ● Create a database table ● Read data from the database ● Understand the role of Core Data Services © Copyright. All rights reserved. 130 Unit 8 Lesson 1 Understanding Open SQL LESSON OBJECTIVES After completing this lesson, you will be able to: ● Understand Open SQL Open SQL Architecture Figure 135: Database Table SAP systems run on relational database management systems. In the past, SAP did not produce a system for a particular database system, so an SAP Business Suite system could run on Oracle, MS SQL Server, DB2, MaxDB, and others – including latterly, of course, SAP HANA. The difference with SAP S/4HANA is that it is developed exclusively for SAP HANA as the underlying database. In a relational database, information is stored in two dimensional tables, in which each row represents one data record whose contents are split up into columns. The database is known as a relational database, as there are also relations between tables. For example, the table in the figure contains an airline code. In the database table, there would be a relationship to a further table containing the information that AA stands for American Airlines, LH for Lufthansa, QF for Qantas, and so on. A sequence of columns at the beginning of each database table forms its key. The key is a combination of values that ensures that each row in the table can be identified uniquely. © Copyright. All rights reserved. 131 Unit 8: Open SQL Database tables in SAP systems are repository objects, and as such, are cross-client. However, the vast majority of tables contain business data, which is client-specific. To keep the data separate, client-specific tables have a client field (often named MANDT) as their first key field. SAP's own database access statements – Open SQL – ensure that a statement only manipulates data from the current client. Figure 136: Structured Query Language – SQL All relational database systems use a variant of Structured Query Language (SQL) to allow you to work with them, and SAP HANA is no exception. There are three main pillars of SQL: Data Manipulation Language (DML): DML comprises the statements that you need to work with information in database tables. These are INSERT for adding new records, SELECT for reading data, UPDATE to change existing records, and DELETE to delete table contents. These statements are reflected in ABAP in the form of Open SQL. Data Definition Language (DDL): Data Definition Language provides commands for creating and deleting database tables and other database artefacts such as schemata, table indexes, and views. In an SAP system, you perform these tasks using the ABAP Dictionary, not with ABAP programs. Data Control Language (DCL): Data Control Language is used in SQL to restrict access to data in the database for a particular user. It is not used in its classic form in ABAP, since the users at database level do not correspond one-to-one with the end users. Consequently, ABAP has its own authorization concept. © Copyright. All rights reserved. 132 Lesson: Understanding Open SQL Figure 137: Open SQL Architecture In the past, SAP systems had to support a range of database platforms, and each platform had a slightly different implementation of the SQL standard. This meant that each platform needed slightly different commands to achieve a particular task. To avoid the ABAP code being database-specific, SAP invented Open SQL. This is an abstract set of SQL commands implemented at ABAP level. As it happens, none of the databases that SAP supports could understand Open SQL by themselves. To translate Open SQL into a variant that the database understands, the system uses the database interface. Even though SAP S/4HANA only runs on SAP HANA, SAP has still retained the concept of Open SQL and the database interface. This is for the following reasons: ● Architecture compatibility – Open SQL and the database interface are an integral part of the system architecture. ● Code compatibility – Open SQL coding from previous SAP products (including customerspecific development) should run free of side-effects in an SAP S/4HANA system. ● Built-in features of the database interface – the database interface does not just translate statements. It is also responsible for automatic client handling and for managing the SAP table buffer. In cases where Open SQL proves insufficient, you can use the underlying Native SQL of the database system to access the database. SAP strongly discourages you from using Native SQL to perform tasks that can be achieved using Open SQL. In the case of SAP HANA, it can be beneficial in terms of performance to use built-in features of Native SQL. In this case, we recommend that you use ABAP Managed Database Procedures (AMDP). © Copyright. All rights reserved. 133 Unit 8: Open SQL Figure 138: Database Tables and CDS Views In the SAP S/4HANA system, all of the data is stored in database tables. From an ABAP program, you can access the tables directly to read the information. However, in reality, it is not so simple. To collect all of the data together that belongs to a particular business entity, you almost always have to read more than one table. In SAP S/4HANA, these entities are represented in the ABAP Dictionary by Core Data Service (CDS) Views. Views are a logical collection of information that comes from more than one database table. In the definition of the view, you find the fields that it contains but also the conditions for combining the tables (for example, line items from a line item table match an order header from the headers table when the order number on both sides is the same). SAP /4HANA contains what is known as a Virtual Data Model (VDM). The VDM is a hierarchy of CDS views that read, combine, and process data from different database tables in all of the different ways that the business applications require. As well as describing how to read data from the database, CDS views also contain important information that enable the system to generate views for the user interface and the OData services that allow the frontend and backend systems to communicate. Thus they are a central pillar in the SAP S/4HANA programming model. In Open SQL in ABAP, there is no difference in how you read data, regardless of whether you read it directly from a database table or using a CDS view. © Copyright. All rights reserved. 134 Lesson: Understanding Open SQL Figure 139: Database Tables in the ABAP Dictionary To define a database table in an SAP S/4HANA system, you use the ABAP Dictionary. The definition contains a list of fields, each one with a type that is described by a data element. A combination of fields at the beginning of the table structure defines the key, which identifies each record uniquely. From the definition of a database table, you can also display its content by choosing the function highlighted in the figure. Figure 140: CDS Views in the ABAP Dictionary CDS views are also ABAP Dictionary objects, but you edit them using a source code editor rather than a form-based one as is the case with database tables. © Copyright. All rights reserved. 135 Unit 8: Open SQL A CDS view can be a selection of fields from a single table, as shown here, or a combination of fields from different tables. CDS views also contain annotations. Annotations provide information about the view or individual fields in it that goes beyond the simple instruction "Select this field from that table". The system of annotations is open, so that any framework can add its own metadata to the definition of a CDS view without altering the basic SQL definition. To open the data preview for a CDS view, press F8. The Flight Data Model Figure 141: The ABAP Training Flight Data Model Figure 142: Table SCARR The database table SCARR contains a list of airlines, including their airline code and full name. In other tables in the data model, only the code is used. © Copyright. All rights reserved. 136 Lesson: Understanding Open SQL Figure 143: Table SPFLI Table SPFLI contains a list of flight connections. Each connection is identified by an airline code (which must be present in table SCARR) and a flight number. These details are followed by information about the departure and arrival airports, cities, and countries of the flight, and its departure and arrival times. Figure 144: Table SFLIGHT This table contains a list of actual flights for each connection. Whereas SPFLI defines that LH 400 flies from Frankfurt to New York, SFLIGHT contains an entry for each day on which LH 400 actually flies, along with the price of the flight, type of airplane used, and the number of available seats. © Copyright. All rights reserved. 137 Unit 8: Open SQL LESSON SUMMARY You should now be able to: ● Understand Open SQL © Copyright. All rights reserved. 138 Unit 8 Lesson 2 Creating Database Tables LESSON OBJECTIVES After completing this lesson, you will be able to: ● Create a database table Creating a Database Table Figure 145: Creating a Database Table There are three stages to creating a database table: 1. Delivery and Maintenance attributes. On this tab, you specify the delivery class for the table and whether users should be able to display and change table contents using the Data Browser (transaction SE16). By far the most common delivery class, and the one that you will use for the vast majority of your own tables, is A for Application Table. This class covers both master data and transactional data. Choose the appropriate option from the dropdown list Data Browser/Table View Editing to determine whether users can see the table contents in transaction SE16. 2. Fields. On this tab, you specify the actual fields that the table has. Remember the client field, as you need to be able to store client-specific data in a table object that is crossclient. For each field, you need a data element that specifies the type. Mark the Key column for each field that is to be part of the table key. © Copyright. All rights reserved. 139 Unit 8: Open SQL 3. Technical Settings. The technical settings of the table are information that is not part of the table definition itself, but that the system needs (or at least finds useful). In SAP S/ 4HANA, the most important attribute is the storage type of the table. As a rule, you should set this to Column Store. You also need to specify the data class (APPL0 for master data and APPL1 for transactional data), and the size category of the table. This provides the system with information about the predicted size of the table. It is definitely not an upper limit for the table size! In the technical settings, you can also set the buffering options for the table. The majority of tables are not suitable for buffering, sometimes because they are too big, but mostly because their contents keep changing. Once you have maintained all three sections of the table definition, you can activate it. Common reasons for the activation failing are either that you have forgotten to maintain the technical settings of the table or that you have forgotten to mark the key fields of the table. When you activate the definition of a database table in ADT, the system creates the corresponding physical table object in the database. LESSON SUMMARY You should now be able to: ● Create a database table © Copyright. All rights reserved. 140 Unit 8 Lesson 3 Reading Data from the Database LESSON OBJECTIVES After completing this lesson, you will be able to: ● Read data from the database The SELECT Statement Figure 146: The SELECT Statement To read data from the database, you use the SELECT statement. It makes no difference if you are accessing a database table directly or reading data using a CDS view. When you write a SELECT statement in Open SQL, the syntax check compares what you have written with the definitions of the tables and CDS views in the ABAP Dictionary. If you try to address tables, views, or fields that do not exist, a syntax error occurs. When you run your program, the database interface translates the Open SQL statement into a corresponding Native SQL statement. The database executes the statement and returns the result to the database interface. The database interface passes the result back to the ABAP program. © Copyright. All rights reserved. 141 Unit 8: Open SQL Figure 147: Syntax of the SELECT Statement The basic syntax of the SELECT statement contains several sections – called clauses – and always follows the pattern in the figure. The first thing that you specify after SELECT is the source of the data, in the FROM clause. This can be either a database table or a CDS view. Reading data from the database – even an in-memory database like SAP HANA – can be time-consuming. To ensure that it does not take too long to retrieve the data, and to make sure that the user sees data that he or she actually needs, rather than the entire contents of a table, it is important only to transfer data that you need. There are, of course, two ways to do this – firstly by only transferring the columns that you need, and secondly by restricting the data selection to rows that meet certain selection criteria. In the FIELDS clause of the SELECT statement, you list the columns of the database table that you want to read. The columns in the list must be separated by commas. If you want to read the entire table line, you can specify FIELDS * instead of a column list. Be aware, however, that this can cause the SAP HANA database considerably more work than just reading the columns you need. In the WHERE clause, you can specify a condition that describes which rows of the table will be read. For example, the condition WHERE carrid = 'LH' means that only those rows will be read in which the column CARRID contains the value LH. The WHERE clause can contain multiple conditions linked with the AND and OR operators. For example, WHERE carrid = 'LH' and FLDATE > sy-datum would return all Lufthansa flights with a departure date in the future. You can also negate conditions using NOT. At the very end of the SELECT statement comes the INTO clause. This specifies the variable in the ABAP program into which the data should be placed. This is normally a structure or an internal table and should ideally have the same sequence of components as the column list in the FIELDS clause. Note that you will see other forms of SQL syntax in ABAP. These are older and have been retained to ensure compatibility. You should get used to using the modern syntax, as it provides far more functions and features than the old form. Furthermore, only the new form supports selections using CDS views. © Copyright. All rights reserved. 142 Lesson: Reading Data from the Database Figure 148: Field Lists and ABAP Variables Whenever you write a list of fields in a SELECT statement, you must separate the field names using commas. In the example, this applies to the FIELDS clause. Later, in more advanced queries, you will find that it also applies to the GROUP BY and ORDER BY clauses. Wherever you use an ABAP variable in a SELECT statement, you must prefix it with the @ character. This indicates to the SQL parser (part of the ABAP compiler) that the variable comes from ABAP and not from the database. You need the @ symbol both when you pass a value to the statement (as in the WHERE clause) and when you receive data from the statement (as in the INTO clause). Figure 149: Selecting a Single Row into a Structure The SELECT SINGLE statement reads a single entry from the specified database table. If the entry exists, the system places it into the variable listed in the INTO clause. If it does not exist, © Copyright. All rights reserved. 143 Unit 8: Open SQL the contents of the variable remain unchanged, and the system sets the return code field sysubrc to 4. The SELECT SINGLE statement searches the table until it finds one record that meets the specified condition, at which point it stops searching. Even if there is more than one table entry that satisfies the condition, the system only returns the first. There is not even a warning that there were (or might have been) other matches. SELECT SINGLE is particularly useful if the WHERE clause contains a single value for every key fields of the table. By specifying a single value for every key fields of a database table, you identify a unique record. If you need the capability to process more than one record, use a different variant of the SELECT statement. Figure 150: Selecting Multiple Rows into an Internal Table To select multiple rows from a database table, you can use the SELECT… INTO TABLE variant of the SELECT statement and place all of the rows directly into an internal table in your program. © Copyright. All rights reserved. 144 Lesson: Reading Data from the Database Figure 151: Selecting Multiple Rows Using a Loop A further variant of SELECT is the SELECT loop. In this case, you read multiple rows from the database, but place them successively into a structure. The statements between LOOP and ENDLOOP are executed for each row that you have read. If you want to keep a row beyond the end of the loop, you must insert it into an internal table. Figure 152: Correspondence Between FIELDS and INTO The INTO or INTO TABLE clause of the SELECT statement will only work correctly if the number and types of the components of the structure or the line type of the internal table correspond to the number and types of the columns specified in the FIELDS clause. In the above example, the statement can only work if the structure gs_connection has four components with the same type and length as the columns carrid, connid, cityfrom, and cityto © Copyright. All rights reserved. 145 Unit 8: Open SQL of the database table. Note that, in this case, the names do not have to be identical – the system fills the target structure from left to right. If the field list in the FIELDS clause does not match the structure or table line type in the INTO clause, a runtime error will occur. Figure 153: INTO CORRESPONDING FIELDS If the fields of the FIELDS clause and the components of the structure in the INTO clause do not match, you can use the variant INTO CORRESPONDING FIELDS or INTO CORRESPONDING FIELDS OF TABLE. This has the same effect as the CORRESPONDING #( ) operator that you learned about earlier and ensures that data is copied between identically named components. Once again, only the names must be identical. If identically named components have different types, the system attempts to convert the contents of the source field into the type of the target field. You must bear in mind that even if this operation does not cause a runtime error, data may still be lost due to the conversion rules. © Copyright. All rights reserved. 146 Lesson: Reading Data from the Database Figure 154: Data Transfer from the Database to the Program When you read data from the database, the database interface requests it from the database, which transfers it in packages to the application server. The database interface optimizes this process so as to read the data as quickly as possible. The database interface then passes the data to the program according to the way you programmed the SELECT statement. For SELECT SINGLE this means that the single line is transferred into the corresponding structure. In the case of SELECT INTO TABLE, the internal table is filled in a single transfer. If you choose SELECT…ENDSELECT, the rows are transferred individually from the database interface to the program. The key to efficient Open SQL programming in ABAP is to transfer as little data as possible from the database to the program. You can do this by using a list of columns in the FIELDS clause of the SELECT statement – then you do not transfer the entire row, but only the columns you actually need. The second way to do it is to formulate a WHERE clause that describes as precisely as possible the rows of the table that you need. Figure 155: Expressions in the FIELDS Clause In addition to reading data from the database, the SELECT statement also allows you to process it in expressions. For example, the database table SFLIGHT contains the number of occupied seats for each flight and the number of seats that are actually booked. This example shows how you can get the database to calculate the number of free seats and return it as part of the result set of the SELECT statement. © Copyright. All rights reserved. 147 Unit 8: Open SQL When you perform a calculation like this in the SELECT statement, the system generates a new column for it in the result set. Because it does not represent a column from one of the database tables, it initially has no name. It is at least good practice – and in some cases mandatory – to name the column using the notation AS <name>. The calculated column is then known by this name in the rest of the SELECT statement and in the ABAP program. For further information on how to use expressions in the SELECT statement, refer to the ABAP documentation for SELECT. Figure 156: Expressions in the WHERE Clause Another place in which you can use expressions in the SELECT statement is in the WHERE clause. This is particularly useful for performance reasons, as you can further restrict the data that you read. In this example, the SELECT statement only reads the flights with fewer than ten free seats. Without the possibility to do this directly in the WHERE clause, you would have to read all of the flights from the database and then decide by performing the calculation in the program which records to keep and which to discard. This calculation is a very simple example of code push-down. Code push-down in the context of SAP HANA and SAP S/4HANA means getting the database to perform calculations rather than performing them in the program on data that has already been read. The aim is that the results of the calculations can filter out unwanted data before it is transferred to the program, thus speeding up the data transfer. You will hear about code push-down in the context of Open SQL, Core Data Services, and ABAP-Managed Database Procedures. LESSON SUMMARY You should now be able to: ● Read data from the database © Copyright. All rights reserved. 148 Unit 8 Lesson 4 Preview: Core Data Services in SAP S/4HANA LESSON OBJECTIVES After completing this lesson, you will be able to: ● Understand the role of Core Data Services Joins and Core Data Services Figure 157: Understanding a Data Record In a relational database management system (RDBMS), there are strict design rules that are intended to save space in the database (a hug consideration in the 1970s and 1980s) and to preserve the integrity of the data. Even if storage space is no longer such an issue, data integrity is important enough for these rules to have stuck around! One important rule is that the system must not store data redundantly. The consequence of this in a table of flight bookings is that we see the flight number, consisting of airline and connection number, but not any other information about the flight, such as its departure and arrival cities and times. The reason for this is simple; the flight number identifies a connection uniquely, and any other information stored in the flight booking record would have to be duplicated for each booking and would therefore be redundant and liable to data inconsistency. The same applies to the customer information. The booking record contains the number of the customer, but not his or her name and address. In order to present the full details of a flight booking to the end user, we therefore need to consult more than just this table. This is the norm in SQL programming and in this case we © Copyright. All rights reserved. 149 Unit 8: Open SQL can consider ourselves fortunate that we only have to read three tables and not a whole lot more. Figure 158: Joining Tables In the SELECT statement, you can read from more than one table in a single operation using a table join. In it, you specify the columns that you want to read, the tables from which they come, and also under what conditions a record from one table matches one from another. In this example, we are reading from the bookings table SBOOK, which contains a customer number in the column CUSTOMID. In order to find the customer details, we need to use the customer number to find the corresponding entry in table SCUSTOM. We also need to use the combination of CARRID and CONNID to find the details of the connection. While table joins are relatively simple to implement in ABAP, they have the disadvantage that you need to rewrite them in every program. Furthermore, each programmer needs to understand the relationship between the different tables in the data model in order to be able to write the joins correctly. Figure 159: Hiding Complexity with Core Data Services © Copyright. All rights reserved. 150 Lesson: Preview: Core Data Services in SAP S/4HANA In ABAP, you can use views to create reusable join definitions in the ABAP Dictionary. Dictionary Views have existed for a long time, but the recommended way to create views from AS ABAP Release 7.40 onwards is to use Core Data Services, because they provide a far greater range of functions. The simplest kind of CDS view is one that replaces a join in a SELECT statement. In other words, the relationships between the database tables from which you want to read are described in the view object instead of in the SELECT statement in an ABAP program. However, CDS views can also contain advanced functions such as case distinctions and currency conversions. As well as the actual view definition, CDS views can also contain metadata in the form of annotations. This is not information that describes how to read the data from the database, but instead what should happen with the data in a particular context. Frequently used annotations describe whether the CDS view should be used as the basis for an SAP Gateway service, how the fields from the view should be prioritized by the user interface, or how they should behave in an analytical application. You can learn more about CDS views in class S4D430. Figure 160: Simple Core Data Service Views In this example, there is a simple view that defines a join between two tables. It specifies that a line from the database table spfli fits a line from the table scarr when the value of the airline carrid matches. A program that uses this view does not have to understand the underlying data model – it can just consume the view and will receive the correctly arranged data. © Copyright. All rights reserved. 151 Unit 8: Open SQL Figure 161: Complex Core Data Services This example of a Core Data Service view is more complex. It does not just contain the definition of a database view, but there are also various annotations. Annotations provide information about a particular aspect of a view that is not directly related to reading the data from the database. Here, there is an annotation @OData.publish: true, which indicates that the system should generate an OData service when the view is activated. The @UI annotations provide guidance to the system as to how it should generate a Fiori Elements user interface based on the view. LESSON SUMMARY You should now be able to: ● Understand the role of Core Data Services © Copyright. All rights reserved. 152 Unit 8 Learning Assessment 1. Which of the following statements regarding Open SQL are true? Choose the correct answers. X A Open SQL is specific to SAP HANA X B Open SQL supports automatic client handling. X C Open SQL allows you to read directly from database tables, but also to use Core Data Service views. X D You use Open SQL to create database tables in the SAP System. 2. You can create database tables for the SAP System either using the ABAP Dictionary or the database management studio. Determine whether this statement is true or false. X True X False 3. Which of the following statements regarding the key of a database table are correct? Choose the correct answers. X A The key determines the order in which entries in the table will be stored. X B The combination of key fields identifies each row uniquely. X C The key must not have more than five fields. X D The key is mandatory. © Copyright. All rights reserved. 153 Unit 8: Learning Assessment 4. You use SELECT SINGLE to read a single row from a database table. What happens if there is more than one row in the table that meets the condition that you specified? Choose the correct answer. X A The statements returns all rows that correspond to your selection. X B The statement merely returns the first row that corresponds to your selection. X C An exception occurs. X D The system sets sy-subrc to a value unequal to zero. 5. When would you use the addition SELECT... INTO CORRESPONDING FIELDS ? Choose the correct answer. X A When you only want to read one row from a table. X B When you want to read multiple rows from a table. X C When the list of fields is identical to the structure of your target variable. X D When the list of fields is different from the structure of your target variable. © Copyright. All rights reserved. 154 Unit 8 Learning Assessment - Answers 1. Which of the following statements regarding Open SQL are true? Choose the correct answers. X A Open SQL is specific to SAP HANA X B Open SQL supports automatic client handling. X C Open SQL allows you to read directly from database tables, but also to use Core Data Service views. X D You use Open SQL to create database tables in the SAP System. 2. You can create database tables for the SAP System either using the ABAP Dictionary or the database management studio. Determine whether this statement is true or false. X True X False 3. Which of the following statements regarding the key of a database table are correct? Choose the correct answers. X A The key determines the order in which entries in the table will be stored. X B The combination of key fields identifies each row uniquely. X C The key must not have more than five fields. X D The key is mandatory. © Copyright. All rights reserved. 155 Unit 8: Learning Assessment - Answers 4. You use SELECT SINGLE to read a single row from a database table. What happens if there is more than one row in the table that meets the condition that you specified? Choose the correct answer. X A The statements returns all rows that correspond to your selection. X B The statement merely returns the first row that corresponds to your selection. X C An exception occurs. X D The system sets sy-subrc to a value unequal to zero. 5. When would you use the addition SELECT... INTO CORRESPONDING FIELDS ? Choose the correct answer. X A When you only want to read one row from a table. X B When you want to read multiple rows from a table. X C When the list of fields is identical to the structure of your target variable. X D When the list of fields is different from the structure of your target variable. © Copyright. All rights reserved. 156 UNIT 9 Object-Orientation in ABAP Lesson 1 A Short History of ABAP 158 Lesson 2 Modeling a Class 161 UNIT OBJECTIVES ● Understand the emergence of object-orientation ● Be able to create and understand a simple UML model © Copyright. All rights reserved. 157 Unit 9 Lesson 1 A Short History of ABAP LESSON OBJECTIVES After completing this lesson, you will be able to: ● Understand the emergence of object-orientation The Evolution of Programming Figure 162: The Beginning – Spaghetti Programming In the early days of programming, no real consideration was given to how to structure the code. Developers simply started at the top of the program and finished at the bottom. To control the program flow, they used GOTO statements, which gave them the freedom to jump backwards and forwards in the program to any line they needed. Unfortunately, this way of programming made maintenance and debugging almost impossible, so while it was an acceptable way of programming if you needed a program once to solve a problem in an academic research project, it was not helpful as soon as product maintenance and support became an issue. © Copyright. All rights reserved. 158 Lesson: A Short History of ABAP Figure 163: Procedural Programming – Function Encapsulation A later phase of programming was procedural programming. Driven by the conviction that programs needed more structure than spaghetti coding, architects devised the concept of encapsulating functions in procedures. This had two main advantages – it made the flow of a program easier to understand, and it also meant that the procedures could be reused at different points in the program. As time went on, the idea of reuse was extended to provide reuse not just in one program, but across multiple programs through the concept of procedure libraries. ABAP also had its own procedure libraries in the form of subroutine pools (a very long time ago) and function groups (up to the present day). For many years, ABAP supported procedural programming by providing subroutines and function modules. The drawback to this approach was, however, that all of the procedures in the program have unrestricted access to all of the data. While the separation of functions into procedures makes it easier to locate errors in the code, data inconsistencies become very difficult to solve, since it is not clear which parts of the program changed which data. Figure 164: Object-Oriented Programming – Data Encapsulation © Copyright. All rights reserved. 159 Unit 9: Object-Orientation in ABAP Moving on from procedural programming, the architects of programming languages started to look towards representing whole, real-world entities in a program. Instead of just working with relational models as you would find them at database level, they created representations of these objects in their programs. Thus the object-oriented paradigm was born. An object corresponds to a real-life object such as an employee, a vehicle, or, in our case, a flight. It has attributes that describe it – in the case of a flight, that might be the airline, the flight number, the number of available seats and the number that are occupied. Now let us consider what happens when a program that is using this object wants to create a booking. It obviously – at least to us – makes sense that the flight should not have more bookings than available seats. Under the procedural paradigm, every program that wants to book a flight must remember to ensure that it is not overbooked – and here is the point at which things could go wrong! In object-orientation, the client program cannot just create a booking by adding one to the number of filled seats. Instead, it would call a function - called a method in object-orientation to perform this task. The method, which is part of the object itself, checks whether the flight is overbooked. If it is, it refuses to create a new booking. Otherwise, the new booking is created. This concept is called data encapsulation. The information about the flight is managed by the flight object itself, and cannot be manipulated by anyone else. This ensures that no other point in the program can bypass the check of the number of free seats – either knowingly or unknowingly. Outside of the object itself, as you will learn later, the data is not visible at all – it can only be changed by the object itself. This is one of the major advantages of objectorientation. LESSON SUMMARY You should now be able to: ● Understand the emergence of object-orientation © Copyright. All rights reserved. 160 Unit 9 Lesson 2 Modeling a Class LESSON OBJECTIVES After completing this lesson, you will be able to: ● Be able to create and understand a simple UML model Modeling a Class Figure 165: Classification of Objects – What Is a Vehicle? One of the main principles of object orientation is to describe an object, but how do you do that when there are lots of different ways of looking at the same thing? To a car manufacturer, a car has a bill of materials stretching to around 30000 different components. To the consumer, however, the car looks quite different and merely has a make, model, color, engine size, top speed, and whatever other favorite features you happen to have! A car rental firm will have yet another view of the vehicle, the licensing authorities another, and so it goes on. When you create a description of an object in an object-oriented application, you describe the aspects of it that are important and relevant to your application. If you are implementing an application to manage car rentals, the licensing authority's view of the vehicle is inappropriate. If you are a car manufacturer, the consumer's view of a car is not sufficiently detailed. In short, different applications that deal with vehicles in different ways will describe them differently according to their needs. © Copyright. All rights reserved. 161 Unit 9: Object-Orientation in ABAP Figure 166: Classification of Objects – Describing an Entity The first task in object-oriented programming is not programming at all – it is to identify and describe all the entities (just a complicated word for "things") in your program. You start off by doing this on paper or by using modeling software. The standard language that has established itself over time is the Unified Modeling Language (UML), which was invented at Rational Software during the 1990s. You can find the full specification of UML at http:// www.omg.org/spec/UML. There are also various Eclipse-based tools that support UML modeling. The figure above shows a simple description of a vehicle. The description contains two sections – the attributes of the vehicle, which describe its state, and the methods, which describe the functions that you can perform on a vehicle. In total, the description is called a class. Attributes and methods of classes are optional; theoretically, you could have a class with only attributes. This would allow you to store information about a particular thing without there being any special functions to manipulate it. Although unusual, it would be possible. You could also have a class with only methods; the class is then just a container for functions instead of managing the state of an object. Sometimes, you will see this kind of class used for helper functions in an application as an alternative to using subroutines or function modules. © Copyright. All rights reserved. 162 Lesson: Modeling a Class Figure 167: Classes and Objects A class is a description of an object – it does not represent a real-life thing. In this respect, it is like a data type; the data type of a structure describes the components that a structure of that kind would have, but you need a variable in order to store real data. A class describes what makes up a vehicle, but you need an object in order to represent an actual vehicle in your application. You can have any number of objects that are derived from the same class. Each represents one particular instance of the entity that the class describes. The words object and instance are synonymous. All objects are simultaneously identical and independent of one another. Identical: The elements that make up each vehicle are the same in each case – every vehicle has a make and a model. Independent: The state of each object is independent of that of all other objects. Each object can be manipulated completely independently of all other instances of the same class. © Copyright. All rights reserved. 163 Unit 9: Object-Orientation in ABAP Figure 168: Visibility of Components In a class, every attribute, method, or other component must have a defined visibility. Public components are visible both within the class itself and to all users of the class. Private components, on the other hand, are only visible within the class, and cannot be accessed directly by a program that is using the class. A guiding principle of object-oriented modeling is to make as many components public as necessary, but as few as possible. Private components allow you to ensure the consistency of classes in the following ways: Private attributes can only be changed within the class. This eliminates the possibility that a program can change the value without knowing the business rules that govern the possible values and consistency of the attribute. To allow programs to change the values of attributes, you provide public methods to which the program can pass a value. The method then checks that the value is acceptable, and sets the new value of the attribute accordingly. Private methods allow you to modularize your code within a class. If two or more methods require exactly the same coding, you can put the common code into a separate method. Since this code is then only one part of a bigger function, it makes sense to make the method private so that a program that is unfamiliar with the structure and implementation of the class cannot call it by mistake. In UML, public components are denoted with a plus sign and private components with a minus sign. © Copyright. All rights reserved. 164 Lesson: Modeling a Class Figure 169: Instance Components Normally, each attribute and method that you define for a class exists separately in each instance of the class. However, there are sometimes cases where this is not a good idea. In the figure above, we have extended the vehicle class to contain a list of permitted vehicle makes. The list is used to check that each new vehicle make is actually allowed. However, because the attribute is an instance attribute, each instance of the class has a copy of the vehicle list. This is ineffective, and a waste of memory; the vehicle list is actually identical for all instances of the class and only really needs to be held once for the entire class. Figure 170: Static Components In this example, we have changed the attribute permitted_makes from an instance attribute to a static attribute. Static attributes do not belong to a particular instance but instead exist once only at class level. Every instance of the class can access static components. © Copyright. All rights reserved. 165 Unit 9: Object-Orientation in ABAP As well as static attributes, you can also declare static methods. You can call these methods using the name of the class, and they are accessible even if there are no instances of the class. Static methods may only access static attributes. Static attributes are useful for: look-up data that any instance of the class might need, counters to tell you how many instances of a particular class you have created. Static methods are useful for: helper functions in an application that do not really apply to a particular instance, retrieving an instance of a class when you start to work with a particular framework. In UML notation, static attributes are underlined. Figure 171: Classifying Different Kinds of Vehicles The previous figure showed the components belonging to one single class. However, most applications consist of more than one class, and the relationships between the classes are also important. For this reason, UML also provides ways of describing these relationships. This figure shows one of the most common relationships (called associations in UML) – that of generalization and specialization. On the left-hand side are three classes - vehicle, truck, and bus - that are all independent of each other. However, in reality, it is true to say that both trucks and buses are kinds of vehicle. In object-oriented modeling, we say that the vehicle class is a general class. We can then say that trucks and buses are specializations of the vehicle. This has wide-reaching (but positive) consequences in the implementation of the application. Everything that is common to all vehicles can be implemented in the vehicle class. These common components are then automatically passed on to the specialized classes, which then do not have to reimplement those features. Instead, they concentrate on the attributes and methods that only a truck or only a bus possess. © Copyright. All rights reserved. 166 Lesson: Modeling a Class Figure 172: Storing Objects Within Objects – Aggregation An attribute of a class might be an object from a different class. So, for example, a car rental company might keep a list of all of its vehicles, and each entry in the list is a vehicle object. This kind of association is called aggregation. The vehicle objects are created outside the class and then assigned to the rental class. In other words, a vehicle can survive outside the rental class. Figure 173: Storing Objects Within Objects – Composition Here, we see a special kind of aggregation. The example has changed, and we are now looking at a fictive example from the user interface world. Imagine a UI control that displays a table. In the table are columns, each of which is represented by an instance of a class. When we tell the table class to display the data, it creates the column objects by itself. When the table display is finished, the column objects are no longer needed and so they are © Copyright. All rights reserved. 167 Unit 9: Object-Orientation in ABAP destroyed at the same time as the table object. In other words, the entire lifecycle of the columns objects depends on the table object. This kind of aggregation is called composition. LESSON SUMMARY You should now be able to: ● Be able to create and understand a simple UML model © Copyright. All rights reserved. 168 Unit 9 Learning Assessment 1. Which of the following statements about classes is true? Choose the correct answer. X A Attributes of a class are always private. Methods of a class are always public. X B A class must always have both private and public elements. X C You can create any number of independent instances of a class X D You use classes to make large quantities of global data available to a program. © Copyright. All rights reserved. 169 Unit 9 Learning Assessment - Answers 1. Which of the following statements about classes is true? Choose the correct answer. X A Attributes of a class are always private. Methods of a class are always public. X B A class must always have both private and public elements. X C You can create any number of independent instances of a class X D You use classes to make large quantities of global data available to a program. © Copyright. All rights reserved. 170 UNIT 10 Creating and Using Classes Lesson 1 Creating Classes 172 Lesson 2 Creating Objects 179 Lesson 3 Calling Methods 183 Lesson 4 Using Constructors 189 Lesson 5 Using Factory Methods 192 UNIT OBJECTIVES ● Create a class ● Create objects in ABAP ● Call methods ● Use constructors ● Use factory methods © Copyright. All rights reserved. 171 Unit 10 Lesson 1 Creating Classes LESSON OBJECTIVES After completing this lesson, you will be able to: ● Create a class Creating Classes in ABAP Figure 174: Local And Global Classes Classes in ABAP can be either local or global. You define local classes as part of an ABAP program and you can only use them in the program in which they are defined. Local classes are useful for entities or functions that you only need in a single program. Global classes are contained in their own Repository object called a class pool. They are stored centrally and can be used by all other ABAP programs (including other classes and function groups). The ABAP syntax of both local and global classes is almost identical. In this course, you will be working with local classes. © Copyright. All rights reserved. 172 Lesson: Creating Classes Figure 175: Local Classes in ABAP The declaration of a class has two sections – the definition and the implementation. The definition part of a class contains the declaration of all of the elements in the class, that is, the attributes, methods, types, and constants. As you have already learned, each element in a class has a particular visibility – public or private. You set the visibility of an element by definining it in the relevant section. The PUBLIC SECTION statement introduces the public section of the class. Any elements that you declare after PUBLIC SECTION and before the introduction of the next section are public. The public section of the class does not have an explicit closure; in our example, it ends where the private section begins. All elements that you define after PRIVATE SECTION are private. The private section ends at the ENDCLASS statement. There is also a PROTECTED SECTION, which is relevant to inheritance, and which you will learn about in the unit covering that subject. The declarations of the visibility sections in your class must follow the order PUBLIC SECTION - PROTECTED SECTION- PRIVATE SECTION. However, the sections are optional; if you do not need a particular section, you do not have to declare it. You must not declare any elements of the class between the CLASS <class> DEFINITION statement and the first visbility section that you declare, as this causes a syntax error. © Copyright. All rights reserved. 173 Unit 10: Creating and Using Classes Figure 176: Definition Part of a Class The figure shows the different kinds of elements you can define in a class. You can create any of these kinds of elements in any visibility section of the class. The TYPES statement allows you to define types within your class. You do this in exactly the same way as you would outside a class (for example, to define a structured or internal table type). If types are public, a program that uses the class can use the type (or types) to declare ist own variables. You use DATA and CLASS-DATA to declare attributes of the class. DATA declares an instance attribute, while CLASS-DATA declares a static attribute. Classes may also contain constants. Both constants and types are static components of the class. © Copyright. All rights reserved. 174 Lesson: Creating Classes Figure 177: Method Signatures When you declare a method, you define its signature; that is, the set of values that the method exchanges with its caller and the exceptions that may arise during the method. Each parameter has a name and a type. Importing parameters are values that the method receives from the caller. By default, importing parameters are mandatory, but there are two ways to make them optional: ● Using the OPTIONAL addition. The parameter is optional and its default value is the initial value appropriate to the type of the parameter ● Using the DEFAULT <val> addition. The parameter is optional and its default value is the value that you specified as <val>. The implementation of a method may not change importing parameters. If you attempt to do so, you will cause a syntax error. Exporting parameters are results that are returned by the method. All exporting parameters are optional – a program only uses the values that it actually needs. Changing parameters are values that you pass to the method. Unlike importing parameters, the method can change the values of these parameters. They are then returned to the caller under the same name. Changing parameters are mandatory by default; you can make them optional in the same way as importing parameters. A method can have any number of importing, exporting, and changing parameters. By default, they are passed by reference. In addition to or instead of its importing, exporting, and changing parameters, a method may have one returning parameter. This is a single result value that can be used directly in an expression. Returning parameters are always passed by value. If an error occurs during a method, the method triggers an exception. The method terminates, and the calling program can then react to the error. The signature of a method must list the possible exceptions. © Copyright. All rights reserved. 175 Unit 10: Creating and Using Classes Figure 178: Declaring Attributes Of The Vehicle Class Let us start implementing our UML model in ABAP, and take the attributes of the vehicle class to begin with. All of the attributes are private, so we include them after the PRIVATE SECTION statement. To declare an attribute, use the DATA statement within the appropriate visibility section. The prefix mv_ follows the normal prefixing rule of <scope><type>_. In this context, m stands for member and v for an elementary variable. The attribute gv_no_of_veh is underlined, which denotes a static attribute. You declare static attributes using the CLASS-DATA statement. The syntax of CLASS-DATA is identical to that of DATA. In the DATA and CLASS-DATA statements, you can specify the type of the attribute as follows: Using TYPE: Use TYPE to refer to an ABAP Dictionary type, a built-in ABAP type, or a type defined locally in the class. Using LIKE: Use LIKE to declare an attribute with reference to another attribute that you have already declared. © Copyright. All rights reserved. 176 Lesson: Creating Classes Figure 179: Defining Methods Of The Vehicle Class The next step in realizing the UML model is to declare the methods in the class. The set_attributes method of the class needs two importing parameters – one for the make, and one for the model of the vehicle. By defining the method, you introduce a syntax error into your class; the syntax check tells you that the implementation of the method is missing. For every method that you define, you must also create an implementation. ADT allows you to do this using a quick fix. Position the cursor in the statement containing the error and press Ctrl + 1. A list of possible quick fixes appears, including the option Add implementation for set_attributes. When you choose this option, ADT creates the corresponding implementation of the method. Your class is now syntactically correct once again. Figure 180: Implementing Methods You must implement every method that you define. You do this in the implementation part of the class between the statements METHOD <method_name> and ENDMETHOD. © Copyright. All rights reserved. 177 Unit 10: Creating and Using Classes The method implementation contains ABAP statements that can access the parameters of the method (you are not allowed to change importing parameters) and all types, attributes, and constants that you declared in the class. Instance methods may access both instance attributes and static attributes. Static methods may only access static components. LESSON SUMMARY You should now be able to: ● Create a class © Copyright. All rights reserved. 178 Unit 10 Lesson 2 Creating Objects LESSON OBJECTIVES After completing this lesson, you will be able to: ● Create objects in ABAP Creating Objects Figure 181: Reference Variables In order to work with instances of classes in ABAP, you need a reference variable. This is a special kind of variable that you use to create, address, and manage an object. You declare reference variables using the DATA statement with the addition TYPE REF TO followed by the name of a class. Using the reference variable, you will be able to create an instance of the class that you specified. However, at the moment you declare the variable, it is initial just like any other variable in ABAP. In other words, the object does not yet exist. © Copyright. All rights reserved. 179 Unit 10: Creating and Using Classes Figure 182: Creating Instances of a Class To create a new instance of a class, you use the NEW #( ) operator. This creates a new instance of the class and places the address of the instance into the reference variable on the left-hand side of the expression. You may have noticed that the name of the class that you want to instantiate does not appear anywhere in the expression. However, the system already knows that go_vehicle has the type REF TO lcl_vehicle, and consequently it knows that it should create an instance of the class lcl_vehicle. The pound sign after the NEW operator means "use the type of the variable before the equals sign". (In more advanced scenarios, you can actually specify the name of the class in place of the pound sign). Note that there must be at least one space between the parentheses. When you address a class for the first time (which could be by creating an instance of the class), the runtime system also loads the class definition into the program memory. This contains all of the static attributes, which only exist once in the class instead of once for each instance. © Copyright. All rights reserved. 180 Lesson: Creating Objects Figure 183: Copying Reference Variables If you assign one reference variable to another, the system copies the address of the object to which the first variable is pointing into the second reference variable. The result of this is that you have two reference variables that point to the same object. Figure 184: Overwriting Reference Variables You can use the same reference variable to create more than one instance of a class. Each time you use the NEW #( ) operator, the system creates a new instance of the class and places the address of the new instance into the reference variable. However, the address of the new instance overwrites the address of the previous instance. In the example above, the address of vehicle 2 overwrites the address of vehicle 1. Consequently, there is no longer a reference variable in the program pointing to vehicle 1. When this happens to an instance, it can no longer be addressed from the program. © Copyright. All rights reserved. 181 Unit 10: Creating and Using Classes To prevent the program memory from becoming filled with objects that can no longer be addressed and eventually overflowing, the runtime system has a component called the garbage collector. The garbage collector is a program that runs periodically to look for and destroy objects to which no more references point. If during a program you delete the last reference to an object by overwriting it or using the CLEAR statement, the garbage collector will destroy the object on its next pass. Equally, at the end of a program, when all of the reference variables are freed, the garbage collector will destroy all of the instances to which they had pointed. You therefore do not have to worry about resource management in the program yourself. Figure 185: Holding Reference Variables in an Internal Table One way in which you can keep objects alive is to place the references into an internal table. This is a technique that you may well want to use if you are creating a whole series of objects. It enables you to use a single reference variable to create lots of objects. However, when the reference variable is overwritten with the address of the next object, the existing objects are safe because the internal table contains a reference to them. You therefore never delete the "last" reference to the objects. LESSON SUMMARY You should now be able to: ● Create objects in ABAP © Copyright. All rights reserved. 182 Unit 10 Lesson 3 Calling Methods LESSON OBJECTIVES After completing this lesson, you will be able to: ● Call methods Calling Methods Figure 186: Calling Instance Methods You call methods of instances of a class using a reference variable. The reference variable must already contain the address of an object. If you try to call an instance method when the reference variable is initial, you will cause a runtime error. To call an instance method, you use the instance component selector following the reference variable name. This is an arrow made up of a dash and the greater than sign. Once you have typed the component selector, you can use the code completion in ADT to display a list of instance components that you can address. Once you have identified the component that you want to use, you can insert the name of the method and its full signature into your code by pressing Shift + Enter. © Copyright. All rights reserved. 183 Unit 10: Creating and Using Classes Figure 187: Calling Static Methods To call a static method, you do not need a valid object reference. Instead, you use the name of the class, followed by the static component selector. The static component selector is an arrow made up of the equals sign and the greater than sign. Figure 188: Method Call Syntax The figure shows the different syntax forms that you can use to call methods. The general syntax contains sections for exporting, importing, and changing parameters. Remember that the directions exporting and importing are seen from the point of view of the program, and that the exporting parameters in the method call correspond to the importing parameters of the method and the other way around. As well as the general syntax, there are also various shortened forms. For example, if the method only has importing parameters, you can call it and omit the EXPORTING addition. If the method only has one importing parameter, you can omit the explicit assignment of the value to the parameter and just specify the value that you want to pass. For methods with no signature, you can just write empty parentheses. Remember that there must be at least one space between the opening and closing parenthesis. © Copyright. All rights reserved. 184 Lesson: Calling Methods If a method has, for example, importing and exporting parameters, but you do not want to take the exporting parameters into your program, you can write the method call as though the method had only importing parameters. Likewise, if a method has a single obligatory importing parameter and several optional parameters, and you do not want to specify the optional parameters, you can write the method call as though the method had only one importing parameter. Figure 189: Explicit Exception Handling If a method can raise exceptions, you must take this into account when you call it. You must assume that an error will occur, since if the method triggers an exception to which you do not react in your program, a runtime error will occur. There are three different ways of reacting to exceptions from a method. The first, shown above, is a separate reaction for each exception that can occur. If the method triggers an exception with type cx_error_1, the program will jump to the CATCH cx_error_1 statement. If the method triggers an exception with type cx_error_2, the program will jump to the CATCH cx_error_2 statement. In this way, you can react specifically to each error that might occur. © Copyright. All rights reserved. 185 Unit 10: Creating and Using Classes Figure 190: Bundled Exception Handling You might not always need to write a separate error handling routine for each exception that can occur during a method. If this is the case, you can bundle exceptions in a single CATCH statement. In this example, the program will jump to the same CATCH statement regardless of whether cx_error_1 or cx_error_2 occurs. Figure 191: Exception Handling with sy-subrc When you use older classes, you may find that they do not use class-based exceptions. Instead, they have an exception system that is based on the system field sy-subrc. There are two ways to recognize this kind of exception; in the method definition, the exceptions are not declared using the RAISING addition, but instead using EXCEPTIONS. Furthermore, if you use code completion to insert the method call into your program, you will © Copyright. All rights reserved. 186 Lesson: Calling Methods see that the method signature contains an EXCEPTIONS block, and there is no TRY… CATCH… ENDTRY block. These exceptions work as follows: If the method raises an exception, control returns to the calling program, and the system places the corresponding numeric value from the EXCEPTIONS section of the method call in the system field sy-subrc. You can then query the value of sy-subrc to find out if an error occurred and which it was. If you do not want to handle the exceptions specifically, you can use the generic exception OTHERS. For example: reference->do_something( EXCEPTIONS others = 1 ). This means that the system would assign the value 1 to sy-subrc in the event of any exception of the method being raised. Note that you can mix explicit and generic exception handling by assigning numeric values to some named exceptions but using OTHERS as well. Figure 192: Functional Methods Most ABAP methods have importing, exporting, and changing parameters. If you want to check in your program whether an exporting parameter has the value zero, you must first assign it to a variable and then test the value of the variable in your program. Functional methods are ABAP methods that have a returning parameter. The difference between returning and exporting parameters is that you can use a returning parameter directly in an ABAP expression. You define a functional method by declaring a RETURNING parameter in the signature. There may only be one returning parameter, and you must pass it by value. As well as the one returning parameter, the method may also have any number of importing, exporting and changing parameters and, of course, exceptions. The figure above shows two examples of how you can use functional methods in expressions; the first is a simple example in which the returning parameter is assigned directly to a variable. The second example shows how the method call can be used in an IF expression. The system executes the method, and then uses the value of the returning parameter to process the logical expression. © Copyright. All rights reserved. 187 Unit 10: Creating and Using Classes LESSON SUMMARY You should now be able to: ● Call methods © Copyright. All rights reserved. 188 Unit 10 Lesson 4 Using Constructors LESSON OBJECTIVES After completing this lesson, you will be able to: ● Use constructors Using Constructors Figure 193: Initial State of an Object When you create a new instance of a class, all of its attributes have the initial value appropriate to their type. With the vehicle class, we therefore had to call the set_attributes method in order to assign a make and model to a new vehicle. This is, of course, not ideal, as it means that the user of the class needs to know that this is necessary, and may forget to call the method. Furthermore, you can call a normal instance method any number of times and this may not be suitable for some actions that you need once only to initialize a new object. © Copyright. All rights reserved. 189 Unit 10: Creating and Using Classes Figure 194: Instance Constructor To initialize a new instance of a class properly you use the instance constructor. This is a special method with the following properties: ● It is a public instance method with the reserved name constructor. ● It is called automatically by the runtime system when you create a new instance of the class, but may not be called explicitly. ● It is guaranteed to run once and once only for each instance that you create. ● It may have importing parameters that you use to obtain starting values for the attributes of the new instance. ● It may raise exceptions. Figure 195: Instantiating Classes That Have a Constructor When you instantiate a class that has a constructor, the system calls the method automatically. If the constructor has importing parameters, you pass them in the NEW expression exactly as you would pass parameters to a normal method. © Copyright. All rights reserved. 190 Lesson: Using Constructors If the constructor has exceptions, you must ensure that you catch them by enclosing the instantiation in a TRY… CATCH...ENDTRY block. If the constructor raises an exception, control returns immediately to the program containing the NEW expression. In this case, you do not receive a new instance of the class. Figure 196: Defining the Static Constructor While the instance constructor is called once when each instance of a class is created, you will sometimes need to perform actions once only for the entire class. For example, the vehicle class contains a static attribute gt_vehicle_types, which is an internal table containing all of the permitted combinations of make and model of vehicle. Since the table needs to be filled only once, and the data must be available as soon as anyone tries to instantiate the class, the ideal place to fill the table is in the static constructor. The static constructor is a public static method with the reserved name class_constructor. The runtime system calls the method automatically and once only when the class is addressed for the first time. This can be: ● When a program instantiates the class ● When a program calls a static method of the class ● When a program accesses a public static attribute of the class Note that this is not a complete list. There are other actions (related to inheritance) that can cause a class to be addressed for the first time. The runtime system calls the static constructor before creating the instance, calling the static method, or addressing the static attribute. The static constructor may not have a signature. This is because it is impossible to tell exactly when a class will be addressed for the first time. LESSON SUMMARY You should now be able to: ● Use constructors © Copyright. All rights reserved. 191 Unit 10 Lesson 5 Using Factory Methods LESSON OBJECTIVES After completing this lesson, you will be able to: ● Use factory methods Using Factory Methods Figure 197: Not All Classes Let You Use NEW You will sometimes come across classes that do not let you create instances directly using NEW. You will recognize this by the syntax error shown in the figure. There are in fact, two kinds of class that you cannot instantiate. One kind is abstract classes, which you will learn about later in connection with inheritance. The other kind is any class that is defined with the addition CREATE PRIVATE. These classes need to restrict who is allowed to create instances, so they decide that only a method of the class itself may do so. Here are some reasons why a class might restrict its instantiation: ● The class provides a central function in the application and there must only ever be one instance. ● Instances of the class represent a particular business entity (flight, employee, material) and there should only be one instance of the class per business key (and not twelve different instances all pertaining to the same material number). © Copyright. All rights reserved. 192 Lesson: Using Factory Methods ● The class may need to perform some checks before creating an instance, or some kind of registration of the new instance after the constructor has finished. Whatever the reason, a class with private instantiation must still provide its users with a way to obtain instances of the class. This is most often done using a factory method. Figure 198: Using a Factory Method A factory method is a static method whose job it is to create and return an instance of the class. The method will often have importing parameters that allow you to specify key information about the object you need, and there will be an exporting or a returning parameter with the type of the class itself by which the method gives you the instance you requested. If a class is designed for there only to be one instance of it, it may have a factory method. However, it is also possible that the instance is stored in a public static attribute so that you can retrieve it directly. In this case, the class uses its static constructor to create the single instance. LESSON SUMMARY You should now be able to: ● Use factory methods © Copyright. All rights reserved. 193 Unit 10 Learning Assessment 1. In what sequence must you declare the visibility sections of a class? Choose the correct answer. X A PRIVATE SECTION. PROTECTED SECTION. PUBLIC SECTION. X B PROTECED SECTION. PUBLIC. SECTION. PRIVATE SECTION. X C PUBLIC SECTION. PROTECTED SECTION. PRIVATE SECTION. X D You can order the sections however you like. 2. Which of the following statements can you use in the definition part of a class? Choose the correct answers. X A DATA X B TABLES X C TYPES X D CONSTANTS 3. When you declare a reference variable using DATA... TYPE REF TO, the newly-declared variable already points to an instance of the class. Determine whether this statement is true or false. X True X False 4. What happens to objects that are no longer required and to which no more reference variables are pointing? Choose the correct answer. X A Nothing. They remain in the program memory until the end of the program. X B They are destroyed when you release the memory explicitly. X C They are destroyed when you call the garbage collector explicitly. X D They are destroyed when the garbage collector next runs automatically. © Copyright. All rights reserved. 194 Unit 10: Learning Assessment 5. You have a reference variable oref that points to a valid instance of a class. You want to call the instance method meth. You do not need to pass any parameters to the method. Which of the following is the correct method call? Choose the correct answer. X A oref=>meth( ) X B oref=>meth() X C oref->meth( ) X D oref->meth() 6. Which of the following elements may an instance constructor have? Choose the correct answers. X A Importing parameters X B Exporting parameters X C Changing parameters X D Exceptions 7. What happens when a constructor raises an exception? Choose the correct answer. X A The method terminates and the new instance is returned. X B The method terminates and no new instance is returned. X C The method continues to the end and the new instance is returned. X D The method continues to the end and no new instance is returned. © Copyright. All rights reserved. 195 Unit 10 Learning Assessment - Answers 1. In what sequence must you declare the visibility sections of a class? Choose the correct answer. X A PRIVATE SECTION. PROTECTED SECTION. PUBLIC SECTION. X B PROTECED SECTION. PUBLIC. SECTION. PRIVATE SECTION. X C PUBLIC SECTION. PROTECTED SECTION. PRIVATE SECTION. X D You can order the sections however you like. 2. Which of the following statements can you use in the definition part of a class? Choose the correct answers. X A DATA X B TABLES X C TYPES X D CONSTANTS 3. When you declare a reference variable using DATA... TYPE REF TO, the newly-declared variable already points to an instance of the class. Determine whether this statement is true or false. X True X False © Copyright. All rights reserved. 196 Unit 10: Learning Assessment - Answers 4. What happens to objects that are no longer required and to which no more reference variables are pointing? Choose the correct answer. X A Nothing. They remain in the program memory until the end of the program. X B They are destroyed when you release the memory explicitly. X C They are destroyed when you call the garbage collector explicitly. X D They are destroyed when the garbage collector next runs automatically. 5. You have a reference variable oref that points to a valid instance of a class. You want to call the instance method meth. You do not need to pass any parameters to the method. Which of the following is the correct method call? Choose the correct answer. X A oref=>meth( ) X B oref=>meth() X C oref->meth( ) X D oref->meth() 6. Which of the following elements may an instance constructor have? Choose the correct answers. X A Importing parameters X B Exporting parameters X C Changing parameters X D Exceptions 7. What happens when a constructor raises an exception? Choose the correct answer. X A The method terminates and the new instance is returned. X B The method terminates and no new instance is returned. X C The method continues to the end and the new instance is returned. X D The method continues to the end and no new instance is returned. © Copyright. All rights reserved. 197 UNIT 11 Using Inheritance Lesson 1 Inheritance in ABAP 199 Lesson 2 Special Features of Inheritance 216 UNIT OBJECTIVES ● Implement inheritance ● Use inheritance ● Understand abstract and final classes © Copyright. All rights reserved. 198 Unit 11 Lesson 1 Inheritance in ABAP LESSON OBJECTIVES After completing this lesson, you will be able to: ● Implement inheritance ● Use inheritance Implementing Inheritance Figure 199: Generalization and Specialization When we talked about modeling, we discussed the idea of having general and more specialized classes. In the example, there is a generic vehicle class that contains all of the elements common to all different kinds of vehicles. We then extended the model by defining more specialized kinds of vehicle – a truck and a bus. This kind of modeling enables us to transform a flat, unstructured list of classes into a more easily understandable hierarchy. We must consider the role of the vehicle class in this hierarchy. In some cases, there will be actual things in the real world with the type "vehicle". In that case, we would need instances of the class in the application. However, it is also possible that the application only contains trucks and buses, but for the purpose of modeling the application, we decided to invent a vehicle class, even though the application will only need instances of the truck and bus class and there will never be a real vehicle. This approach is allowed, and in that case, we refer to the vehicle class as abstract. It is a help for modeling purposes, but a program may not create any instances of it. © Copyright. All rights reserved. 199 Unit 11: Using Inheritance Figure 200: Inheritance – The "Is A" Relationship In modeling, we talk about specialization. The implementation of this relationship in a programming language uses the concept of inheritance, in which a new class (the subclass) is derived from an existing one (the superclass). A reliable test to see if there is a genuine inheritance relationship between two classes is to try to say "A subclass is a superclass". If this is clearly true, you have an inheritance relationship. If it is clearly not true, or even sounds a bit strange, you do not have an inheritance relationship, and should not implement one – it will probably get you into trouble later on! Testing our model, we can definitely say "A truck is a vehicle " and "A bus is a vehicle". A class that inherits from a superclass automatically contains all of the components of the superclass. So, for example, the truck class has a make and a model, just as a vehicle does. This should not be surprising, as a truck "is a" vehicle. What may at first appear surprising is that the truck class cannot access its own make and model. This is because they are private attributes of the superclass and, as such, they are not accessible to the subclass. Later on you will learn a way of allowing a subclass to access components of a superclass without making them fully public. © Copyright. All rights reserved. 200 Lesson: Inheritance in ABAP Figure 201: Defining the Inheritance Relationship In ABAP, you implement inheritance using the INHERITING FROM addition in the class definition statement. In this example, the truck class is defined as a subclass of the vehicle class. Note that the subclass knows its superclass, but the vehicle class has no idea what subclasses it has (if any). A subclass may only have one direct superclass. Some other object-oriented languages such as C++ allow a class to inherit from multiple superclasses, but this is not permitted in ABAP. Figure 202: One Superclass – Any Number of Subclasses The vehicle class may have any number of subclasses, but it does not know about any of them. Each subclass has a single direct superclass. It knows its superclass, but does not know about any sibling classes (other classes that are derived from the same superclass). In our example, the truck class has no knowledge of the bus class. © Copyright. All rights reserved. 201 Unit 11: Using Inheritance Figure 203: Multi-Level Hierarchies Although a class may only have one direct superclass, it may be a part of a multi-level hierarchy. This happens frequently in complex frameworks. Here, you can see an extract of the class hierarchy of an ABAP framework called Run Time Type Identification. It has several hierarchy levels with a very general class at the top. As you move down the hierarchy, the classes become progressively more specific. If you move from the bottom of the hierarchy to the top, you will see that every class has a maximum of one direct superclass. When you are dealing with inheritance in a particular class, you only need to concern yourself with the next-highest class, and not with the levels above that. The superclass of your own class deals with its own superclass, and so on until you get to the top of the hierarchy. Figure 204: What You Can Do with a Freshly Inherited Class When you derive a new class from a superclass you can, in fact already use it. As long as the superclass was not abstract, you can instantiate the subclass and call its public methods. © Copyright. All rights reserved. 202 Lesson: Inheritance in ABAP When you instantiate the class, you must supply the obligatory parameters of the constructor of the superclass. This makes perfect sense, since (in this case) a truck is a vehicle, and instantiating a vehicle involves calling its constructor. You will learn in a moment how to add a new constructor to the subclass. When you call the public methods that have been inherited from the superclass, the runtime system executes the implementation as defined in the superclass. One of the things you need to consider when you define a subclass is whether the method implementations in the superclass are appropriate to the subclass. If they are, you can leave things as they are. If they are not, you will be able to supply a different implementation for an inherited method in the subclass. Figure 205: How to Extend a Subclass Once you have declared a subclass, you need to add new components to it or change existing components. This is what turns the mere copy of the vehicle class into a truck or a bus. Thanks to inheritance, you do not need to implement the class from scratch – you merely extend it by the new components that it needs. There are three ways to do this: Add new components: You can declare new attributes, types, constants, and methods in the class. Their names must not clash with other names that have already been used to declare components in the superclass. You must also ensure that the new components are only relevant to the subclass, and not to all specializations of the superclass. If you declare a new attribute or method that is generally relevant, you must move it into the superclass. Redefine methods: When you call an inherited method, the runtime system executes the implementation of the method from the superclass. This implementation cannot, however, take into account any new components that you have declared in the subclass. In this case, you may redefine the method. This means that you can assign it a new implementation that is relevant to the subclass. Add a new constructor: Constructors ensure that new instances of the class are properly initialized. When you create an instance of a subclass, the runtime system always executes the constructor of the superclass. This ensures, for example, that a truck has a make and a model in just the same way as any other vehicle. However, the constructor of the superclass © Copyright. All rights reserved. 203 Unit 11: Using Inheritance cannot initialize attributes of the subclass, as it does not know that they exist. For this reason, you can define a new constructor for the subclass. Figure 206: Declaring New Components You can extend a subclass by declaring new components. These are visible to the class itself, but not to the superclass, and not to any other classes that inherit from the same superclass. You therefore need to consider whether the new components are only relevant in the current class or if they actually need to be declared in the superclass. It is not uncommon for you to model a class, begin to implement it, and then to realize that a particular component is in the wrong place. ADT helps you to solve this and other problems by providing refactoring functions. Refactoring means changing the definition of a class by moving an element, changing its visibility, or renaming it. The danger of refactoring is that it can invalidate other code where the element that you are changing has already been used. The refactoring tools in ADT help by identifying where the element has already been used and adapting the code to fit the new definition of the object. © Copyright. All rights reserved. 204 Lesson: Inheritance in ABAP Figure 207: Refactoring in ADT In this example, we had added the attribute mv_color to the truck class. However, we have subsequently decided that color is a general attribute shared by all vehicles. To refactor the attribute, position the cursor on the name of the attribute and press Ctrl + 1 to open the Quick Fix suggestions. ADT suggests what you might like to do with the attribute – you can rename it, change its visibility, but also pull the attribute up into the superclass lcl_vehicle. This moves the attribute into the superclass and deletes it from the current class. Note that you can only move attributes up the inheritance hierarchy in this way; there is no way of pushing an attribute from a superclass to a subclass. © Copyright. All rights reserved. 205 Unit 11: Using Inheritance Figure 208: Protected Components Even though a subclass contains all of the attributes of its superclass, it is not allowed to access the private components directly by itself. Sometimes this is necessary, but there are other times when a superclass needs to let its subclasses access particular attributes or methods without making them fully public. It can do this by declaring them in the protected section. Protected components are visible within the class itself but also to all subclasses. In the class definition, you introduce the protected section using the statement PROTECTED SECTION. You must always declare the visibility sections in the sequence PUBLIC SECTION PROTECTED SECTION - PRIVATE SECTION. You can move an existing component of a class using a Quick Fix; to do so, place the cursor on the name of the component in ADT and press Ctrl + 1, then choose the quick fix Make <element> protected. Moving a private component to the protected section is a compatible change – you have broadened the visibility of the component. However, making a public component protected is an incompatible change and could cause syntax errors. This is because you have restricted the visibility of the component, which might already have been used outside the inheritance hierarchy. © Copyright. All rights reserved. 206 Lesson: Inheritance in ABAP Figure 209: Redefining Methods Superclasses often contain methods that you want to use in a subclass, but their implementations are unsuitable as they do not take into account the particular nature of the subclass. For example, the get_attributes method of the vehicle class cannot return attributes that are defined in the truck class. However, the truck class still needs a method get_attributes. In ABAP, you can solve this conundrum by redefining the instance method get_attributes. When you redefine a method, you write a new implementation for it in the subclass that takes into account things that only the subclass can know. However, the definition of the method stays exactly the same. You must follow these rules: ● The method retains the same name. ● You indicate that you want to redefine the method by declaring it in the subclass with the addition REDEFINITION. ● The method has the same visibility as in the superclass. ● You must not change the signature of the method. You cannot redefine a static method. © Copyright. All rights reserved. 207 Unit 11: Using Inheritance Figure 210: Implementing the Redefinition When you implement the redefinition of a method, you can call the implementation in the superclass. You do this using the implicit object reference super, which points to the superclass within the current instance. In this way, you can reuse the method implementation from the superclass and then add to it in your own implementation. You do not need to declare the reference variable super. It is automatically available within the implementation of redefined methods. Calling the method in the superclass in this way is optional. Sometimes it will be a good idea, sometimes there is nothing to be gained by it. Figure 211: Defining a New Constructor In a subclass, you may define a new constructor. In contrast to method redefinitions, a constructor may have its own signature. The signature of a constructor will often contain the same parameters as the constructor of the superclass, plus new parameters of its own. This is because the new instance constructor has two tasks: firstly, to call the constructor of the superclass, then to take care of initializing its own attributes that are specific to the subclass. © Copyright. All rights reserved. 208 Lesson: Inheritance in ABAP As well as defining a new constructor, you can also define a new static constructor in a subclass. Figure 212: Role of the Constructor The constructor of a subclass has two functions; it must ensure that the instance of the superclass is properly created, and after that, it can set the initial values of its own attributes. In our example, since a truck is a vehicle, there can be no truck instance unless the constructor of the vehicle class has run successfully to set the make and model of the new truck. After this, and only after this, can the truck class set its own attributes. The constructor of the subclass must therefore be able to set not only its own attributes, but to pass the required values to the constructor of the superclass. This is why the signature of the constructor in the subclass often contains the entire signature of the constructor that it is required to call. © Copyright. All rights reserved. 209 Unit 11: Using Inheritance Figure 213: Implementing the New Constructor – Sequence In the implementation of the new constructor, there is a particular sequence of operations that you must observe. The most important event is the call to the constructor of the superclass. This is obligatory and you call the method using the implicit reference super, just as you can when calling the original implementation of a redefined method. Once again, you do not need to declare super explicitly. Before you have called the constructor of the superclass, you must not address any instance components of the instance that is under construction. You may address static components of the class and check the correctness of the importing parameters of the constructor. If they are not correct, raise an exception. Once the constructor of the superclass has run successfully, you may address the instance components of your new instance. Figure 214: Sequence of Constructor Calls © Copyright. All rights reserved. 210 Lesson: Inheritance in ABAP The figure illustrates the sequence in which static and instance constructors are called. The example assumes that a program wants to instantiate the truck class and that the vehicle class has not previously been addressed. When the program tries to create an instance of the truck class, the runtime system automatically calls the static constructors sequentially, starting at the top of the inheritance hierarchy. Once all of the static constructors have run, the runtime system calls the instance constructor of the subclass, which in turn calls the instance constructor of the superclass. Using Inheritance Figure 215: Instantiating Subclasses Figure 216: Using Superclass References A reference variable with the type of a superclass – in this case lcl_vehicle – can also hold references to objects with the type of a subclass. This makes sense, since a truck or a bus is a vehicle. However, a reference variable with the type of the superclass is only aware of the components defined in the superclass. Consequently, when you use a reference with this type to manage an instance of a subclass, you can only address the components from the superclass, even though the actual object to which the reference points is an instance of the subclass. Assigning object references to a reference variable of a different type is called casting. Assigning a reference that points to a subclass to a reference variable with the type of a © Copyright. All rights reserved. 211 Unit 11: Using Inheritance superclass is called an up-cast, because you are making the assignment to a type higher up in the inheritance hierarchy. Figure 217: Calling Methods After an Up-Cast When you use a reference variable with type ref to lcl_Vehicle to manage a truck instance, you cannot use it to access components that belong to the truck class, as the vehicle class does not know that they exist and the syntax check cannot know what type of object the reference will actually point to at runtime. Using the reference, you can, however, access methods whose original definition is contained in the class. This is the case with the get_attributes method in the example in the figure. The question here is which implementation of the method will be called. In this case, the system looks at runtime to see what type of object the reference variable is pointing to, and calls the implementation from the corresponding class. In other words, although we are using a vehicle reference to manage an instance of the truck class, it is still the method implementation from the truck class that is called. © Copyright. All rights reserved. 212 Lesson: Inheritance in ABAP Figure 218: Generic Types in Method Signatures You will often use methods that return object references for you to work with. Sometimes they always return an object of the same type, but some factory methods can return instances of different classes depending on what you requested from them. So, for example, there might be a factory method that returns either a truck or a bus according to your request. The type of the returning parameter in this case must be a generic type that fits both the truck and the bus class. This generic type is, of course, their common superclass lcl_vehicle. When you use this method, the object comes back to you in a reference with a generic type. This, of course, means that you can only access the components of the object that are actually defined in that class. In order to access specific components, you must copy the object reference back into a reference variable with the more specific type. This operation is called a down-cast. Figure 219: Assigning a Generic Reference to a Specific Type © Copyright. All rights reserved. 213 Unit 11: Using Inheritance You can always assign a reference variable with the type of a subclass to a reference variable with the type of a superclass. For example, you can always assign a truck reference to a vehicle reference. As we have seen, this is because a truck is a vehicle. Assigning reference variables in the opposite direction is, however, more tricky. This is because a vehicle reference can contain references to other classes than the truck class. In other words, where every truck is a vehicle not every vehicle is a truck. Given object references go_vehicle with type ref to lcl_vehicle and go_truck with type ref to lcl_truck, the system will always allow you to write go_vehicle = go_truck. However, the assignment go_truck = go_vehicle leads to a syntax error because the syntax check cannot be sufficiently sure that the vehicle reference will actually hold a reference to a truck object at that moment. Figure 220: The CAST Operator The syntax check does not let you assign a superclass reference directly to a subclass reference. However, you can still do it using the CAST operator. Casting means looking at an object as though it had a different type. In the example, we tell the system to treat go_vehicle as though it were an instance of the truck class. This is syntactically correct, as we are now pretending that go_vehichle on the right-hand side of the expression has the same type as go_truck on the left-hand side. However, there is still not guaranteed that go_vehicle actually contains a truck reference, and if it turns out not to contain one at runtime, the assignment cannot be made. Left unprotected, this assignment could cause a runtime error. In older coding, you will see the expression go_truck ?= go_vehicle. ?= is also a cast operator; however, the introduction of the CAST expression makes the coding easier to understand. © Copyright. All rights reserved. 214 Lesson: Inheritance in ABAP Figure 221: Securing a Down-Cast If you are not certain that the object to which a reference variable is pointing is actually an instance of the correct subclass, you can check it using the logical expression IS INSTANCE OF. In this example, the assignment to the truck reference is only processed if go_vehicle actually points to an instance of the class lcl_truck. This is a new expression in ABAP. In older coding, you will find the following solution to the same problem: TRY. go_truck ?= go_vehicle. CATCH cx_sy_move_cast_error. ENDTRY. In this example, the unprotected assignment causes the exception cx_sy_move_cast_error if the vehicle reference points to an instance of a different class. The CATCH block is merely there to prevent an uncaught exception ending in a runtime error. LESSON SUMMARY You should now be able to: ● Implement inheritance ● Use inheritance © Copyright. All rights reserved. 215 Unit 11 Lesson 2 Special Features of Inheritance LESSON OBJECTIVES After completing this lesson, you will be able to: ● Understand abstract and final classes Understanding Abstract and Final Classes Figure 222: Abstract Classes and Methods When you work with inheritance, you will sometimes define classes that are useful in the sense of software modeling because they allow you to bundle components that two or more other classes have in common. However, at the same time, they do not represent complete entities in your application. In other words, you need the class, but you do not want to have instances of it in the application. In this case, you can use abstract classes. An abstract class cannot be instantiated. It can contain all of the usual components – types, attributes, constants, and methods – and the components can be either instance components or static components. The methods of a static class may be fully implemented so that the implementation can be passed on to the subclasses. On the other hand, you may wish to define a method so as to ensure that all of the subclasses of this class contain it, but there is no common implementation. In this case, you may define a method as abstract. Abstract methods do not have an implementation in the class in which they are declared. You can instantiate subclasses of an abstract class under the following conditions: © Copyright. All rights reserved. 216 Lesson: Special Features of Inheritance ● The subclass must not be abstract itself ● The subclass re-implements any abstract methods of the superclass. Although you cannot instantiate a subclass, you can still do the following with it: ● Use it as a type for reference variables; even though there are no instances, it can still point to instances of any of its subclasses ● Use its types and constants ● Use its static attributes ● Use its static methods Figure 223: Final Classes and Methods While abstract methods must have subclasses in order to be useful, there will also be times when you do not want an inheritance hierarchy to be extended any further. Here, you can use the FINAL addition when you define a class. Final classes may not have any subclasses. You can also define individual methods as final. In this case, you can derive subclasses from the class itself, but you may not redefine any of the methods that have been classified as final. This could be particularly useful in the case of methods that perform security checks. A subclass could bypass these checks by redefining the method and leaving the method implementation empty. If the method is defined as final in the superclass, this is not allowed. LESSON SUMMARY You should now be able to: ● Understand abstract and final classes © Copyright. All rights reserved. 217 Unit 11 Learning Assessment 1. In ABAP, each subclass may have only one direct superclass. Determine whether this statement is true or false. X True X False 2. Which of the following statements apply when you redefine a method in a subclass? Choose the correct answers. X A You must not change the name of the method. X B You must not change the signature of the method. X C You must not change the visibility of the method. X D You must not change the coding of the method. 3. You have an instance of a subclass and want to assign it to a reference variable that has the type of the superclass. Which of the following statements is true? Choose the correct answer. X A You cannot do this because the types are incompatible. X B You can always assign an instance of a subclass to superclass reference. X C You can only assign an instance of a subclass to a superclass reference after you have checked that the types are compatible. X D You can only do this if the superclass provides a suitable method that performs the assignment. 4. When you use a reference variable with the type of a superclass to call a method, the runtime system always calls the method implementation as it is defined in the superclass. Determine whether this statement is true or false. X True X False © Copyright. All rights reserved. 218 Unit 11 Learning Assessment - Answers 1. In ABAP, each subclass may have only one direct superclass. Determine whether this statement is true or false. X True X False 2. Which of the following statements apply when you redefine a method in a subclass? Choose the correct answers. X A You must not change the name of the method. X B You must not change the signature of the method. X C You must not change the visibility of the method. X D You must not change the coding of the method. 3. You have an instance of a subclass and want to assign it to a reference variable that has the type of the superclass. Which of the following statements is true? Choose the correct answer. X A You cannot do this because the types are incompatible. X B You can always assign an instance of a subclass to superclass reference. X C You can only assign an instance of a subclass to a superclass reference after you have checked that the types are compatible. X D You can only do this if the superclass provides a suitable method that performs the assignment. © Copyright. All rights reserved. 219 Unit 11: Learning Assessment - Answers 4. When you use a reference variable with the type of a superclass to call a method, the runtime system always calls the method implementation as it is defined in the superclass. Determine whether this statement is true or false. X True X False © Copyright. All rights reserved. 220 UNIT 12 Using Interfaces Lesson 1 Using Interfaces 222 UNIT OBJECTIVES ● Use interfaces © Copyright. All rights reserved. 221 Unit 12 Lesson 1 Using Interfaces LESSON OBJECTIVES After completing this lesson, you will be able to: ● Use interfaces Defining And Implementing Interfaces Figure 224: Reasons to Use Interfaces Interfaces allow you to define how a program will address one or more classes. In an interface, you can define methods, attributes, types, and constants, just as you would in a class. These components form a description of how a client program could interact with the corresponding objects. However, an interface cannot be instantiated, and does not contain any implementations of its methods. To make the concept work, we also need one or more classes that implement the interface. This means that they include the interface in their own class declaration and the components that are declared in the interface become part of the class itself. If the interface contains method declarations, the class that implements the interface must also provide an implementation of that method. Interfaces have two important uses: Providing a unified approach to different classes: If you have classes that are not related by inheritance, but that should still provide common services to their users, you can define the common services in an interface. This ensures that © Copyright. All rights reserved. 222 Lesson: Using Interfaces each class provides a method with the same name and the same signature to perform a particular task. Programs that use the classes then have a single way to call particular functions regardless of which class they are actually addressing. Providing a simplified approach to a complex class: As you will see later on, interfaces provide a restricted view of an object. This enables you to expose a particular set of methods to a program that will use a particular class on the basis of the functions that program actually requires. Figure 225: Interface Definition The definition of an interface is very similar to the definition section of a class. However, since an interface does not have an implementation, there is no DEFINITION addition in the INTERFACE statement. The second major difference is that there are no visibility sections in an interface, as all components of an interface are public. Interfaces are useful because of their interaction with other classes, so having non-public components would make no sense. In the interface definition, you can use types, attributes, constants, and methods, and both instance and static components are allowed. Remember that interface methods have a definition, but no implementation. This will be supplied by the implementing class. In many ways, interfaces are similar to abstract superclasses. They provide a useful technique for cases in which you need to define common components for classes without there being a case for inheritance, in other words, there is no clear "is a" relationship. © Copyright. All rights reserved. 223 Unit 12: Using Interfaces Figure 226: Declaring the Interface To implement an interface in a class, you use the INTERFACES statement. As all components of the interface are public and you cannot change the visibility of an existing component, you must include the interface in the public section of the class. As soon as you have written the INTERFACES statement, your program is syntactically incorrect. This is because the interface contains a method that you have not yet implemented. You can use a quick fix (Ctrl + 1) to add the method implementation to your class. Generally, you must implement all interface methods in your class. However, some interfaces contain optional methods. You can recognize these in the interface definition by the addition DEFAULT IGNORE or DEFAULT FAIL. You only implement optional methods if you actually need them in your application. If a class does not implement an optional method, but a program calls the method anyway, the system reacts either by ignoring the call (DEFAULT IGNORE) or by raising the exception CX_SY_DYN_CALL_ILLEGAL_METHOD (DEFAULT FAIL). © Copyright. All rights reserved. 224 Lesson: Using Interfaces Figure 227: Implementing the Interface Methods In the implementation of your class, you must implement all non-optional methods that are declared in the interface. When you name the method in the implementation, you must use the fully qualified name, which consists of the interface name and the method name joined by a tilde. This is because there is no guarantee that the method name by itself is unambiguous; remember that component names must only be unique in the class or interface in which they are declared. Consequently, a class could declare a method called get_partner_attributes as well as the interface lif_partner. In an implementing class, you can declare alias names for interface components. So, for example, in the public section of the class, after the INTERFACES statement, you could declare: ALIASES get_partner_attributes FOR lif_partner~get_partner_attributes. You can then address the interface method as get_partner_attributes throughout the class. Since the alias is public, users of the class can also do the same. © Copyright. All rights reserved. 225 Unit 12: Using Interfaces Using Interface References Figure 228: Declaring an Interface Reference You can use interfaces as a reference type for declaring a reference variable. As you learned earlier, you use reference variables to create and manage instances of a class. Since it is not possible to instantiate an interface, you may be wondering what kinds of objects you can manage using an interface reference. Interface references may contain references to instances of any class that implements the interface in the same way that a reference variable with the type of a superclass can contain references to any subclasses. (If you now imagine that the superclass is abstract, you have an identical situation of a type that cannot be instantiated holding references to other classes that are related to it). When you use a variable with the type of a superclass to manage an instance of one of its subclasses, you can only access the components that are defined in the superclass. Similarly, when you use an interface reference to manage an instance of a class that implements the interface, you can only access the components that are defined in the interface. This means that the developer of a particular framework of classes can ship interfaces that provide a particular view of an object instead of exposing every single thing that the class can do. You can call a method from an interface using a reference variable with the type of the class. In this case, you must use the fully qualified name of the method (including the interface name). (If you have defined an alias for the method, you can use that). When you call an interface method using an interface reference, the name of the interface is inferred from the type of the reference variable, and you do not need to specify the interface name before the method name. © Copyright. All rights reserved. 226 Lesson: Using Interfaces Figure 229: Casting with Interface References Assigning object references to an interface reference is also a cast; you look at the rental or carrier object as though it were a business partner. You can always assign an instance of the implementing class to an interface reference. This is an up-cast, and is guaranteed by the fact that the class implements the interface. You cannot, however, assign an object from an interface reference to a reference with the type of an implementing class, since the syntax check cannot tell whether the actual runtime objects will be compatible. The assignment go_rental = go_partner would work if the object in the interface reference really is an instance of lcl_rental, but if it is an instance of another implementing class, you would cause a runtime error. Here we have a down-cast in the same way that we encountered it in inheritance. The solution is the same as well; if you need to assign an object reference from a reference variable with the type of an interface to one with the type of a class (so that you can access specific features of the class), you must use the CAST operator. The correct solution in this case would be: IF go_partner IS INSTANCE OF lcl_rental. go_rental = CAST #( go_partner ). ENDIF. © Copyright. All rights reserved. 227 Unit 12: Using Interfaces Figure 230: Generic Types in Method Signatures We have already seen that methods of frameworks often work with generic types to allow them to return instances of different classes. Sometimes they do this using superclass references, but other methods will use interface references instead. A method that has an interface type for an exporting or returning parameter can use it to provide an instance of any class that implements the given interface. When you use this kind of method in your program, you can either receive the parameter into a variable with the type of the interface or, if you need to access specific components of the class that are not contained in the interface description, you can cast the value onto a variable of the corresponding type. If the method has a returning parameter, you can do this directly in the method call: DATA go_rental TYPE REF TO lcl_rental. go_rental = CAST #( lcl_partner_factory=>create_partner( ) ). If the method has an exporting parameter, you must first receive the object reference into a variable of its exact type, then perform the cast in a subsequent step. LESSON SUMMARY You should now be able to: ● Use interfaces © Copyright. All rights reserved. 228 Unit 12 Learning Assessment 1. Which of the following statements are true of interfaces? Choose the correct answers. X A They may contain method definitions. X B They may contain method implementations. X C They may contain private attributes. X D They may contain type definitions. 2. A class that implements an interface must implement all of the methods defined in that interface. Determine whether this statement is true or false. X True X False 3. What instances can you assign to an interface reference? Choose the correct answer. X A Instances of the interface. X B Instances of any classes that implement the interface X C Instances of any local classes in the same program. X D Instances of any class. © Copyright. All rights reserved. 229 Unit 12 Learning Assessment - Answers 1. Which of the following statements are true of interfaces? Choose the correct answers. X A They may contain method definitions. X B They may contain method implementations. X C They may contain private attributes. X D They may contain type definitions. 2. A class that implements an interface must implement all of the methods defined in that interface. Determine whether this statement is true or false. X True X False 3. What instances can you assign to an interface reference? Choose the correct answer. X A Instances of the interface. X B Instances of any classes that implement the interface X C Instances of any local classes in the same program. X D Instances of any class. © Copyright. All rights reserved. 230