Hirdetés


Chat program ABAP-ban? Igen, lehetséges!

PDF
Nyomtatás

abapchat.jpgKorábbi Tudásmorzsák kiadásokban már írtunk Kabai Imre (www.kabai.com) ABAP forráskódjairól, így gondoltuk folytatjuk ezt a hagyományt. Ebben a rövid leírásban egy olyan programról szól, ami lehetővé teszi két bejelentkezett felhasználó számára, hogy chateljenek egymással a SAPGui-n keresztül. Izgalmasan hangzik, igaz?
A program működéséhez két Z reportot kell létrehoznunk, az egyik, a ZPOPUP maga a chat program, amit el kell indítani mindkét felhasználónak, a másik pedig a ZPOPUPDE, ami a kommunikációt biztosítja.

Ez a terminal program, ami a két felhasználó közötti kommunikációért felelős.


REPORT ZPOPUPDE.
************************************************************************
* The programs ZPOPUP and ZPOPUPDE implement a talk utility -
* - similar to the UNIX talk or write commands.
* The two instances of zpopups will negotiate the communication
* parameters and call zpopupde, the terminal module. Using the
* terminal window's buttons you can chat, get help or exit.
************************************************************************
TABLES: USR02, SSCRFIELDS, INDX.
DATA: C12(12), Q(12), LINE(90).
DATA: FIRST_TIME VALUE '1'.
DATA: I_AM.
DATA: A_NAME(22), B_NAME(22), AB_NAME(22), BA_NAME(22), MY_NAME(22).
DATA: MY_TURN.
DATA: MESSAGE(30) VALUE ' Waiting for an answer'.
DATA: NO_HELP_SCROLL.
* Selection screen begin
INITIALIZATION.
* Receive area
SET PF-STATUS 'ZCLEAR'.
SELECTION-SCREEN BEGIN OF BLOCK A WITH FRAME.
SELECTION-SCREEN BEGIN OF LINE.SELECTION-SCREEN POSITION 1.
PARAMETERS: REMOTE(12) MODIF ID ABB.
SELECTION-SCREEN END OF LINE.
selection-screen begin of line.selection-screen position 1.
PARAMETERS: A(45) MODIF ID ABC LOWER CASE.
SELECTION-SCREEN END OF LINE.
selection-screen begin of line.selection-screen position 1.
PARAMETERS: B(45) MODIF ID ABC LOWER CASE.
SELECTION-SCREEN END OF LINE.
selection-screen begin of line.selection-screen position 1.
PARAMETERS: C(45) MODIF ID ABC LOWER CASE.
SELECTION-SCREEN END OF LINE.
selection-screen begin of line.selection-screen position 1.
PARAMETERS: D(45) MODIF ID ABC LOWER CASE.
SELECTION-SCREEN END OF LINE.
selection-screen begin of line.selection-screen position 1.
PARAMETERS: E(45) MODIF ID ABC LOWER CASE.
SELECTION-SCREEN END OF LINE.
selection-screen begin of line.selection-screen position 1.
PARAMETERS: F(45) MODIF ID ABC LOWER CASE.
SELECTION-SCREEN END OF LINE.
* Send area
SELECTION-SCREEN BEGIN OF LINE.SELECTION-SCREEN POSITION 1.
PARAMETERS: LOCAL(12) MODIF ID ABB.
SELECTION-SCREEN END OF LINE.
selection-screen begin of line.selection-screen position 1.
PARAMETERS: G(45) MODIF ID ABC LOWER CASE.
SELECTION-SCREEN END OF LINE.
selection-screen begin of line.selection-screen position 1.
PARAMETERS: H(45) MODIF ID ABC LOWER CASE.
SELECTION-SCREEN END OF LINE.
selection-screen begin of line.selection-screen position 1.
PARAMETERS: I(45) MODIF ID ABC LOWER CASE.
SELECTION-SCREEN END OF LINE.
selection-screen begin of line.selection-screen position 1.
PARAMETERS: J(45) MODIF ID ABC LOWER CASE.
SELECTION-SCREEN END OF LINE.
selection-screen begin of line.selection-screen position 1.
PARAMETERS: K(45) MODIF ID ABD LOWER CASE.
SELECTION-SCREEN END OF LINE.
selection-screen begin of line.selection-screen position 1.
PARAMETERS: L(45) MODIF ID ABD LOWER CASE.
SELECTION-SCREEN END OF LINE.
* Buttons
SELECTION-SCREEN SKIP 2.
SELECTION-SCREEN PUSHBUTTON 1(13) TEXT-010 USER-COMMAND SND.
SELECTION-SCREEN PUSHBUTTON 17(13) TEXT-011 USER-COMMAND EXI.
SELECTION-SCREEN PUSHBUTTON 33(13) TEXT-012 USER-COMMAND HLP.
SELECTION-SCREEN END OF BLOCK A.
* End of selection screen

