SAP Robot Template

The SAP GUI Scripting template details how to create a robotic process that will interact with an SAP application. Using the SAP module, this template will have a robotic process log on to SAP with a configured connection, username, and password, and then open an SAP transaction. In this example, the transaction to open is VA01, which is the t-code to create a sales order.

When you use a template to create your robotic process, you are provided with a ZIP file containing your source code and a pre-built workflow in the Robotic process configuration page. This page explains the contents of the workflow and the source code generated by the template. This template assumes you have a basic understanding of SAP GUI components. To learn more about the SAP GUI components that interact with your robotic process, review the SAP module components.

Before using this template, you must complete the SAP module prerequisites to use the components of the module.

Workflow

SAP-robot-workflow.png

The SAP GUI Scripting template's workflow contains five actions: Init, SAP Open, SAP Login, SAP Open Transaction, and End. Similar to an Appian process model, each workflow has a start and end action. The other actions in the workflow are related to interacting with an SAP application.

If you click the list icon 951644.png on any action, you'll see it is associated with a method. These methods are in the source code generated from the template. Within the source code, Appian has provided an outline of how you can configure each method.

Source code

Within the downloaded ZIP file, you will see three files:

  • SapConstants is a class that contains constants related to the SAP elements you'll interact with during the process.
  • ESapTransaction is an enum that defines the SAP transaction code, which is VA01.
  • RobotSapTemplate is a class that implements the IRobot interface and contains the main methods used to configure the actions in your robotic process.

SapConstants

The SapConstants class contains constants that define the installation path of SAP GUI, the titles of SAP GUI elements, and the names of the controls available on the interface.

This class assumes that the executable saplogon.exe is located in the default path selected by the SAP GUI installer: C:\\Program Files(x86)\\SAP\\FrontEnd\\SAPgui\\saplogon.exe. If your local installation is located in a different path, modify SAP_EXECUTABLE_PATH (line 29) with the correct file location.

24
25
26
27
28
29
30
31
32
	/**
	 * The Class App.
	 */
	public class App {
		
		public static final String SAP_EXECUTABLE_PATH = "C:\\Program Files (x86)\\SAP\\FrontEnd\\SAPgui";
		public static final String SAP_EXECUTABLE = "saplogon.exe";
		
	}

To use this template, you should not need to modify any of the other constants in this class. The remaining constants are defined so they match with the titles, controls, and format of the SAP application.

ESapTransaction

In SAP, transactions are used to execute an SAP program. Transactions are referenced using t-codes. For the purposes of this example, the template uses the t-code VA01, which creates a sales order.

The ESapTransaction enum is used to define the transaction type and instantiate it.

RobotSAPTemplate

The class RobotSAPTemplate implements the IRobot interface and is annotated with @Robot. Every Appian RPA robotic process must have the IRobot interface and @Robot annotation to allow the Appian RPA API to identify the class as a robot.

RobotSAPTemplate includes several methods and attributes. These methods are directly associated with the workflow actions:

Method Description Associated Action
init() Provides initial information to the process. Init
sapOpen() Opens SAP GUI and brings you to the SAP Logon window. SAP Open
sapLogin() Logs into SAP using the username and password from the Credentials list in the console. SAP Login
sapOpenTransaction() Opens the transaction specified in enum ESapTransaction. SAP Open Transaction
sapClose() Closes SAP GUI. End

The following sections explain how to work with each of the methods and attributes provided in the template.

Attributes

The first few lines in the template's source code reference the attributes and constants related to the robotic process:

  • SAP_CONNECTION = "SAP Demo" (line 36) is a constant that defines the entry to the SAP system. In this template, the SAP system is called SAP Demo.

    2236285.png

  • CREDENTIALS_SAP_APPLICATION = "SAP_IDES" (line 39) is a constant that defines the application name of the credentials configured in the List of credentials section of the console. The robotic process will use the credentials associated with this application. As an example, this template refers to an application name called SAP_IDES, where the credentials could appear as follows:

    sap-credential.png

  • IWindows (line 42) represents a Windows operating system. This is what enables your robotic process to interact with each window.
  • IJidokaServer (line 45) declares the server variable to manage the interaction with the server. The server is what communicates information to the console.
  • IGuiApplication (line 48) represents the system where all SAP GUI activities occur. There can only be one GuiApplication object instantiated.
  • IWaitFor (line 51) determines a robotic process's wait time. This interface implements smart waits, which make the wait time dynamic by depending on certain actions to occur rather than a hard-coded time limit.
  • IKeyboard (line 54) declares the variable to allow the robotic process to interact with the keyboard. This interface solves the most common keyboard needs: typing text, using the Shift, Alt, and Control keys, keyboard arrows, etc.
  • IUsernamePassword (line 57) declares the variable that will represent credentials stored in the console.
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
	/** The Constant SAP_CONNECTION. */
	public static final String SAP_CONNECTION = "SAP Demo";

	/** The Constant CREDENTIALS_SAP_APPLICATION. */
	private static final String CREDENTIALS_SAP_APPLICATION = "SAP_IDES";
	
	/** The windows. */
	private IWindows windows;

	/** The server. */
	private IJidokaServer<?> server;

	/** The sap. */
	private IGuiApplication sap;

	/** The wait for. */
	private IWaitFor waitFor;

	/** The keyboard. */
	private IKeyboard keyboard;

	/** The sap credentials. */
	private IUsernamePassword sapCredentials;

