Changing SAP data is more complex than reading it. The following should be noted:
As an example, we include the change of some fields of the customer address in our application. For this we first define a button within the display of the address, with which the user can switch to the change mode:
In the HTML file the button is defined as follows:
HTML<!-- Change address -->
<img src="../../../icons/edit.png"
style="width:32px; margin:8px; float:right"
onclick="S10Apply('to_change');"/>
That is, we display a suitable png image, move it to the right side with "float:right" and execute the ABAP method "to_change" when clicking on it.
If the application is also intended to be a desktop application, we give the button a tooltip with the option title=, for example <img ... title="Change address" />:
In the ABAP method "to_change" we navigate to a new screen "change". Before that it is necessary
since it may be that another user has changed the address while we were on the display screen for a while. In change mode we must always display the actual data, otherwise when we "Save" we overwrite an intermediate change made by another user. So when transitioning to change mode, always lock first, then read again:
ABAP* to address change
method to_change.
* enqueue KNA1
enqueue( ).
* read data again
s10databaseread( ).
* to adress change
s10nextscreen( 'change').
endmethod.
The SAP system contains generated function modules for locking objects; their names begin with "enqueue_". The easiest way to find out which enqueue module you need to call is to call the relevant SAP change transaction and then use SM12 to see which lock was created with your user name. A double click on the lock entry shows the technical properties and there the "Lock Object name":
In this case we see that the function module "ENQUEUE_EXKNA1" must be called to lock. In our ABAP method "enqueue" we issue a suitable error message if the object is currently locked. The user who has currently locked the object can be found in the system field "sy-msgv1" after calling the enqueue module.
ABAP* enqueue KNA1
method enqueue.
call function 'ENQUEUE_EXKNA1'
exporting
kunnr = kunnr
exceptions
others = 1.
if sy-subrc ne 0.
s10errormessage(
exporting
text = |Customer is currently being processed by user | && sy-msgv1 ).
endif.
endmethod.
If the customer is not locked, s10nextscreen( "change" ) will call the change screen "change":
The address fields are now ready for input and marked as mandatory. The country is selectable via a dropdown field and the functions "Check", "Save" and "Back" are available. The HTML file for this:
HTML
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type"
content="text/html; charset=utf-8">
<meta name="viewport"
content="width=400">
<link rel='stylesheet' type='text/css'
href='../../../style/s10.style.css'>
<link rel='stylesheet' type='text/css'
href='../../../style/custom.style.css'>
<script
src='../../synactiveS10/synactiveS10.java.js'>
</script>
<title>Customer information</title>
</head>
<body style="width: 100%; margin: 0px; padding: 0px;"
onload='init();'
class="colorscheme9">
<div class="headerarea"
style="width: 100%; padding: 10px;">
<b>
Address change customer
<span class='output'
type="text"
name='kunnr'>
</span>
</b>
<br />
<br />
<button type="button"
class="toolbarbutton"
onclick="S10Apply('check');">
Check
</button>
<button type="button"
class="toolbarbutton"
onclick="S10Apply('save');">
Save
</button>
<button type="button"
class="toolbarbutton"
onclick="S10Apply('change_to_display');">
Back
</button>
</div>
<div style="max-width: 800px">
<!-- Name 1 -->
<div class="infoblock2"
style="height: 50px">
<label class='label output'
name="name1"
for='name1'>
</label>
<br />
<input type="text"
class="input"
required
name="name1"
id="name1"
style="width: 300px;">
</div>
<br />
<!-- Street -->
<div class="infoblock2"
style="height: 50px">
<label class='label output'
name="stras"
for='stras'>
</label>
<br />
<input type="text"
class="input"
required
name="stras"
id="stras"
style="width: 300px;">
</div>
<br />
<!-- Postal code -->
<div class="infoblock"
style="width: 100px;
height: 50px;">
<label class='label output'
name="pstlz"
for='pstlz'>
</label>
<br />
<input type="text"
class="input"
required
name="pstlz"
id="pstlz"
style="width: 80px;">
</div>
<!-- City -->
<div class="infoblock2"
style="height: 50px">
<label class='label output'
name="ort01"
for='ort01'>
</label>
<br />
<input type="text"
class="input"
required
name="ort01"
id="ort01"
style="width: 300px;">
</div>
<!-- Country -->
<div class="infoblock2"
style="height: 50px;">
<label class='label output'
name='land1'
for='land1'>
</label>
<br />
<select size="1"
name='land1'
data-s10dropdownlist='land1@dropdownlist'
id='land1'
class='inputselect'
required
style='width: 240px;'>
</select>
</div>
</div>
</body>
</html>
Some notes:
We implement "Check" and "Save" via the ABAP technique "Call transaction using...", which we use to execute the SAP transaction in the background, which then also performs all SAP checks.
For the user it then looks like this, for example::
For "Check", we just execute "Enter" instead of "Save" at the end; this way we get the original SAP error messages. To build the batch input session for XD02 we can use the "Recording Mode" in transaction SHDB:
We then convert the recording into ABAP coding by building a batch input session from the current input data:
ABAP
method save.
check_or_save( save = 'X' ).
endmethod.
method check.
check_or_save( save = 'N' ).
s10infomessage( 'Input data checked' ).
endmethod.
method check_or_save.
* bdc data
data:
bdcdatawa type bdcdata,
bdcdata type table of bdcdata.
* message table for call transaction
data:
messtabwa type bdcmsgcoll,
messtab type table of bdcmsgcoll.
* create bdc data
* screen 101
clear bdcdatawa.
bdcdatawa-program = 'SAPMF02D'.
bdcdatawa-dynpro = '0101'.
bdcdatawa-dynbegin = 'X'.
append bdcdatawa to bdcdata.
clear bdcdatawa.
bdcdatawa-fnam = 'RF02D-KUNNR'.
bdcdatawa-fval = s10getuservalue( 'KUNNR' ).
append bdcdatawa to bdcdata.
clear bdcdatawa.
bdcdatawa-fnam = 'RF02D-D0110'.
bdcdatawa-fval = 'X'.
append bdcdatawa to bdcdata.
clear bdcdatawa.
bdcdatawa-fnam = 'BDC_OKCODE'.
bdcdatawa-fval = '/0'.
append bdcdatawa to bdcdata.
* screen 110
clear bdcdatawa.
bdcdatawa-program = 'SAPMF02D'.
bdcdatawa-dynpro = '0110'.
bdcdatawa-dynbegin = 'X'.
append bdcdatawa to bdcdata.
clear bdcdatawa.
bdcdatawa-fnam = 'KNA1-NAME1'.
bdcdatawa-fval = s10getuservalue( 'NAME1' ).
append bdcdatawa to bdcdata.
clear bdcdatawa.
bdcdatawa-fnam = 'KNA1-ORT01'.
bdcdatawa-fval = s10getuservalue( 'ORT01' ).
append bdcdatawa to bdcdata.
clear bdcdatawa.
bdcdatawa-fnam = 'KNA1-STRAS'.
bdcdatawa-fval = s10getuservalue( 'STRAS' ).
append bdcdatawa to bdcdata.
clear bdcdatawa.
bdcdatawa-fnam = 'KNA1-PSTLZ'.
bdcdatawa-fval = s10getuservalue( 'PSTLZ' ).
append bdcdatawa to bdcdata.
clear bdcdatawa.
bdcdatawa-fnam = 'KNA1-LAND1'.
bdcdatawa-fval = s10getuservalue( 'LAND1' ).
append bdcdatawa to bdcdata.
clear bdcdatawa.
bdcdatawa-fnam = 'BDC_OKCODE'.
if save = 'X'.
bdcdatawa-fval = '=UPDA'.
else.
bdcdatawa-fval = '/0'.
endif.
append bdcdatawa to bdcdata.
* dequeue, otherwise account is locked
dequeue( ).
call transaction 'XD02' with authority-check
using bdcdata
mode 'N'
update 'S'
messages into messtab.
* enqueue again
enqueue( ).
data: messagetext type string.
loop at messtab into messtabwa.
* get message text
message
id messtabwa-msgid type messtabwa-msgtyp number messtabwa-msgnr
with messtabwa-msgv1 messtabwa-msgv2 messtabwa-msgv3 messtabwa-msgv4
into messagetext.
case messtabwa-msgtyp.
when 'E' or 'A'.
* set focus for known input fields
case messtabwa-fldname.
when 'KNA1-LAND1'. s10setfocus( 'LAND1' ).
when 'KNA1-PSTLZ'. s10setfocus( 'PSTLZ' ).
endcase.
s10errormessage( messagetext ).
when others.
* final message after "save"
if save = 'X'.
s10infomessage( messagetext ).
endif.
endcase.
endloop.
endmethod.
Please note:
The implementation of the function "Back from change mode" is simple in principle: we unlock the object and set the next screen "display". At this point, however, be sure to re-read the data so that in the event of incorrect entries and then "Back", all fields are at the currently saved status.
ABAPmethod change_to_display.
* dequeue KNA1
dequeue( ).
* read data again
s10databaseread( ).
* next screen: display
s10nextscreen( 'display').
endmethod.