* When a button is pressed
AT SELECTION-SCREEN.
* The SEND button or ENTER was pressed
IF SSCRFIELDS-UCOMM = 'SND' OR SSCRFIELDS-UCOMM IS INITIAL
OR SSCRFIELDS-UCOMM = 'AAAA'.
IF I_AM = 'I'. " I am an initiator
LINE = K. LINE+45(45) = L.
EXPORT LINE TO DATABASE INDX(ST) ID AB_NAME.
COMMIT WORK AND WAIT.
MY_TURN = '0'.
ELSEIF I_AM = 'R'. " I am a responder
LINE = K. LINE+45(45) = L.
EXPORT LINE TO DATABASE INDX(ST) ID BA_NAME.
COMMIT WORK AND WAIT.
MY_TURN = '0'.
ENDIF.
* The exit button was pressed (or green or yellow arrow, or red cross)
ELSEIF SSCRFIELDS-UCOMM = 'EXI'
OR SSCRFIELDS-UCOMM = 'BBBB'
OR SSCRFIELDS-UCOMM = 'CCCC'
OR SSCRFIELDS-UCOMM = 'DDDD'.
* Send the exit message to the partner and exit.
LINE = 'EXITEXITEXITEXITEXIT'.
EXPORT LINE TO DATABASE INDX(ST) ID BA_NAME.
EXPORT LINE TO DATABASE INDX(ST) ID AB_NAME.
COMMIT WORK AND WAIT.
LEAVE PROGRAM.
* If the HELP button was pressed
ELSEIF SSCRFIELDS-UCOMM = 'HLP'.
NO_HELP_SCROLL = '1'.
CALL FUNCTION 'POPUP_TO_INFORM'
EXPORTING
TITEL = 'HELP'
TXT1 = 'Enter the message using the input lines at the bottom'
TXT2 = 'Press ENTER or the SEND button to send the message'
TXT3 = 'Wait for the answer'
TXT4 = 'Press EXIT to close the connection'.
ENDIF.
* End: when a button is pressed