init() method

The init() method is used to define the initial actions of the workflow. This is where you should initialize the objects that will be used by the robotic process.

  • server = JidokaFactory.getServer(); (line 66) initializes IJidokaServer.
  • windows = IWindows.getInstance(this); (line 67) initializes IWindows, where this refers to the class that implements the IRobot interface.
  • waitFor = windows.waitFor(this); (line 69) initializes IWaitFor, where this refers to the class that implements the IRobot interface.
  • keyboard = windows.getKeyboard(); (line 70) initializes IKeyboard.
  • sap = ISap.getInstance(this); (line 72) creates an instance of the SAP module, where this refers to the class that implements the IRobot interface.
  • sapCredentials = server.getCredential() (line 74) returns the credentials associated with a specified application. This accepts the following parameters:
    • CREDENTIALS_SAP_APPLICATION is the name of the application containing the credentials you want to use. This constant references the application name SAP_IDES.
    • false determines that you do not want to reserve the returned credentials.
    • ECredentialSearch.FIRST_LISTED determines that the first available user for the SAP_IDES application should be returned.

If there are no credentials returned from the server, then an exception occurs that says the process does not have access to the credentials.

64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
public void init() throws JidokaException {

		server = JidokaFactory.getServer();
		windows = IWindows.getInstance(this);

		waitFor = windows.waitFor(this);
		keyboard = windows.getKeyboard();

		sap = ISap.getInstance(this);

		sapCredentials = server.getCredential(CREDENTIALS_SAP_APPLICATION, false, ECredentialSearch.FIRST_LISTED);

		if (sapCredentials == null) {
			throw new JidokaException("Robot doesn't have access to any SAP credentials");
		}
		
	}

sapOpen() method

The sapOpen() method is responsible for opening SAP GUI and the SAP system, which is SAP Demo.

  • Path sapPath = Paths.get(SapConstants.App.SAP_EXECUTABLE_PATH,SapConstants.App.SAP_EXECUTABLE); (line 89) defines sapPath with the path to the SAP GUI executable file.
  • ProcessBuilder pb = new ProcessBuilder(sapPath.toString()); (line 92) declares the variable pb will start a new Windows process. Within the object, the SAP GUI executable file defined in line 89 is called and returned as a string.
  • pb.start() (line 96) opens the SAP GUI executable file.
  • waitFor.window() (line 98) waits for the window to appear for a certain amount of time and provides actions to occur if the window is not found in the specified amount of it. It accepts the following parameters:
    • 30 determines the wait time is 30 seconds.
    • true determines that if the window is not found after 30 seconds, then JidokaUnsatisfiedConditionException will be thrown. The specific exception actions are defined on line 205.
    • true indicates that a corresponding screenshot will be written to the robotic process's execution log if the image is not found.
    • SapConstants.Titles.SAP_LOGON_WINDOW_TITLE references the title of the window that is being waited on. The window's title is defined in the SapConstants class.
  • server.info("Sap application opened"); (line 100) sends a log message of type info to the server indicating that the application is open.
  • keyboard.type(SAP_CONNECTION).pause(1000).enter(); (line 102) uses the keyboard to type SAP Demo in the connection list. After typing, the process will pause for 1,000 milliseconds and then click Enter on the keyboard.
  • waitFor.window() (line 104) waits for the window to appear for a certain amount of time and provides actions to occur if the window is not found in the specified amount of it. It accepts the following parameters:
    • SapConstants.Timeouts.DEFAULT_WAIT determines the wait time is 10 seconds. This time is specified in the SapConstants class.
    • true determines that if the window is not found after 10 seconds, then JidokaUnsatisfiedConditionException will be thrown. The specific exception actions are defined on line 205.
    • SapConstants.Titles.SAP_LOGON_WINDOW_TITLE_FIRST references the title of the window that is being waited on. The window's title is defined in the SapConstants class.
  • server.info (line 106) sends a log message of type info to the server indicating that the process is connected to SAP Demo.

