This section will explain the process of uploading and downloading data between SAP ERP and Offline, using the functions and processes previously introduced. Topics covered are as follows:
- Uploading
- Downloading
To synchronize data, please follow the instructions listed below. First, create a client-side script if this has not already been done. This script will initiate the upload process and send data to Liquid UI Server from specified data tables.
Once the client-side script is created, users should also create a corresponding server-side script. Offline needs customized screens to carry data to SAP and back. Thus, once the data is received from the Offline client, the Liquid UI Server will process the data in SAP. It is important to ensure that the Liquid UI Server is running. Liquid UI Server does not need to run during the offline runtime, but must be running in order for data to be synchronized between SAP ERP and the Offline client. Once the scripts are created, a user can then initiate the download function from the offline client.
Users will enter the SAP username and password to be used in background login to SAP by offline client. This screen is optional since users already enter a username and password when logging to offline application. But for some scenarios, companies might want to separate offline login from SAP login. They require each application to have their own login credentials. To accomplish this, this customized login screen gives companies an option to define a separate login for synchronization to SAP.
Offline makes a connection to Liquid UI Server. Developers can see this connection happening in debug mode. We will not show debug mode in this document.
Below is actually what happens in background processing in SAPGUI during a data synchronization. First, all the actions to process data in the flow below come from offline client. These actions are simple enters on each screen. The Offline client then sends data to the Liquid UI server for background processing and Server processes this data according to a standard flow in which each action sent from Offline client executes a process in Server. Those are the processes where offline data gets synchronized with SAP ERP.
Background Processing for Upload
A global variable (Z_mode) is defined in the GuiXT scripts, which is used to set an internal mode in the server to maintain the process flow. Z_mode has a blank value when the connection to the GuiXT server is established. The layout created (function “scr_main”) when Z_mode has a blank value is called “Main Menu” and it is created for server to populate the upload (or download) process code sent from offline client. Below is the code that controls this process:
if(isBlank(Z_mode)) scr_main(); function scr_main() { println('Inside blank Z_mode'); set("V[g*]",''); set("V[z_line_empty]",""); set("V[z_idx]",""); inputfield([2,1],'Process',[2,18],{"size":20,"name":"z_process"}); inputfield([3,1],'Records per Page',[3,18],{"size":5,"name":"z_upload_rows"}); println('z_process- ' + z_process); onUIEvents['Enter']={"process":zmobile_set_mode,'fcode':"\0"}; }
The Offline client populates the upload process code in SAPGUI (Any transaction in SAP can be used for offline to send the data to server)
Once data gets populated on the above screen, the Offline client sends an 'Enter' action to the Liquid UI Server. The Server then executes this action on this screen in background. Pressing Enter invokes the “z_mobile_set_mode” function which sets the value of Z_mode to display upload screen via a process code sent by the Offline client. The process code is controlled by the z_process global variable as shown below with the upload rows defined also above. This function also sets some default values. Once Z_mode is sets to upload value, depending on the arZ_Mode array assignments, the upload screen gets displayed (scr_UPLD_mm01).
arZ_Mode = []; arZ_Mode['UPLD_mm01'] = scr_UPLD_mm01; if(isBlank(Z_mode)) scr_main(); else if(arZ_Mode[Z_mode] != void 0) arZ_Mode[Z_mode](); function zmobile_set_mode(){ println('Zmobile set mode called'); if(isBlank(z_process.value)) { message('E:Enter a process to download'); } println('z_process- ' +z_process.value); set("V[Z_mode]",'&V[z_process]'); set("V[Z_upload_rows]", '&V[z_upload_rows]'); set("V[g*]",""); set("V[message*]",""); //Setting defaults if(Z_mode=='wkdr') { set("V[z_mobile_wo]",""); set("V[z_plant]",'1000'); set("V[z_work_ctr]",'MECHANIK'); } set("V[z_mobile_from_date]",'01.04.2003'); set("V[z_mobile_to_date]",'06.07.2006'); set("V[z_download_rows]",'90'); set("V[z_upload_rows]",'&V[Z_upload_rows]'); set("V[z_upload_rows_old]", '&V[z_upload_rows]'); enter('/nzguixt'); // <<---------???? println('Zmobile set mode finished'); }
Offline sends an “Enter” action on this screen and server executes that action via function “scr_UPLD_mm01” as see below. The “Enter” action invokes process “InputScript_mm01” which processes client request in SAP and returns outcome message to be forwarded to offline. Offline grabs this message only if the fieldname and fieldlength definitions for the datatable which this data will be forwarded in offline match to those of corresponding GuiXT variables used to generate this screen. The code is shown below:
function scr_UPLD_mm01() { inputfield([1,2],'Records per Page',[1,21],{"size":5,"name":"z_upload_rows"}); set("V[g_row]",'6'); if(!isBlank(z_upload_rows.value)) { comment([5,3],'Mat.Type'); comment([5,17],'Plant'); comment([5,27],'Description'); comment([5,80],'Uom'); comment([5,85],'Mat.Grp'); comment([5,102],'H.Viscous'); comment([5,113],'Msg'); for(idx=0; idx<z_upload_rows.value; idx++) { inputfield([g_row,3], { 'name':'z_mm01_mtype_&V[idx]',"size":4,"nolabel":true}); inputfield([g_row,17],{'name':'z_mm01_plant_&V[idx]',"size":4,"nolabel":true}); inputfield([g_row,27],{'name':'z_mm01_desc_&V[idx]',"size":40,"nolabel":true}); inputfield([g_row,80],{'name':'z_mm01_uom_&V[idx]',"size":3,"nolabel":true}); inputfield([g_row,85],{'name':'z_mm01_mgrp_&V[idx]',"size":8,"nolabel":true}); inputfield([g_row,102],{'name':'z_mm01_hvis_&V[idx]',"size":1,"nolabel":true}); inputfield([g_row,113],{'name':'message_&V[idx]',"size":40,"readonly":true,"nolabel":true,"maxlength":80}); g_row++; } box([4,2], [g_row,164],'Add Parts'); set("V[z_upload_rows_old]",'&V[z_upload_rows]'); onUIEvents["enter"] ={"process":InputScript_mm01,"fcode":"/nmm01"}; } else { onUIEvents["enter"] ={"process":setrows_txt}; set("V[z_upload_rows_old]",'&V[z_upload_rows]'); } }
Each transaction has a status screen. Once the process is done, users can view the status by entering /n_stat. The Status screen for the transaction will display as shown in the following example.
For how upload process is initiated from offline client and which parameters are used please refer to the Data Synchronization section.
Download for background processing
A global variable (Z_mode) is defined in GuiXT scripts, which is used to set an internal mode in server to maintain the process flow. Z_mode has a blank value when a connection to the GuiXT Server is established. The layout created (function “scr_main”) when Z_mode has a blank value is called “Main Menu” and it is created for server to populate the upload (or download) process code sent from Offline client. Below is the code:
if(isBlank(Z_mode)) scr_main(); function scr_main() { println('Inside blank Z_mode'); set("V[g*]",''); set("V[z_line_empty]",""); set("V[z_idx]",""); inputfield([2,1],'Process',[2,18],{"size":20,"name":"z_process"}); inputfield([3,1],'Records per Page',[3,18],{"size":5,"name":"z_upload_rows"}); println('z_process- ' + z_process); onUIEvents['Enter']={"process":zmobile_set_mode,'fcode':"\0"}; }
Offline client populates the download process code in SAPGUI. Note that Offline can use any transaction in SAP to send the data to the GuiXT Server.
Once the data is populated on above screen, the Offline client sends an “Enter” action to server and server executes this action on this screen in background. Enter invokes “zmobile_set_mode” function in server to paint below screen populated with the transaction criteria sent from offline. This function sets the criteria values retrieved from offline client to the screen below. “Rows” seen in below screen is used to paint the rows on the screen where results from SAP are displayed. This number will also be used to determine whether scrolling needs to happen in server to see the whole data or not using scrolling function. For more information on scrolling, please see the Table Controls section below.
arZ_Mode = []; arZ_Mode['wkdr'] = scr_wkdr; if(isBlank(Z_mode)) scr_main(); else if(arZ_Mode[Z_mode] != void 0) arZ_Mode[Z_mode](); function zmobile_set_mode(){ println('Zmobile set mode called'); if(isBlank(z_process.value)) { message('E:Enter a process to download'); } println('z_process- '+z_process.value); set("V[Z_mode]",'&V[z_process]'); set("V[Z_upload_rows]",'&V[z_upload_rows]'); set("V[g*]",""); set("V[message*]",""); //Setting defaults if(Z_mode=='wkdr') { set("V[z_mobile_wo]",""); set("V[z_plant]",'1000'); set("V[z_work_ctr]",'MECHANIK'); } set("V[z_mobile_from_date]",'01.04.2003'); set("V[z_mobile_to_date]",'06.07.2006'); set("V[z_download_rows]",'90'); set("V[z_upload_rows]",'&V[Z_upload_rows]'); set("V[z_upload_rows_old]",'&V[z_upload_rows]'); enter('/nzguixt'); // <<---------???? println('Zmobile set mode finished'); }
The above function uses default values for “plant”, “start and end dates”, “download row number” and work center. But these values can also be retrieved from offline client criteria screen. Then these hard coded values are replaced by variables which hold values sent from offline client.
Once data is populated as below, the Offline client sends another “Enter” action to server and server executes this action via “scr_wkdr” function. “Enter” action invokes “zmobile_get_wo_oper_dtl_file” process in SAP which returns client request on the following screen based on the criteria populated in this screen.
The code for this is shown below:
function scr_wkdr() { println('inside Z_mode==WKDR'); inputfield([0,1],'WO ',[0,14],{"size":12,"name":"z_mobile_wo"}); inputfield([1,1],'Plant',[1,14],{"size":4,"name":"z_plant"}); inputfield([2,1],'Work Ctr',[2,14],{"size":8,"name":"z_work_ctr"}); inputfield([3,1],'Funcl Loc',[3,14],{"size":18,"name":"z_mobile_floc"}); inputfield([4,1],'Equipment ',[4,14],{"size":18,"name":"z_mobile_equipment_no"}); inputfield([5,1],'Order Type',[5,14], {"size":4,"name":"z_mobile_otype"}); inputfield([5,20],'To',[5,25],{"size":4,"name":"z_mobile_otype2"}); inputfield([7,1],'Rows',[7,14],{"size":3,"name":"z_download_rows"}); inputfield([9,1], 'From Date',[9,14],{"size":10,"name":"z_mobile_from_date"}); text([9,25],'MM/DD/YYYY'); inputfield([10,1], 'To Date',[10,14],{"size":10,"name":"z_mobile_to_date"}); text([10,25],'MM/DD/YYYY'); if(!isBlank(cur_row)){ setcursor([cur_row,cur_col]); } onUIEvents['Enter']= {"process":zmobile_get_wo_oper_dtl_file_txt,"using":{"l_mode":"UPDATE_WO_RESULT","l_prev_mode":"WO"}}; } //Setting defaults if(Z_mode=='wkdr') { set("V[z_mobile_wo]",""); set("V[z_plant]",'1000'); set("V[z_work_ctr]",'MECHANIK'); } set("V[z_mobile_from_date]",'01.04.2003'); set("V[z_mobile_to_date]",'06.07.2006'); set("V[z_download_rows]",'90'); set("V[z_upload_rows]",'&V[Z_upload_rows]'); set("V[z_upload_rows_old]",'&V[z_upload_rows]'); enter('/nzguixt'); // <<---------???? println('Zmobile set mode finished'); }
Data returned to server as a result of this process is painted on the server with the help of GuiXT scripts as shown below:
Now it is time to forward this data to Offline. Offline can only get whatever it sees on the screen. If data retrieved from SAP is more than the data that is currently displayed on this screen, then a scroll function is executed after each read of data in the current screen by offline till all data is read. Scroll functions are covered later in this document.
The metadata tag must be defined for all data that is to be downloaded. The metadata tag is a guideline that Offline uses to verify the validity of the data. Metadata includes the following:
- Total number of records downloaded &V[z_total_rows]
- The number of rows that are read at a time from a screen &V[cidx]
- How many columns the data will be inserted into in Offline
- Field names and field lengths
A sample metadata tags are shown below:
- All GuiXT variables must match the Offline database field definitions in terms of field length and field name.
- Inputfields are limited to 255 characters in SAP.
- Metadata tags are simple GuiXT variables and are represented by an array in Offline. The string can hold 255 characters, so fro any data definition that is larger than 255 characters. If a particular datatable has more than 255 characters in its metadata, then metadata tags for that particular download must be indexed.
Scroll function during a download process to process data flow to offline happens via “zmobile_navigate_items” function. A sample scenario for scrolling is as below:
- User has read 200 records from SAP in which only 100 (based on Rows value defined in the criteria screen) can be displayed on the SAPGUI screen in the background.
- This means that after the first 100 records is displayed on the server side, offline reads these 100 records updates its database and then sends an “Enter” action to server which the server executes to get the next 100 records. This determination to get the next set of records is done using below condition maintained on the server side.
if not V[z_line_empty=X] On "Enter" "process=zmobile_navigate_items.txt" using l_move = "&V[z_download_rows]" using l_time = "&V[nxtscrnid]" else On "Enter" "process=zmobile_back.txt" using l_mode = endif
As seen above, process checks whether there are more records to read (controlled by “z_line_empty” global variable) This variable gets a value only if there are no more records to be read on the server. If variable is blank, scroll happens. The determination whether variable is blank or not is done in the scrolling function (zmobile_navigate_items) as below. If there are no more records to read, the layout is set to initial layout which is blank. This value is sent as a parameter from the else part of the condition above to zmobile_back function to take the user back to the start screen of the background processing where the Offline client populates the process code. The code is shown below:
If not V[g_wo_no_&V[idx]] Set V[Z_mode] "&U[l_mode]" Set V[z_line_empty] "X" goto loop_end Endif
For process to decide whether there are more items to scroll or not as shown above, it needs to do the scroll first and at each scroll it checks above condition and if condition is satisfied it quits scrolling. Scrolling process requires the calculation of the rows left to be read each time. If there is data to scroll, then two parameters are sent to zmobile_navigate_items function to set the number of data to be read and the scrolling index.
- l_move: Defines how many rows should be scrolled each time.
- l_time: Defines the number of scroll happens in the server.
This calculation happens via below assignment.
function zmobile_navigate_items(param){ l_time=param.l_time; l_move=param.l_move; tmp_calc = parseInt(z_download_rows) * parseInt(l_time); tmp_idx = parseInt(z_total_rows) - parseInt(tmp_calc); … …. … }
Tmp_calc is used to calculate tmp_idx which is the rows left to be read. If rows left to be read are more than the rows user specifies in main menu then the metadata displays whatever user specifies, if it is less than the rows user specifies in main menu then metadata displays the left number of rows so that offline knows that many rows need to be downloaded to database. This means metadata variable (cidx – please check fig 1 above) that represents rows to be displayed on the screen changes dynamically to let offline know how many records should be downloaded to offline database each time.
temp = parseInt(z_idx) + parseInt(l_move);
The above assignment shown in the following code gets the current row read everytime and assigns it as starting row index for the next scroll.
function zmobile_navigate_items(param){ l_time=param.l_time; l_move=param.l_move; tmp_calc = parseInt(z_download_rows) * parseInt(l_time); tmp_idx = parseInt(z_total_rows) - parseInt(tmp_calc); if(parseInt(tmp_idx) > parseInt(z_download_rows)) { set("V[cidx]", '&V[z_download_rows]'); println('V[cidx] set as '+ cidx); } else { println('V[cidx] else set as'+ tmp_idx); set("V[cidx]",'&V[tmp_idx]'); } if(Z_mode=='UPDATE_WO_RESULT') { set("V[z_header_metadata_0]", '&V[z_total_rows]:&V[cidx]:7:g_wo_no:8:g_wo_activity:4:g_order_info_second:4:g_order_info_third:40:g_Mn_Wk_ctr_info:10:g_Equipment_info:12:g _wo_location:12'); set("V[z_header_metadata_1]",'&V[z_total_rows]:&V[cidx]:2:g_notification_info:12:g_sys_status_info: 30'); } set("V[z_line_empty]",""); temp = parseInt(z_idx) + parseInt(l_move); println('TEMP VALUE IS: ' + temp); if(parseInt(l_move)>0) { //Move forward by l_move set("V[idx]",'&V[z_idx]'); set("V[count]",'1'); loop_start: println('The Zmode is' +Z_mode); if(Z_mode=='UPDATE_WO_RESULT') { set('V[z_temp_no]','&V[g_wo_no_&V[idx]]'); if(isBlank(z_temp_no)){ set("V[Z_mode]",''); set("V[z_idx]",''); set("V[z_line_empty]",'X'); goto funcloop_end; } } if(parseInt(count) > parseInt(z_download_rows)){ goto funcloop_end; } idx++; count++; goto loop_start; funcloop_end: if(z_line_empty != 'X') { set("V[z_idx]",'&V[temp]'); } } nxtscrnid++; enter('/nzguixt'); }
According to above user input scrolling happens two times (100*2=200) to read all the records. Please see the Data Synchronization section for additional information on how the upload process is initiated from the Offline client and which parameters are used.