* Prepare the selection screen for output
AT SELECTION-SCREEN OUTPUT.
* When the display module runs the first time: import the communication
* parameters
IF FIRST_TIME = 1.
IMPORT I_AM A_NAME B_NAME AB_NAME BA_NAME FROM MEMORY ID 'AAA'.
IF I_AM = 'I'.
LOCAL = A_NAME.
REMOTE = B_NAME.
MY_TURN = '1'.
ELSEIF I_AM = 'R'.
LOCAL = B_NAME.
REMOTE = A_NAME.
MY_TURN = '0'.
ENDIF.
FIRST_TIME = 0.
ENDIF. " First time
* Wait for an answer (my_turn = '0')
IF MY_TURN = '0'. " Wait for the partner
CLEAR LINE.
IF I_AM = 'I'. " Listen on BA
DO.
IMPORT LINE FROM DATABASE INDX(ST) ID BA_NAME.
* Horray, a message has arrived
IF NOT LINE IS INITIAL.
DELETE FROM INDX WHERE RELID = 'ST' AND
SRTFD = BA_NAME.
COMMIT WORK AND WAIT.
MY_TURN = '1'.
EXIT.
ENDIF.
* No message yet: display a progress indicator
SHIFT MESSAGE CIRCULAR RIGHT.
CALL FUNCTION 'SAPGUI_PROGRESS_INDICATOR'
EXPORTING
PERCENTAGE = ''
TEXT = MESSAGE.
ENDDO.
* Wait for an answer (my_turn = '0')
ELSEIF I_AM = 'R'. " Listen on AB
DO.
IMPORT LINE FROM DATABASE INDX(ST) ID AB_NAME.
* Horray, a message has arrived
IF NOT LINE IS INITIAL. " An answer came
DELETE FROM INDX WHERE RELID = 'ST' AND
SRTFD = AB_NAME.
COMMIT WORK AND WAIT.
MY_TURN = '1'.
EXIT.
ENDIF.
* No message yet: display a progress indicator
SHIFT MESSAGE CIRCULAR RIGHT.
CALL FUNCTION 'SAPGUI_PROGRESS_INDICATOR'
EXPORTING
PERCENTAGE = ''
TEXT = MESSAGE.
ENDDO.
ENDIF.
ENDIF.
* my_turn = '1'
* An exit message come: free up the communication area and exit
IF LINE = 'EXITEXITEXITEXITEXIT'.
DELETE FROM INDX WHERE RELID = 'ST' AND
SRTFD = AB_NAME.
DELETE FROM INDX WHERE RELID = 'ST' AND
SRTFD = BA_NAME.
COMMIT WORK AND WAIT.
CALL FUNCTION 'POPUP_TO_INFORM'
EXPORTING
TITEL = 'INFORMATION'
TXT1 = 'Partner closed the connection'
TXT2 = ''.
LEAVE PROGRAM.
ENDIF.
* Prepare the selection screen fields for output
LOOP AT SCREEN.
IF SCREEN-GROUP1 = 'ABC' OR SCREEN-GROUP1 = 'ABB'.
SCREEN-INPUT = '0'.
MODIFY SCREEN.
ENDIF.
IF SCREEN-GROUP1 = 'ABB'.
SCREEN-INTENSIFIED = '1'.
MODIFY SCREEN.
ENDIF.
ENDLOOP.
* Scroll the input and output lines
IF NO_HELP_SCROLL <> '1'.
G = I. H = J.
I = K. J = L.
CLEAR K. CLEAR L. CLEAR NO_HELP_SCROLL.
ENDIF.
IF NOT LINE IS INITIAL. " Refresh the receive lines.
A = C. B = D.
C = E. D = F.
E = LINE(45). F = LINE+45(45).
ENDIF.

Ez pedig az említett chat program. Ezt kell elindítania mindkét felhasználónak.


REPORT ZPOPUP NO STANDARD PAGE HEADING.
************************************************************************
* The programs ZPOPUP and ZPOPUPDE implement a talk utility -
* - similar to the UNIX talk or write commands. When zpopup is
* started via a transaction (i.e. ZPOP) it displays the active users.
* By double-clicking on the username the remote user will receive
* a popup window inviting him for a chat. The remote user starts ZPOP
* as well, and the two instances of zpops will negotiate the
* communication parameters and call zpopupde, the terminal module.
* The terminal module will enable them to send and receive the messages.
* To make these programs work, you have to assign zpopup to transaction
* code ZPOP and create status ZCLEAR for zpopupde with only the
* enter(AAAA), green arrow(BBBB), yellow arrow(CCCC) and red cross(DDDD)
************************************************************************
DATA: ESTABLISHED.
DATA: I_AM.
DATA: LINE(90).
DATA: A_NAME(22), B_NAME(22), AB_NAME(22), BA_NAME(22), MY_NAME(22).
DATA: INDXKEY LIKE INDX-SRTFD.
TABLES INDX.
DATA: CURR_TIM LIKE SY-UZEIT.
DATA: TEMP_TIM TYPE T.
DATA: MESSAGE(128).
DATA: OPCODE TYPE X VALUE 2.
DATA: BEGIN OF USR_TABL OCCURS 10.
INCLUDE STRUCTURE UINFO.
DATA: END OF USR_TABL.
DATA: A(61).
DATA: TIM LIKE SY-UZEIT, N TYPE I VALUE 30, DTIM LIKE SY-UZEIT.