Now that your current active window is the SAP Logon window, the SAP module can start managing the application. The code on lines 108-110 connect the SAP module instance to the application just opened by initializing the module.

The remainder of the code in this method is optional. Lines 112-119 are used to maximize the window and send a log message of type info to the server indicating that the module has been initialized and it's ready to be used.

87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
	public void sapOpen() throws JidokaException {

		Path sapPath = Paths.get(SapConstants.App.SAP_EXECUTABLE_PATH, SapConstants.App.SAP_EXECUTABLE);

		// open SAP logon window
		ProcessBuilder pb = new ProcessBuilder(sapPath.toString());

		try {

			pb.start();

			waitFor.window(30, true, true, SapConstants.Titles.SAP_LOGON_WINDOW_TITLE);

			server.info("Sap application opened");

			keyboard.type(SAP_CONNECTION).pause(1000).enter();

			waitFor.window(SapConstants.Timeouts.DEFAULT_WAIT, true, SapConstants.Titles.SAP_LOGON_WINDOW_TITLE_FIRST);

			server.info("Connected to: " + SAP_CONNECTION);

			if (!sap.isInitialized()) {
				sap.init();
			}

			GuiMainWindow win = (GuiMainWindow) sap.getCurrentSession().getActiveWindow();

			win.iconify();
			win.maximize();

			windows.pause(2000);

			server.info("Jidoka SAP module initialized");

		} catch (IOException | JidokaUnsatisfiedConditionException e) {
			throw new JidokaException("SAP could not be opened: " + e.getMessage(), e);
		}
	}

sapLogin() method

The sapLogin() method is responsible for identifying the login screen and entering the appropriate credentials.

Now that the robotic process is working directly in the SAP application, this is where the robotic process will reference SAP GUI elements. The robotic process will need to first determine if the active window is the Logon window where it can enter credentials:

  • sap.refreshOpenSessions(); (line 134) refreshes the open session of SAP GUI.
  • IGuiSession guiSession = sap.getConnection().getOpenSessions().get(0); (line 136) defines guiSession with the current session.
  • GuiMainWindow activeWindow = (GuiMainWindow) guiSession.getActiveWindow(); (line 138) defines activeWindow with the active window in the session.

If the active window does not match the title of the SAP Logon window defined in the SapConstants class, then an error is thrown with a message that says the login was not successful (lines 140-142).

If the active window does match the title, then the robotic process will start referencing the elements on the GUI using the findById() method. In this template, IDs of each element are defined in the SapConstants class. In your own robotic process, you can use the Tracker tool to obtain the element's unique identifiers.

First the robotic process will enter the username in a text field element on the active window.

  • GuiTextField user = activeWindow.getUserArea().findById(SapConstants.Controls.LOGIN_USER_TEXTFIELD); (line 146) gets an instance of GuiUserArea, which is where the main elements of the window are located. Then, using the findById() method of the GuiUserArea instance, it locates the text field element using the ID defined in the SapConstants class. The text field element is stored in the user variable.
  • user.setFocus(); (line 148) sets the focus on the text field defined in user.
  • user.setText(sapCredentials.getUsername()); (line 149) sets the text property with the username obtained from the console.

Now the robotic process will focus on the password field element to enter the password.

  • GuiPasswordField password = activeWindow.getUserArea().findById(SapConstants.Controls.LOGIN_PASSWORD_TEXTFIELD); (line 151) gets an instance of GuiUserArea, which is where the main elements of the window are located. Then, using the findById() method of the GuiUserArea instance, it locates the password field element using the ID defined in the SapConstants class. The password field element is stored in the password variable.
  • password.setFocus(); (line 153) sets the focus on the password field defined in password.
  • password.setText(sapCredentials.getPassword()); (line 154) sets the text property with the password obtained from the console.

