Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C#

Search User in SAP and LDAP Databases or Create User in SAP

4.81/5 (8 votes)
14 May 2013CPOL4 min read 51.8K   1.6K  
Use Bapi in C#

Introduction

SAP systems are usually installed in large corporate offices. Sometimes we can make a mistake and a user can have two or more logins. How can we find these duplicates when the database is large? If you use the CUA, and CUA is not integrated with LDAP, this program is for you. I have created this program to help myself in my work.

First version, published here, was capable only for search, create users, assign only one role. Now I added manipulation with user's roles.

Using the code

There do exist some prerequisites which need to be fulfilled before you are to install this program:

  • Need to install .NET 3.0, usually this is already installed in PCs, begin with WinXP.
  • Need to install SAPGUI7.xx (this is the SAP's presentation service for SAP's backend systems).

In the program, use the following BAPI functions:

  • "BAPI_USER_GETLIST"
  • "BAPI_USER_GET_DETAIL"
  • "BAPI_USER_CREATE1"
  • "BAPI_USER_CHANGE"
  • "BAPI_USER_UNLOCK"
  • "BAPI_USER_LOCK"
  • "RFC_READ_TABLE"

Import/Export parameters to the BAPI functions can be obtained using the transaction BAPI in SAP or exploring the function module, in sapgui type SE37 -> type function module name. Here is an example of how can you lock the user:

C++
// input: user Login
public bool sapLockUser(string sUserLogin)
{
    bool bOk = true;
    if (sUserLogin == "") return false;
    SAPFunctionsOCX.Parameter pUserName = 
      (SAPFunctionsOCX.Parameter)m_iBAPI_USER_LOCK.get_Exports("USERNAME");
    ((SAPFunctionsOCX.Parameter)pUserName).Value = sUserLogin;
    bOk = m_iBAPI_USER_LOCK.Call();
    if (bOk)
    {
        SAPTableFactoryCtrl.Tables tTables = 
    (SAPTableFactoryCtrl.Tables)m_iBAPI_USER_LOCK.Tables;
        showReturn(ref tTables);
    }
    return bOk;
}

If you get a search in database, you need to make a range area for searching. In LDAP we use construction Reverse Polish Notation (from right to left). You can add your own constructions in the search statement.

C++
(&(cn=?)(objectCategory=person)(mail=*)(userAccountControl=512))

In SAP's function modules we use another technique where you need to fill the SELECTION_EXP structure. You can find how to fill it in the help in transaction BAPI, or in the SAP's document: SAP Identity Management APIs.

If the import parameter in function module is a table, as in the case of SELECTION_EXP, you need to use a wrapper function, because of the marshalling error in C# interop and SAP's COM object. There are many ways to workaround this, as you can see in the blog of Lim Bio Liong. Here the wrapper function is used.

C++
SAPTableFactoryCtrl.Table oSELECTION_EXP = 
    (SAPTableFactoryCtrl.Table)tTables["SELECTION_EXP"];
int icntCol = oSELECTION_EXP.ColumnCount;
int icntRow = oSELECTION_EXP.RowCount;
icntRow = oSELECTION_EXP.RowCount;
sSapLogin = null;
try
{
  oRowSetVal oRowSet = new oRowSetVal();
  object oRow = ((SAPTableFactoryCtrl.Rows)oSELECTION_EXP.Rows).Add(null);
  oRowSet.SetVal(ref oRow, "LOGOP", "AND");
  oRowSet.SetVal(ref oRow, "ARITY", "1");
  oRow = ((SAPTableFactoryCtrl.Rows)oSELECTION_EXP.Rows).Add(null);
  oRowSet.SetVal(ref oRow, "PARAMETER", "USERNAME");
  oRowSet.SetVal(ref oRow, "OPTION", "CP");
  oRowSet.SetVal(ref oRow, "LOW", sapTemplateLogin.ToUpper());
}

In the wrapper DLL I add a new function: SetDateTime.

Now the idl description looks like:

C++
interface IoRowSetVal : IDispatch{
    [id(1), helpstring("method SetVal")] 
      HRESULT SetVal([in,out] VARIANT* pvRow, [in] BSTR vsColumn, [in] BSTR vsValue);
    [id(2), helpstring("method SetDateTime")] 
      HRESULT SetDateTime([in,out] VARIANT* pvRow, [in] BSTR vsColumn, [in] VARIANT vVal);
};

Structure of the data in the program

First of all, I have to tell that most program possibilities are determined by the data structure. The structure of the data in this program looks like:

Image 1

Around this structure the user interface is created to solve everyday tasks.

How this work from user's view

First, you need to fill the config tab with initial parameters as here:

Image 2

First time this tab hidden. To get it you need to unhide using the system menu:

Image 3

When you fill the config tab, you can work with program from face tab:

Image 4

The searching words can be typed in 'Last First Name' or in 'SAP User Login' fields. If logins are found in SAP, they can be viewed in the Temporary ListBox. If checkbox 'with roles' is selected, then all roles assigned to the user are loaded too. Logins may be memorized in Memory list Box; because of Temporary list Box cleared in each search process. Press 'Enter' to start searching: it is the same as press 'Search' button. To search Company, you can type part company name in the Company ComboBox and press 'Enter' in the keyboard.

I must tell that all manipulation with users and roles in memory and only two buttons change the content of the user in SAP: yellow 'Change/Create' on face tab and yellow 'Save User in CUA' in tab Roles, and checkBox 'Blocked' change the status user's login: blocked/not blocked!

When you find logins, you can switch to tabRoles tab to view roles or compare user roles:

Image 5

Roles can be deleted, added, or changed here (saved in SAP only when pressing button 'Save User in CUA'!)

Some times I need to compare roles with different users:

Image 6

If roles are copied between users, you can save the selected user with a new set of roles.

I hope that somebody finds this utility useful.

History

  • 20.11.2011: First version published.
  • 04.05.2012: 1.1.8 version published.
  • 17.05.2012: 1.1.10 ver. (minor changes).
  • 24.05.2012: 1.1.11 (minor correction in compare user's roles tab).
  • 07.09.2012: 1.1.12 (Correct: Roles UpperCase, Ldap Filter not saved, compare two logins in one click).
  • 15.05.2013: 1.1.13 (for x64 machines add target x86 in compilation, change mapping LDAP<->SAP telephone and mobile) 

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)