START-OF-SELECTION.
* Find out, if I am an initializator (A) or a responder (B)
MY_NAME = SY-UNAME.
INDXKEY = MY_NAME.
IMPORT LINE FROM DATABASE INDX(ST) ID INDXKEY.
IF SY-SUBRC <> 0. "Nothing there: I am an initializator
I_AM = 'I'.
A_NAME = SY-UNAME.
* Get the list of logged on users
CALL 'ThUsrInfo' ID 'OPCODE' FIELD OPCODE
ID 'TAB' FIELD USR_TABL-*SYS*.
WRITE: / 'Recently no one is waiting for you to connect.'.
WRITE: / 'Doubleclick on a name of an active user, to establish'.
WRITE: / 'a conversation or choose the green arrow to exit.'.
SKIP.
WRITE: /2(8) 'CLIENT',
10(14) 'USER NAME',
24(14) 'TRANSACTION',
38(24) 'LAST DIALOG STEP(AGO)'.
SKIP.
SORT USR_TABL BY MANDT BNAME.
LOOP AT USR_TABL.
IF NOT USR_TABL-BNAME IS INITIAL AND USR_TABL-BNAME <> SY-UNAME
AND USR_TABL-MANDT = SY-MANDT.
TEMP_TIM = USR_TABL-ZEIT.
CURR_TIM = SY-UZEIT - TEMP_TIM.
WRITE: /2(8) USR_TABL-MANDT,
10(14) USR_TABL-BNAME,
24(14) USR_TABL-TCODE,
38(24) CURR_TIM.
HIDE: USR_TABL-BNAME, USR_TABL-MANDT.
ENDIF.
ENDLOOP.
CLEAR USR_TABL.
ELSE. "I am a responder
I_AM = 'R'.
A_NAME = LINE.
B_NAME = SY-UNAME.
AB_NAME = A_NAME.
AB_NAME+11 = B_NAME.
CONDENSE AB_NAME NO-GAPS.
BA_NAME = B_NAME.
BA_NAME+11 = A_NAME.
CONDENSE BA_NAME NO-GAPS.
* B sends an answer to A
DELETE FROM INDX WHERE RELID = 'ST' AND
SRTFD = B_NAME.
CLEAR LINE.
EXPORT LINE TO DATABASE INDX(ST) ID AB_NAME.
LINE = 'How are you?'.
EXPORT LINE TO DATABASE INDX(ST) ID BA_NAME.
COMMIT WORK AND WAIT.
* B calls the display program
EXPORT I_AM A_NAME B_NAME AB_NAME BA_NAME TO MEMORY ID 'AAA'.
SUBMIT ZPOPUPDE VIA SELECTION-SCREEN.
ENDIF. "responder/initializator