After entering the credentials, the robotic process will click the checkmark button on the toolbar and confirm that it successfully logged in.

  • GuiButton btn = activeWindow.getToolBar().findById("btn[0]"); (line 156) gets an instance of GuiToolBar, which is the toolbar in the window. Then, using the findById() method of the GuiToolBar instance, it locates a button in the toolbar using an index of 0. The text field element is stored in the btn variable.
  • btn.press(); (line 157) presses the button in the location defined in btn.
  • guiSession.waitIdle(); (line 159) waits while SAP is idle for 10 seconds.
  • GuiTitleBar titl = activeWindow.findById("titl"); (line 161) searches in the active window for the title element. This is represented as the GuiTitleBar class.
  • windows.waitCondition() (line 163) waits until the conditions listed as parameters are satisfied:
    • 3 is how many times the robotic process will try to meet the conditions.
    • 300 indicates a pause of 300 milliseconds between attempts to meet the conditions.
    • "User menu" is the text to be written to the server as a log.
    • null is optional context that the system can pass. In the template, no additional context is passed.
    • true indicates that JidokaUnsatisfiedConditionException will be thrown if the condition is not satisfied.
    • true indicates that a screenshot will be sent to the server as a log if the condition is not satisfied.
    • return titl.getText().matches is a condition to verify if the title of the window matches the SAP_MAIN_WINDOW_TITLE defined in the SapConstants class. A log message of type debug is then sent to the server with the text from the active window.
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
	public void sapLogin() throws JidokaException, JidokaUnsatisfiedConditionException {

		sap.refreshOpenSessions();

		IGuiSession guiSession = sap.getConnection().getOpenSessions().get(0);

		GuiMainWindow activeWindow = (GuiMainWindow) guiSession.getActiveWindow();

		if (!activeWindow.getText().matches(SapConstants.Titles.SAP_LOGON_WINDOW_TITLE)) {
			throw new JidokaException(
					"Unsuccessful login. We should be at page: " + SapConstants.Titles.SAP_LOGON_WINDOW_TITLE);
		}

		// Login field
		GuiTextField user = activeWindow.getUserArea().findById(SapConstants.Controls.LOGIN_USER_TEXTFIELD);

		user.setFocus();
		user.setText(sapCredentials.getUsername());

		GuiPasswordField password = activeWindow.getUserArea().findById(SapConstants.Controls.LOGIN_PASSWORD_TEXTFIELD);

		password.setFocus();
		password.setText(sapCredentials.getPassword());

		GuiButton btn = activeWindow.getToolBar().findById("btn[0]");
		btn.press();
		
		guiSession.waitIdle();

		GuiTitleBar titl = activeWindow.findById("titl");

		windows.waitCondition(3, 300, "User menu", null, true, true, (i, c) -> {

			return titl.getText().matches(SapConstants.Titles.SAP_MAIN_WINDOW_TITLE);

		});

		server.debug(guiSession.getActiveWindow().getText());
	}

sapOpenTransaction() method

The sapOpenTransaction() method is responsible for opening the transaction (VA01) and sending a screenshot to the server when the page transaction is open.

  • IGuiSession session = sap.getCurrentSession(); (line 179) defines session with the current session in SAP.
  • ESapTransaction transaction = ESapTransaction.VA01; (line 181) defines transaction with the t-code and information defined in the ESapTransaction enum.
  • session.sendCommand(transaction.getTransaction()); (line 182) enters the VA01 transaction.
  • String pageTitle = session.getActiveWindow().getText(); (line 184) gets the text of the active window and defines its value in pageTitle.
  • IEasyCondition condition = () -> transaction.getExpectedTitle().equals(pageTitle); (line 186) verifies if the expected title of the transaction, defined in the defined in the ESapTransaction enum, matches the current text on the active window.
  • windows.waitCondition() (line 188) waits until the conditions listed as parameters are satisfied:
    • 30 is how many times the robotic process will try to meet the conditions.
    • 1000 indicates a pause of 1,000 milliseconds between attempts to meet the conditions.
    • "Checking SAP" is the text to be written to the server as a log.
    • null is optional context that the system can pass. In the template, no additional context is passed.
    • true indicates that JidokaUnsatisfiedConditionException will be thrown if the condition is not satisfied.
    • true indicates that a screenshot will be sent to the server as a log if the condition is not satisfied.
    • condition is the condition previously defined in line 186.

Finally, the process will send a log message of type info to the server indicating that the transaction is open, along with a screenshot of the transaction (lines 190-192).

177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
	public void sapOpenTransaction() throws JidokaUnsatisfiedConditionException {
		
		IGuiSession session = sap.getCurrentSession();

		ESapTransaction transaction = ESapTransaction.VA01;
		session.sendCommand(transaction.getTransaction());

		String pageTitle = session.getActiveWindow().getText();
		
		IEasyCondition condition = () -> transaction.getExpectedTitle().equals(pageTitle);
		
		windows.waitCondition(30, 1000, "Checking SAP", null, true, true, condition);
		
		server.info("Transaction opened: " + transaction.getTransaction());
		
		server.sendScreen("Transaction");
		
	}

sapClose() method

The sapClose() method is used to define the final actions of the workflow and is associated with the End action. In this template, the sapClose() method is responsible for closing SAP GUI before ending the execution. In your own robotic process, you can add additional actions here to clean up the resource.

215
216
217
218
219
220
221
222
223
	public void sapClose() {

		try {
			windows.killAllProcesses(SapConstants.App.SAP_EXECUTABLE, 1000);
		} catch (IOException e) {
		}

		windows.pause(1000);
	}
Open in Github

On This Page

FEEDBACK