Alright. The title could seem to be misleading content, however ABAP engineers in all actuality do have the Ability to Kill the SAP Meeting.
This report has given me the potential chance to display the force of an ABAP colleagues. You have consistently subverted the help of an ABAPer. You have involved them for SAP house keeping assignments. In any case, ABAP colleagues are the foundation of any SAP Task. So keep in mind the strong ABAPer.
Recall my last article start to finish of AL11? A premise partner of mine assisted me with realizing about the server subtleties/making of catalog and so forth. Presently it was restitution time. I was somewhat strained, what I could have to propose for the assistance however my partner is a straightforward person. He simply needed an assistance with an irritating day to day work nothing else. Fewww!!
This present time was the opportunity to say thanks to him with my ABAP expertise.
Over a coffee break, he nonchalantly let me know that the Premise group has one occupation booked to refresh some expert information. They plan the occupation during the lean window time period after business hours yet some way or another frequently they discover a few clients locking the exchange the premise group necessities to refresh. Also, assuming any client is sitting in that material expert, the premise work fizzled and the premise group needed to re-run once more.
Our Premise Colleagues were disappointed as they needed to screen the work consistently and reschedule it once more on the off chance that it fizzled.
In the wake of hearing his agony, I could understand his predicament. After all ABAPers are likewise survivor of comparative misery. At any rate, I needed to give back in kind and this was the perfect opportunity.
Here is the summary of the issue:
There is a group work which refreshes the material expert (for straightforwardness expect the information in table MARA) on consistent schedule. However, on the off chance that some client has signed into that material in MM02, the occupation neglects to refresh the material expert and logs the lock object blunder. Premise group needs to re-run the occupation once more.
How often have you opened the SM30 t-code or MM02 or VA02 meetings at night and left for home without closing down your framework? Presently anybody working late evening or in some other time region can’t utilize SM30 to keep up with the table you have opened. Whenever you are finished for the afternoon, log off your SAP framework and shut down your machine. It will assist a worldwide temperature alteration and keep the earth with greening. (from Gyan Bhandar)
My Premise companion needed an answer on need premise.
High level Solution Architecture
- Check the number of clients that are locking the Material Expert exchange.
- Give Spring Up advance notice message to those clients to save their meeting and emerge from exchange in 5 minutes or less.
- Following 5 minutes (time ought to be configurable and not hard coded), check again for those are as yet locking the exchange. Give the second and last admonition to save their work in 5 minutes or less.
- After additional 5 minutes, the material expert exchange which the client is locking would be delivered/shut. Any remaining exchanges and meetings which are not slowing down the gig is left immaculate.
Sounds interesting? Now, action time.
Steps:
Identify Users:
Capability module ENQUEUE_READ gives the subtleties of locks.
Here, I will give sy-uname = my name as I will test this article and don’t have any desire to close other’s meetings.
After full testing, will eliminate my name with ‘*’ to get every one of the clients.
*** FM to get all lock subtleties of MARA table (like SM12)
CALL FUNCTION 'ENQUEUE_READ'
EXPORTING
gname = 'MARA'
guname = '$SBHANDARE'
TABLES
enq = gt_lock_details
EXCEPTIONS
communication_failure = 1
system_failure = 2
OTHERS = 3.
IF sy-subrc <> 0.
EXIT.
ENDIF.
Get active sessions:
When we know which clients are locking our exchange, we really want to figure out the number of meetings that are open in the clients’ framework.
There is a standard ABAP class SERVER_INFO which will give us generally dynamic meeting data.
*** Get all user sessions
CREATE OBJECT server_info.
gt_session_list = server_info->get_session_list( with_application_info = 1 ).
Now we need to filter out the sessions which belong to our users with client details.
*** Filter user sessions on the basis of username and client.
gt_session_list_user = VALUE #( FOR ls_lock_details IN gt_lock_details
FOR ls_session_list IN gt_session_list
WHERE ( user_name = ls_lock_details-guname
AND tenant = sy-mandt )
( ls_session_list ) ).
At this point, we have all open meetings of our objective clients as it were.
Time to send alerts and notices to these obstinate clients. Might be focused clients.
We go through FM ‘POPUP_TO_CONFIRM’ for pop messages. Be that as it may, there is a trick. POPUP_TO_CONFRIM will give message to the individual who is running the report or program. The client who has opened the screen in change mode won’t get notice in the event that we utilize this FM. Anyway, what is the other option?
Visit in SAP. Indeed, you read it right. You can send unknown spring up messages to anybody in your office SAP organization. The beneficial thing is they can not find the source name without any problem. I truly want to believe that you are not thinking what I’m thinking. Prepared for teen trick?
FM ‘TH_POPUP’ assists us with sending spring up messages to any client in the organization framework. Works entirely in our situation.
DATA(gv_msg) = |You are locking Transaction { gv_tcode }. Please save and leave the transaction within 5 Secs!!!|.
DATA gv_message TYPE sm04dic-popupmsg.
gv_message = gv_msg.
LOOP AT gt_lock_details INTO gs_lock_details.
CALL FUNCTION 'TH_POPUP'
EXPORTING
client = sy-mandt
user = gs_lock_details-guname
message = gv_message
EXCEPTIONS
user_not_found = 1
OTHERS = 2.
ENDLOOP.
Circling through the clients table, we can send notice to every one of the clients who are locking our exchange.
We should stand by from 5 minutes with the goal that clients can save the information and close the meeting.
WAIT UP TO 300 SECONDS.
ABAP Stand by proclamation in SAP Work process almost carried my SAP Creation framework to end. That is a fascinating story which I will tell another day. I even have the title of the article as a primary concern – “Stand by Pause.. try not to utilize me”.
Following 5 minutes, check again for the rundown of clients who are perched on our exchange. In the middle between assuming that any new client locks the exchange; this unfortunate person would just get 5 minutes. They wouldn’t get the second admonition as the main rundown of clients are getting.
gv_msg = |grrr..You are still locking Transaction { gv_tcode }. Your session will be killed soon!!!|.
gv_message = gv_msg.
LOOP AT gt_lock_details ASSIGNING <fs_lock_details>.
CALL FUNCTION 'TH_POPUP'
EXPORTING
client = sy-mandt
user = <fs_lock_details>-guname
message = gv_message
EXCEPTIONS
user_not_found = 1
OTHERS = 2.
ENDLOOP.
Stand by from conclusive 5 minutes to allow the clients another opportunity to save the information and close the meeting.
WAIT UP TO 300 SECONDS.
After the tenth moment, take the rundown of clients who are as yet locking the exchange. They are the folks who have previously left for the afternoon or are chatting on telephone for over 10 minutes. Incidentally, with whom could they talk at these late hours?
Activity Time.
We will utilize framework part call to get all dynamic meeting subtleties same as t-code SM04.
"get technical info for the user
CALL 'ThUsrInfo' ID 'OPCODE' FIELD opcode_usr_info
ID 'TID' FIELD <fs_session_list>-logon_hdl
ID 'WITH_APPL_INFO' FIELD with_appl_info
ID 'TABLE' FIELD gt_usr_info[].
Here we will get an enormous rundown of numerous lines for every meeting number (0-6) that the client has opened. Each login by a client is doled out an exceptional login ID which is produced in light of boundaries you sign in with viz: the client number, framework, and language. This meeting ID has the type of TXX_UXXXXX, where X can be any number 0-9.
Every meeting then has a meeting ID which is contained first the login ID as portrayed above, with an annexed _MX, where X for this situation is the meeting number, 0-6 (meeting 1-7). Thus, we are keen on the .meeting worth of this specialized rundown:
modelinfo[0] is for session 1. Similarly [1] and [2] would be for session 2 and 3 respectively.
modeinfo[1].session = T51_U11407_M1
Session 3 would have: modeinfo[2].session = T51_U11407_M2
Presently we really want to utilize the ‘/UPD’ esteem in the specialized data to get the specific meeting utilized by the client. You got it right. UPD should be for Update Mode.
CONCATENATE <fs_lock_details>-gusrvb '/UPD' INTO DATA(gv_value).
READ TABLE gt_usr_info ASSIGNING FIELD-SYMBOL(<fs_usr_info>)
WITH KEY value = gv_value.
IF sy-subrc IS INITIAL.
"The key for the value is 'modeinfo[X].enq_info'.... we need just the X
gv_modus_index = <fs_usr_info>-field+9(1).
ELSE.
CONTINUE.
ENDIF.
Presently we will really do above process and make the rundown of the clients with expected meetings which we really want to close/kill.
In the wake of setting up the last client list, I attempted to sort out the correct method for killing the meeting of client yet fizzled if beginning endeavor.
I attempted to do the BDC recording of SM12 with erase usefulness yet that didn’t work. Not certain, might be I didn’t have the right approval. However, i didn’t dig profound.
Then I explored t-code SM04. I did the BDC recording of it and sent client meeting number to kill that meeting.
" call transaction SM04, sync (S), no screens
CALL TRANSACTION 'SM04'
USING bdcdata
MODE 'N'
UPDATE 'S'.
" Now use bdc to end the session with that session id
CLEAR bdcdata[].
PERFORM bdcdaten USING:
'X' 'SAPMSSY0' '0120',
' ' 'BDC_CURSOR' '04/03',
' ' 'BDC_OKCODE' '=&OL0'.
PERFORM bdcdaten USING:
'X' 'SAPLSKBH' '0800',
' ' 'BDC_CURSOR' 'GT_FIELD_LIST-SELTEXT(01)',
' ' 'BDC_OKCODE' '=WLSE',
' ' 'GT_FIELD_LIST-MARK(01)' 'X',
' ' 'BDC_SUBSCR' 'SAPLSKBH 0810SUB810'.
PERFORM bdcdaten USING:
'X' 'SAPLSKBH' '0800',
' ' 'BDC_CURSOR' 'GT_FIELD_LIST-SELTEXT(01)',
' ' 'BDC_OKCODE' '=CONT',
' ' 'BDC_SUBSCR' 'SAPLSKBH 0810SUB810'.
PERFORM bdcdaten USING:
'X' 'SAPMSSY0' '0120',
' ' 'BDC_CURSOR' '04/03',
' ' 'BDC_OKCODE' '=PS 63'.
PERFORM bdcdaten USING:
'X' 'SAPMSSY0' '0120',
' ' 'BDC_CURSOR' '02/76',
' ' 'BDC_OKCODE' '=&IC1'.
PERFORM bdcdaten USING:
'X' 'SAPMSSY0' '0120',
' ' 'BDC_CURSOR' '02/76',
' ' 'BDC_OKCODE' '=&ILT'.
PERFORM bdcdaten USING:
'X' 'SAPLSSEL' '1104',
' ' 'BDC_OKCODE' '=CRET',
' ' 'BDC_SUBSCR' 'SAPLSSEL 1105%_SUBSCREEN_FREESEL',
' ' 'BDC_CURSOR' '%%DYN001-LOW',
' ' '%%DYN001-LOW' gv_ssi_session_id.
PERFORM bdcdaten USING:
'X' 'SAPMSSY0' '0120',
' ' 'BDC_CURSOR' '04/15',
' ' 'BDC_OKCODE' '=&IC1'.
PERFORM bdcdaten USING:
'X' 'RSM04000_ALV_NEW' '2000',
' ' 'BDC_CURSOR' gv_modus_string,
' ' 'BDC_OKCODE' '=DEL'.
PERFORM bdcdaten USING:
'X' 'SAPMSSY0' '0120',
' ' 'BDC_CURSOR' '04/15',
' ' 'BDC_OKCODE' '=&F15'.
" call transaction SM04, sync (S), no screens
CALL TRANSACTION 'SM04'
USING bdcdata
MODE 'P'
UPDATE 'N'.
At long last we should hold nothing back and shut down that session(s). When that’s what we do, we log which meeting/client/exchange combo we erased to the spool so nobody can cry unfairness later. We gave sufficient time individuals!
Try not to feel frustrated about shutting the meetings. We cautioned the clients two times, allowed them 10 minutes to save the thing however in the event that they are as yet impeding our exchange. We were constrained for the assault.
Here and there, we should be troublesome. Removing the clients from the framework guarantees that the general framework is adjusted with state-of-the-art ace information.
This is my number one line from Spiderman “to whom much is given, much will be expected”. Continuously utilize your super power justifiably.
Check this video for the output in action:
You can utilize the beneath code in your framework and execute it. Remember to eliminate the hard code 300 seconds and my sy-uname. Assuming your framework is beneath 7.4, you really want to change the new language structure to old and furthermore you probably won’t have a few information components.
Working Code
*&---------------------------------------------------------------------*
*& Report ZUSER_SESSION_KILL
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
REPORT zuser_session_kill.
*** Types declarations.
DATA:BEGIN OF gt_usr_info OCCURS 10,
field(40),
value(80),
END OF gt_usr_info.
*** Variable declarations.
DATA: gv_time TYPE string,
gv_tcode TYPE eqetcode,
gv_ssi_session_id TYPE ssi_session_id,
gv_modus_num_found TYPE ssi_session_hdl,
gv_modus_index_char TYPE numc1,
gv_message TYPE sm04dic-popupmsg,
gv_modus_string TYPE string,
gv_modus_index TYPE string,
gv_stop TYPE c,
th_opcode(1) TYPE x.
*** Internal table declarations.
DATA: gt_lock_details TYPE TABLE OF seqg3,
gt_session_list TYPE TABLE OF ssi_session_info,
gt_session_list_user TYPE TABLE OF ssi_session_info,
gt_sessions_user TYPE TABLE OF ssi_session_info.
*** Workareas declarations.
DATA: server_info TYPE REF TO cl_server_info,
bdcdata LIKE bdcdata OCCURS 0 WITH HEADER LINE.
*** Constants declarations.
CONSTANTS: opcode_usr_info LIKE th_opcode VALUE 52,
with_appl_info TYPE ssi_bool VALUE 1. " this is the internal SAP number
CLEAR gv_time.
"To stop the loop processing.
WHILE gv_stop NE abap_true.
"send notification to users, those who are locking our table, do it till 10 seconds.
IF gv_time IS INITIAL. " First warning message after 5 minutes
*** fm to GET all lock details of mara table (like sm12)
CALL FUNCTION 'ENQUEUE_READ'
EXPORTING
gname = 'MARA'
guname = '$SBHANDARE'
TABLES
enq = gt_lock_details
EXCEPTIONS
communication_failure = 1
system_failure = 2
OTHERS = 3.
IF sy-subrc <> 0.
EXIT.
ENDIF.
DATA(gv_msg) = |You are locking Transaction { gv_tcode }. Please save and leave the transaction within 5 Secs!!!|.
gv_message = gv_msg.
LOOP AT gt_lock_details ASSIGNING FIELD-SYMBOL(<fs_lock_details>).
CALL FUNCTION 'TH_POPUP'
EXPORTING
client = sy-mandt
user = <fs_lock_details>-guname
message = gv_message
EXCEPTIONS
user_not_found = 1
OTHERS = 2.
ENDLOOP.
WAIT UP TO 300 SECONDS.
gv_time = '01'.
FREE: gt_lock_details[], gv_message, gv_msg.
"send notification to users, those who are locking our table after first notification too, do it from 5 seconds to 45 seconds.
ELSEIF gv_time = '01'. " Second warning message
*** FM to get all lock details of MARA table (like SM12)
CALL FUNCTION 'ENQUEUE_READ'
EXPORTING
gname = 'MARA'
guname = '$SBHANDARE'
TABLES
enq = gt_lock_details
EXCEPTIONS
communication_failure = 1
system_failure = 2
OTHERS = 3.
IF sy-subrc <> 0.
EXIT.
ENDIF.
gv_msg = |Uff...You are still locking Transaction { gv_tcode }. Your session will be killed soon!!!|.
gv_message = gv_msg.
LOOP AT gt_lock_details ASSIGNING <fs_lock_details>.
CALL FUNCTION 'TH_POPUP'
EXPORTING
client = sy-mandt
user = <fs_lock_details>-guname
message = gv_message
EXCEPTIONS
user_not_found = 1
OTHERS = 2.
ENDLOOP.
WAIT UP TO 300 SECONDS.
gv_time = '03'.
FREE: gt_lock_details[], gv_message, gv_msg.
"kill the user sessions after 50 seconds.
ELSEIF gv_time = '03'.
gv_stop = abap_true.
*** FM to get all lock details of MARA table (like SM12)
CALL FUNCTION 'ENQUEUE_READ'
EXPORTING
gname = 'MARA'
guname = '$SBHANDARE'
TABLES
enq = gt_lock_details
EXCEPTIONS
communication_failure = 1
system_failure = 2
OTHERS = 3.
IF sy-subrc <> 0.
EXIT.
ENDIF.
*** Get all user sessions
CREATE OBJECT server_info.
gt_session_list = server_info->get_session_list( with_application_info = 1 ).
*** Filter user sessions on the basis of username and client.
gt_session_list_user = VALUE #( FOR ls_lock_details IN gt_lock_details
FOR ls_session_list IN gt_session_list
WHERE ( user_name = ls_lock_details-guname
AND tenant = sy-mandt )
( ls_session_list ) ).
FREE: gt_session_list[].
LOOP AT gt_lock_details ASSIGNING <fs_lock_details>.
gv_tcode = <fs_lock_details>-gtcode.
CLEAR gt_sessions_user.
LOOP AT gt_session_list_user ASSIGNING FIELD-SYMBOL(<fs_session_list>). " loop at all open sessions to build a list of just the user sessions
CLEAR gv_modus_index.
CLEAR gt_usr_info[].
"get technical info for the user
CALL 'ThUsrInfo' ID 'OPCODE' FIELD opcode_usr_info
ID 'TID' FIELD <fs_session_list>-logon_hdl
ID 'WITH_APPL_INFO' FIELD with_appl_info
ID 'TABLE' FIELD gt_usr_info[].
"Need to use the '/UPD' value in the technical info to get the exact session used by user
CONCATENATE <fs_lock_details>-gusrvb '/UPD' INTO DATA(gv_value).
READ TABLE gt_usr_info ASSIGNING FIELD-SYMBOL(<fs_usr_info>)
WITH KEY value = gv_value.
IF sy-subrc IS INITIAL.
"The key for the value is 'modeinfo[X].enq_info'.... we need just the X
gv_modus_index = <fs_usr_info>-field+9(1).
ELSE.
CONTINUE.
ENDIF.
" If we found a session with that number, we know we had the correct logon... we can add this to the user list
IF gv_modus_index IS NOT INITIAL.
" convert to type ssi_session_handle for later lookup
gv_modus_num_found = gv_modus_index.
" get the session id for this specific session.
CONCATENATE 'modeinfo[' gv_modus_index '].session' INTO DATA(gv_field). " this time we need to find the value from the field
READ TABLE gt_usr_info ASSIGNING <fs_usr_info> WITH KEY field = gv_field.
IF sy-subrc IS INITIAL.
gv_ssi_session_id = <fs_usr_info>-value.
ENDIF.
APPEND <fs_session_list> TO gt_sessions_user.
ENDIF.
ENDLOOP.
IF gt_sessions_user[] IS NOT INITIAL.
SORT gt_sessions_user BY session_hdl ASCENDING.
READ TABLE gt_sessions_user TRANSPORTING NO FIELDS
WITH KEY session_hdl = gv_modus_num_found .
IF sy-subrc IS INITIAL.
" Kill only the session from the table that matches the index of the modus found
gv_modus_index_char = sy-tabix.
CLEAR gv_modus_string.
CONCATENATE 'MODUS-MTCODE(0' gv_modus_index_char ')' INTO gv_modus_string.
ENDIF.
IF gv_modus_index_char EQ '0'.
CONTINUE.
ENDIF.
" First ensure that sm04 is called and set to the sessions view
CLEAR bdcdata[].
PERFORM bdcdaten USING:
'X' 'SAPMSSY0' '0120',
' ' 'BDC_CURSOR' '04/03',
' ' 'BDC_OKCODE' '=SESSIONS'.
" call transaction SM04, sync (S), no screens
CALL TRANSACTION 'SM04'
USING bdcdata
MODE 'N'
UPDATE 'S'.
" Now use bdc to end the session with that session id
CLEAR bdcdata[].
PERFORM bdcdaten USING:
'X' 'SAPMSSY0' '0120',
' ' 'BDC_CURSOR' '04/03',
' ' 'BDC_OKCODE' '=&OL0'.
PERFORM bdcdaten USING:
'X' 'SAPLSKBH' '0800',
' ' 'BDC_CURSOR' 'GT_FIELD_LIST-SELTEXT(01)',
' ' 'BDC_OKCODE' '=WLSE',
' ' 'GT_FIELD_LIST-MARK(01)' 'X',
' ' 'BDC_SUBSCR' 'SAPLSKBH 0810SUB810'.
PERFORM bdcdaten USING:
'X' 'SAPLSKBH' '0800',
' ' 'BDC_CURSOR' 'GT_FIELD_LIST-SELTEXT(01)',
' ' 'BDC_OKCODE' '=CONT',
' ' 'BDC_SUBSCR' 'SAPLSKBH 0810SUB810'.
PERFORM bdcdaten USING:
'X' 'SAPMSSY0' '0120',
' ' 'BDC_CURSOR' '04/03',
' ' 'BDC_OKCODE' '=PS 63'.
PERFORM bdcdaten USING:
'X' 'SAPMSSY0' '0120',
' ' 'BDC_CURSOR' '02/76',
' ' 'BDC_OKCODE' '=&IC1'.
PERFORM bdcdaten USING:
'X' 'SAPMSSY0' '0120',
' ' 'BDC_CURSOR' '02/76',
' ' 'BDC_OKCODE' '=&ILT'.
PERFORM bdcdaten USING:
'X' 'SAPLSSEL' '1104',
' ' 'BDC_OKCODE' '=CRET',
' ' 'BDC_SUBSCR' 'SAPLSSEL 1105%_SUBSCREEN_FREESEL',
' ' 'BDC_CURSOR' '%%DYN001-LOW',
' ' '%%DYN001-LOW' gv_ssi_session_id.
PERFORM bdcdaten USING:
'X' 'SAPMSSY0' '0120',
' ' 'BDC_CURSOR' '04/15',
' ' 'BDC_OKCODE' '=&IC1'.
PERFORM bdcdaten USING:
'X' 'RSM04000_ALV_NEW' '2000',
' ' 'BDC_CURSOR' gv_modus_string,
' ' 'BDC_OKCODE' '=DEL'.
PERFORM bdcdaten USING:
'X' 'SAPMSSY0' '0120',
' ' 'BDC_CURSOR' '04/15',
' ' 'BDC_OKCODE' '=&F15'.
" call transaction SM04, sync (S), no screens
CALL TRANSACTION 'SM04'
USING bdcdata
MODE 'P'
UPDATE 'N'.
" proper logging. times, order number, and transaction added as well as
WRITE: / 'User session from user ', <fs_lock_details>-guname, 'with session number', gv_modus_index_char, 'was deleted.'.
WRITE: / 'Object Lock Time Length:', <fs_lock_details>-gttime.
ENDIF.
ENDLOOP.
ENDIF.
ENDWHILE.
*&---------------------------------------------------------------------*
*& Form BDCDATEN
*&---------------------------------------------------------------------*
FORM bdcdaten USING start fnam fval.
CLEAR bdcdata.
IF start = abap_true.
bdcdata-dynbegin = start.
bdcdata-program = fnam.
bdcdata-dynpro = fval.
ELSE.
bdcdata-fnam = fnam.
bdcdata-fval = fval.
ENDIF.
APPEND bdcdata.
ENDFORM. " BDCDATEN
Below are the output snapshots of the code:
First Warning message to user (done for 5 secs time as doing testing):
Second Warning message after 10 minutes to user:
SM12 entry of lock:
Following 10 minutes, the meetings which are locking the material expert will be shut.
Trust you saw this as fascinating. Attempt it inside in your group and recall its effect. Additionally observe the illegal framework part calls.
YOU MAY BE INTERESTED IN
Courses for sap ABAP on HANA training with real-time by Experts
OData in SAP ABAP: Streamlining Data Exchange and Integration