cancel
Showing results for 
Search instead for 
Did you mean: 

Updating Infotype 0105 "Communication" with SAPNWRFC and PERL (long !!)

Former Member
0 Kudos

When I read the SAP-Press Book "mySAP HR: Technical Principles and Programming"

(actually it was the german edition "Technische Grundlagen und Programmierung")

I came across Chapter 9.1.3 "Using BAPIs", in which some sample code is provided

for updating the email-adress in infotype 0105 "communication".

I just thought: "OK, that could be easily (and better !) done with PERL and SAPNWRFC".

My PERL-script should do the following:

1) Read subtypes 0001 and 0010 from IT 0105 via RFC

2) Compare that data against our LDAP-Server

3) call the approbiate BAPIs for updating IT 0105 via RFC

OK, here's the ABAP-code which accomplishes task #1:

[code]

  • Z_EMAIL_TAB is a customer-defined structure with 3 components:

  • component component-type

  • MY_PERNR PERNR_D

  • MY_NICKN SYSID

  • MY_EMAIL COMM_ID_LONG

FUNCTION z_read_email.

*"----


""Lokale Schnittstelle:

*" IMPORTING

*" VALUE(MY_DATE) TYPE ENDDA OPTIONAL

*" TABLES

*" Z_EMAIL STRUCTURE Z_EMAIL_TAB

*"----


DATA: sql_date TYPE begda,

sql_mandt type mandt.

DATA: BEGIN OF wa_ldap_out,

pernr TYPE pernr_d,

nickn TYPE sysid,

email TYPE comm_id_long,

END OF wa_ldap_out.

DATA: exc_ref TYPE REF TO cx_sy_native_sql_error,

error_text TYPE string.

IF my_date IS INITIAL.

MOVE sy-datum TO sql_date.

ELSE.

MOVE date TO sql_date.

ENDIF.

  • we use native SQL (Oracle), so we have to specify the mandant

  • exclude-values for PERSK refer to pensionists etc

move sy-mandt to sql_mandt.

EXEC SQL.

open dbcur for

SELECT DISTINCT

pa0001.pernr,

pa0105_0001.usrid,

pa0105_0010.USRID_LONG

FROM pa0000 pa0000,

pa0001 pa0001,

pa0105 pa0105_0001,

pa0105 pa0105_0010

WHERE

pa0000.pernr = pa0001.pernr and

pa0000.begda <= :sql_date AND

pa0000.endda >= :sql_date AND

pa0001.begda <= :sql_date AND

pa0001.endda >= :sql_date AND

pa0001.persk NOT IN ('12' ,'13' ,'17' ,'18') AND

pa0000.stat2 = '3' and

(pa0001.mandt = pa0105_0001.mandt() and pa0001.pernr = pa0105_0001.pernr() and pa0105_0001.usrty() = '0001' and pa0105_0001.begda() <= :sql_date and pa0105_0001.endda(+) >= :sql_date) and

(pa0001.mandt = pa0105_0010.mandt() and pa0001.pernr = pa0105_0010.pernr() and pa0105_0010.usrty() = '0010' and pa0105_0010.begda() <= :sql_date and pa0105_0010.endda(+) >= :sql_date) and

pa0000.mandt = pa0001.mandt and

pa0000.mandt = :sql_mandt

ENDEXEC.

DO.

EXEC SQL.

FETCH NEXT dbcur into :wa_ldap_out

ENDEXEC.

IF sy-subrc <> 0.

EXIT.

ELSE.

APPEND wa_ldap_out to z_email.

ENDIF.

ENDDO.

EXEC SQL.

close dbcur

ENDEXEC.

ENDFUNCTION.

[/code]

Using Native-SQL (we have an Oracle-Backend) saves us from looping through IT0105 twice.