* When a user is selected:
AT LINE-SELECTION.
* Double click
IF NOT USR_TABL-BNAME IS INITIAL. " When a partner is selected
* Set up my variables
B_NAME = USR_TABL-BNAME.
AB_NAME = A_NAME.
AB_NAME+11 = B_NAME.
CONDENSE AB_NAME NO-GAPS.
BA_NAME = B_NAME.
BA_NAME+11 = A_NAME.
CONDENSE BA_NAME NO-GAPS.
* Construct the popup message
MESSAGE = 'User'.
MESSAGE+5(12) = SY-UNAME.
MESSAGE+18(44) = 'would like to start a conversation with you.'.
MESSAGE+63(34) = 'Please run transaction ZPOP. Time:'.
MESSAGE+98(2) = SY-UZEIT.
MESSAGE+100(1) = ':'.
MESSAGE+101(2) = SY-UZEIT+2(2).
MESSAGE+103(1) = ':'.
MESSAGE+104(2) = SY-UZEIT+4(2).
MESSAGE+106(10) = ' (Pacific)'.
* A sends the popup window to B
CALL FUNCTION 'TH_POPUP'
EXPORTING
CLIENT = USR_TABL-MANDT
USER = USR_TABL-BNAME
MESSAGE = MESSAGE
EXCEPTIONS
USER_NOT_FOUND = 1.
* A initializes the comunication: write to B, AB, BA.
LINE = A_NAME.
EXPORT LINE TO DATABASE INDX(ST) ID B_NAME.
LINE = 'HELLO'.
EXPORT LINE TO DATABASE INDX(ST) ID AB_NAME.
CLEAR LINE.
EXPORT LINE TO DATABASE INDX(ST) ID BA_NAME.
COMMIT WORK AND WAIT.
* Wait for the reply for 60 seconds, display a status and check INDX
TIM = SY-UZEIT.
TIM = TIM + 60.
DO.
GET TIME.
DTIM = TIM - SY-UZEIT.
IF TIM < SY-UZEIT.
* No answer from B: clean INDX
DELETE FROM INDX WHERE RELID = 'ST' AND
SRTFD = B_NAME.
DELETE FROM INDX WHERE RELID = 'ST' AND
SRTFD = AB_NAME.
DELETE FROM INDX WHERE RELID = 'ST' AND
SRTFD = BA_NAME.
COMMIT WORK AND WAIT.
EXIT.
ENDIF.
* A displays a progress indicator while waiting
A = 'Waiting for'.
A+12(12) = USR_TABL-BNAME.
A+25(27) = 'to respond. Remaining time:'.
A+53(8) = DTIM.
CALL FUNCTION 'SAPGUI_PROGRESS_INDICATOR'
EXPORTING
PERCENTAGE = ''
TEXT = A.
* A waits for the answer of B: reading BA
IMPORT LINE FROM DATABASE INDX(ST) ID BA_NAME.
* An answer has come from B
IF NOT LINE IS INITIAL.
CLEAR LINE.
EXPORT LINE TO DATABASE INDX(ST) ID BA_NAME.
EXPORT LINE TO DATABASE INDX(ST) ID BA_NAME.
COMMIT WORK AND WAIT.
ESTABLISHED = '1'.
EXIT.
ENDIF.
ENDDO.
* Answer has come: wait for 4 seconds, the start the terminal module
IF ESTABLISHED = '1'.
TIM = SY-UZEIT.
TIM = TIM + 4.
DO.
GET TIME.
DTIM = TIM - SY-UZEIT.
IF TIM < SY-UZEIT.
EXIT.
ENDIF.
ENDDO.
EXPORT I_AM A_NAME B_NAME AB_NAME BA_NAME TO MEMORY ID 'AAA'.
SUBMIT ZPOPUPDE VIA SELECTION-SCREEN.
* No answer has come
ELSE.
WRITE: / 'Partner does not answer.'.
ENDIF.
ENDIF.
CLEAR USR_TABL.


Az eredeti forráskódok megtalálhatók Kabai Imre weboldalán is:
http://www.kabai.com/abaps/z64.htm
http://www.kabai.com/abaps/z63.htm

A SAP Labs Hungary ABAP fejlesztőjeként tevékenykedik, 2010-ig az SCM / MIP területen hegesztette az SPP nevű alkatrészkezelő alkalmazást. 2011-től a DP (Demand Planning) területbe is belekóstolt egy custom development fejlesztés keretében. Ezek mellett SAP In-Memory (HANA) területekkel is megismerkedett, egy prototípus alkalmazás illetve fejleszés alatt lévő termék kapcsán.
Szabadidejét kedvesével és fotózással tölti, szeret utazni, világot látni, új dolgokat megismerni.

További cikkek a szerzőtől