(I don't like ABAP's Open-SQL, it's too limited)

Now we have a nice little table with all our employees pernr, userid and email-adress.

Let's stay on the ABAP-side and have a look at the update-function (task #3):

[code]

FUNCTION z_upd_smtp .

*"----


""Lokale Schnittstelle:

*" IMPORTING

*" VALUE(MY_PERNR) TYPE PERNR_D

*" VALUE(MY_EMAIL) TYPE AD_SMTPADR

*" VALUE(MY_DATE) TYPE BEGDA OPTIONAL

*" TABLES

*" BAPIRETURN STRUCTURE BAPIRETURN1

*"----


DATA: wa_bapireturn TYPE bapireturn1.

IF my_date IS INITIAL.

MOVE sy-datum TO my_date.

ENDIF.

CALL FUNCTION 'BAPI_EMPLOYEET_ENQUEUE'

EXPORTING

number = my_pernr

validitybegin = my_date

IMPORTING

return = wa_bapireturn.

IF wa_bapireturn-type NE 'E'.

CLEAR wa_bapireturn.

CALL FUNCTION 'BAPI_EMPLCOMM_CREATE'

EXPORTING

employeenumber = my_pernr

subtype = '0010'

validitybegin = my_date

validityend = '99991231'

communicationid = my_email

  • NOCOMMIT =

IMPORTING

return = wa_bapireturn

  • EMPLOYEENUMBER =

  • SUBTYPE =

  • OBJECTID =

  • LOCKINDICATOR =

  • VALIDITYBEGIN =

  • VALIDITYEND =

  • RECORDNUMBER =

.

APPEND wa_bapireturn TO bapireturn.

CALL FUNCTION 'BAPI_EMPLOYEET_DEQUEUE'

EXPORTING

number = my_persnr

validitybegin = my_datum

IMPORTING

return = wa_bapireturn.

APPEND wa_bapireturn TO bapireturn.

ELSE.

APPEND wa_bapireturn TO bapireturn.

ENDIF.

ENDFUNCTION.

[/code]

And finally the PERL-Script (task #2):

[code]

  1. ##### Connect to LDAP-server #################################################

use Net::LDAP;

use Net::LDAP::Control;

use Net::LDAP::Constant qw(LDAP_CONTROL_PAGED);

$pagec = Net::LDAP::Control->new( LDAP_CONTROL_PAGED,

size => 1000);

  1. --- replace with your company-specific values ------------------------------ #

$ldap = Net::LDAP->new( 'your-ldap-server' ) or die "$@";

$mesg = $ldap->bind( 'CN=your-ldap-user,CN=aaaa,DC=bbbb,DC=dd,DC=eeeeeee,DC=fff',

password => 'your-password'

);

use SAPNWRFC;

  1. --- Connection to SAP ----------------------------------------------------- #

SAPNW::Rfc->load_config("your-config-file");

$sap_conn = SAPNW::Rfc->rfc_connect;

  1. --- SAP RFCs --------------------------------------------------------------- #

SAP_RFCs();

  1. --- read all Email-adresses from IT0105 ------------------------------------ #

$rd_handle_eml = $rd_eml->create_function_call;

$rd_handle_eml->invoke();

foreach $row_hashref_eml (@{$rd_handle_eml->Z_EMAIL}) {

$MY_PERNR = $row_hashref_eml->{MY_PERNR};

$MY_NICKN = $row_hashref_eml->;

$MY_EMAIL = $row_hashref_eml->;

$MY_NICKN =~ s/ //g;

$MY_EMAIL =~ s/ //g;

if ($MY_NICKN ne '') {

$strMail_LDAP = nick2email(lc($MY_NICKN));

if (lc($MY_EMAIL) ne lc($strMail_LDAP) && $strMail_LDAP ne '') {

updIT0105("$MY_PERNR","$strMail_LDAP");

print "SUCCESS = $i_uit_success, $MY_PERNR $strMail_LDAP\n";

}

}

else {

  1. do some error-processing here

}

$sap_conn->disconnect();

exit;

  1. ############################################################################ #

sub SAP_RFCs {

  1. --- Read E-Mail-Adress from IT0105 ----------------------------------------- #

$rd_eml = $sap_conn->function_lookup("Z_READ_EMAIL");

  1. --- Update E-Mail-Adress in IT0105 ----------------------------------------- #

$rd_uit = $sap_conn->function_lookup("Z_UPD_SMTP");

}

  1. ########################################################################### #

sub nick2email {

$strNickn = $_[0];

$strEMail = '';

  1. --- our userid is stored in LDAP-item "mailnickname", just change filter to your needs #

$filter = qq {

(& (mailnickname=$strNickn)

(givenName=*)

(| (objectCategory=person)

(objectClass=person)

)

)

};

while (defined ($search = $ldap->search(

base => "OU=your-base-OU,DC=bbbb,DC=dd,DC=eeeeeee,DC=fff",

filter => $filter,

attrs => ['mailNickname','mail','whenChanged'],

control => [ $pagec ]

) ) ) {

foreach $entry ($search->entries) {

$strEMail = $entry->get_value('mail') ;

}

($resp) = $search->control( LDAP_CONTROL_PAGED );

last unless ref $resp && $pagec->cookie($resp->cookie);

}

return $strEMail;

};

  1. ########################################################################### #

sub updIT0105 {

$rd_handle_uit = $rd_uit->create_function_call;

$rd_handle_uit->MY_PERNR($_[0]);

$rd_handle_uit->MY_EMAIL($_[1]);

$rd_handle_uit->invoke();

$i_uit_success = 1;

foreach $row_hashref_uit (@{$rd_handle_uit->BAPIRETURN}) {

if ($row_hashref_uit->{TYPE} ne 'S' && $row_hashref_uit-> ne ' ') {

$i_uit_success = 0;

}

}

};

[/code]

I run this script every Friday on a virtual Windows XP machine (VMWare) scheduled with the AT-Command

and it works really fine, enjoy !!!

P.S.: I hope there aren't any typos in the code, but please check

P.P.S: Thanks again to Piers for SAPNWRC, fantastic.

Accepted Solutions (0)

Answers (1)

Answers (1)

Former Member
0 Kudos

Hi,

I am very interested in your solution. Can you send me the scripts?

Greeting Jan