Нередко в наших проектах возникают задачи по взаимодействию SharePoint с внешними системами.
Так как коннектор поставляется для двух версий фреймворка .NET – 2.0 (3.0/3.5) и 4.0, то модуль для интеграции может функционировать в контексте SharePoint 2007/2010/2013 версии.
В самом классе укажем строковые свойства, в которые будет сохранятся информация только по заданному счету:
Далее определим список "BankData", в который будет сохранятся таблица с реквизитами банковских счетов для оплаты - объектов типа "table_INV_BANK".
Данный объект содержит свойства:
Для запроса данных из SAP напишем реализацию метода "GetDetails()".
Вначале необходимо инициализировать обращение к репозиторию в SAP - rfcDest.Repository.
После этого необходимо создать и инициализировать объект "rfc" типа "IRfcFunction", используя метод "CreateFunction()", которому нужно передать название RFC-модуля. Используя метод "SetValue()" мы передаем входной параметр (INV_CODE - номер счета) в вызываемый модуль. Сам же вызов осуществляется в методе "Invoke()".
Далее нам необходимо получить основную информацию по счету-фактуре.
Для этого создаем и инициализируем объект "mainStruct" типа "IRfcStructure", используя метод "GetStructure()", которому нужно передать имя основного объекта "счет-фактура" (INV_MAIN). После этого, используя метод "GetValue()" и названия выходных параметров объекта "счет-фактура", заполняем свойства основного класса "InvoiceData".
Чтобы получить информацию по реквизитам банковских счетов для оплаты счета-фактуры, выполним следующие действия.
Создадим и инициализируем объект "invTable" типа "IRfcTable", используя метод "GetTable()", которому нужно передать имя таблицы с реквизитами (_FULLTABLENAME). Далее, перебирая в цикле строки в таблице "invTable", заполняем список "BankData" реквизитами банковских счетов.
Для отображения информации по "счету-фактуре" и банковским реквизитам в консоли, напишем реализацию метода "Display()", который (как я надеюсь) в комментариях не нуждается.
Исходный текст класса "InvoiceData" приведен в листинге ниже.
Нам осталось написать код главной программы "Main".
Вначале задаем строку для подключения к SAP, в которой указываем необходимые значения параметров через запятую.
Далее инициализируем назначение удаленного вызова "rfcDest", используя метод "InitConnection()" из нашего класса. Для проверки доступности подключения к SAP используется метод "Ping()".
После проверки создаем новый экземпляр "invoice" нашего класса "InvoiceData".
С помощью метода "GetDetails()" получаем информацию из SAP по счету-фактуре с номером "1234" и заполняем данными наш объект "invoice".
Для вывода информации в консоль вызываем метод Display().
Коннектор предоставляет несколько специальных классов-исключений, которые перехватываются с помощью стандартного try{}catch{}.
Листинг файла с главной программой приведен ниже.
Результат работы программы изображен на рисунке ниже.
Сегодня речь пойдет о интеграции с SAP ERP.
Для интеграции приложений на базе .NET Framework 2.0(3.0/3.5) и 4.0 c SAP (посредством вызова RFC-модулей и веб-сервисов) нам предлагается использовать специальный .NET connector.
SAP предоставляет несколько версий своего коннектора:
SAP предоставляет несколько версий своего коннектора:
- NCo 3.0 32-bit (x86), .NET 2.0 (also 3.0, and/or 3.5)
- NCo 3.0 64-bit (x64), .NET 2.0 (also 3.0, and/or 3.5)
- NCo 3.0 32-bit (x86), .NET 4.0
- NCo 3.0 64-bit (x64), .NET 4.0
Так как коннектор поставляется для двух версий фреймворка .NET – 2.0 (3.0/3.5) и 4.0, то модуль для интеграции может функционировать в контексте SharePoint 2007/2010/2013 версии.
Пример разработки приложения для получения данных из SAP ERP
Начало работы с коннектором
Для начала необходимо скачать коннектор с сайта SAP Service Marketplace.
Это действие требует авторизации: вы должны быть клиентом SAP с действительным ID клиента и паролем.
Для Visual Studio 2010 нужно загрузить последнюю версию коннектора в архиве NCo307_Net20.zip
Далее нужно распаковать содержимое архива в папку на вашем компьютере. После распаковки вы обнаружите в папке установочный пакет (Windows Installer Package) с расширением msi. Вам необходимо произвести установку пакета в любую папку на вашем компьютере. Эта папка нам пригодится в дальнейших действиях.
Это действие требует авторизации: вы должны быть клиентом SAP с действительным ID клиента и паролем.
Для Visual Studio 2010 нужно загрузить последнюю версию коннектора в архиве NCo307_Net20.zip
Далее нужно распаковать содержимое архива в папку на вашем компьютере. После распаковки вы обнаружите в папке установочный пакет (Windows Installer Package) с расширением msi. Вам необходимо произвести установку пакета в любую папку на вашем компьютере. Эта папка нам пригодится в дальнейших действиях.
Подготовка проекта в Visual Studio 2010
В рамках данной статьи я продемонстрирую, на примере создания консольного приложения на языке C#, способ получения информации о заказах из SAP.
Для начала необходимо создать в Visual Studio 2010 новый проект типа "Консольное приложение Windows". Я назвал проект "InvoiceDataConsole".
Настройка подключения к SAP
В новом проекте создаем класс "SAPSystemConnect", реализующий интерфейс "IDestinationConfiguration". Этот класс необходим для управления конфигурацией и подключением к SAP.
Для использования интерфейса "IDestinationConfiguration" нам потребуется добавить референсы на библиотеки sapnco.dll и sapnco_utils.dll из папки, в которую мы производили установку пакета в предыдущем пункте.
В файле, содержащем описание класса "SAPSystemConnect" добавим namespace "SAP.Middleware.Connector". Используя класс "SAPSystemConnect", добавим реализацию методов интерфейса "IDestinationConfiguration". В листинге ниже показано, как выглядит исходный код класса "SAPSystemConnect" и реализация методов:
Хочу обратить ваше внимание на код метода "GetParameters()": сначала мы получаем набор параметров для подключения и сохраняем их в строковый массив. Далее для удобства присваиваем переменным с "говорящими" названиями соответствующие значения параметров. После этого создаем новый объект "_params" типа "RfcConfigParameters". Этот класс необходим для управления параметрами подключения к SAP.В файле, содержащем описание класса "SAPSystemConnect" добавим namespace "SAP.Middleware.Connector". Используя класс "SAPSystemConnect", добавим реализацию методов интерфейса "IDestinationConfiguration". В листинге ниже показано, как выглядит исходный код класса "SAPSystemConnect" и реализация методов:
using SAP.Middleware.Connector; namespace InvoiceDataConsole { class SAPSystemConnect : IDestinationConfiguration { public bool ChangeEventsSupported() { return false; } public event RfcDestinationManager.ConfigurationChangeHandler ConfigurationChanged; public RfcConfigParameters GetParameters(string destination) { //Получаем параметры подключения в порядке: _sysNum,_Host,_User,_Pass,_sysID,_mandt string[] pars = destination.Split(','); string _sysNum = pars[0]; string _Host = pars[1]; string _User = pars[2]; string _Pass = pars[3]; string _sysID = pars[4]; string _mandt = pars[5]; //Инициализация объекта, содержащего параметры подключения RfcConfigParameters _params = new RfcConfigParameters(); _params.Add(RfcConfigParameters.AppServerHost, _Host); _params.Add(RfcConfigParameters.SystemNumber, _sysNum); _params.Add(RfcConfigParameters.SystemID, _sysID); _params.Add(RfcConfigParameters.Client, _mandt); _params.Add(RfcConfigParameters.Language, "RU"); _params.Add(RfcConfigParameters.User, _User); _params.Add(RfcConfigParameters.Password, _Pass); _params.Add(RfcConfigParameters.PoolSize, "5"); _params.Add(RfcConfigParameters.IdleTimeout, "5000"); _params.Add(RfcConfigParameters.Name, "MYSAPCONNECT"); return _params; } } }
Листинг 1 - Исходный текст файла SAPSystemConnect.cs
Параметры подключения к SAP
- AppServerHost - IP адрес или FQDN сервера, где установлена система SAP
- SystemNumber - Это номер инстанции, фактически номер сервера приложений, который обрабатывает запрос
- SystemID - Имя системы в SAP
- Client - мандант, в котором работает пользователь(например, 800 - работа, 200,140 - разработка)
- Language - Язык локали, к которой происходит подключение
- User - Имя пользователя, использующееся для подключения
- Password - Пароль
- Poolsize - Размер пула
- IdleTimeout - Таймаут подключения (в мс)
- Name - Имя подключения (задается произвольно)
Параметры RFC-модуля
Для взаимодействия с SAP необходимо иметь представление о свойствах вызываемого RFC-модуля, таких как:
- имя вызываемого RFC-модуля
- имена входных и выходных параметров
- имена получаемых структур и таблиц, а также названия их полей
namespace InvoiceDataConsole { public static class Constants { public static class InvoiceTable { //Имя вызываемого модуля public const string Z_RFC_GET_INV = "Z_RFC_GET_INV"; //Входной параметр для вызова модуля public const string INV_CODE = "INV_CODE01"; //Имя основного объекта "счет-фактура" public const string INV_MAIN = "INV_MAIN01"; //Выходные параметры объекта "счет-фактура" public const string INV_NAME = "INV_NAME01"; public const string INV_ADDR = "INV_ADDR01"; public const string INV_INN = "INV_INN01"; public const string INV_KPP = "INV_KPP01"; //Таблица с реквизитами банковских счетов для оплаты public static class INV_BANK_LIST { //Имя таблицы public const string _FULLTABLENAME = "INV_BANK01"; //Поля таблицы public const string INV_BRNCH = "INV_BRNCH01"; public const string INV_BVTY = "INV_BVTY01"; public const string INV_BANK = "INV_BANK01"; } } } }
Листинг 2 - Исходный текст файла Constants.cs
Установка подключения
Для установки подключения к SAP необходимо использовать интерфейс "RFCDestination". Добавим в проект новый класс "Connection", в котором реализуем наш собственный метод "InitConnection()", принимающий в качестве входного параметра строку для подключения к SAP. Данный метод возвращает объект типа "RFCDestination". В листинге ниже видно, что в теле метода "InitConnection()" происходит инициализация нового экземпляра класса "SAPSystemConnect" - sapCfg. Далее этот объект используется для передачи параметров подключения в метод "GetDestination()" класса "RfcDestinationManager", который в свою очередь создает и инициализирует объект типа "RFCDestination".
using SAP.Middleware.Connector; using System; namespace InvoiceDataConsole { public class Connection { public static RfcDestination InitConnection(string connection) { try { SAPSystemConnect sapCfg = new SAPSystemConnect(); RfcDestination rfcDest = RfcDestinationManager.GetDestination(sapCfg.GetParameters(connection)); return rfcDest; } catch (Exception ex) { Console.WriteLine("Error: " + ex.Message); return null; } } } }
Листинг 3 - Исходный текст файла Connection.cs
Написание собственного класса для хранения и отображения информации по счету-фактуре
Создадим класс "InvoiceData", в котором будет реализовано получение и вывод информации по счету-фактуре.В самом классе укажем строковые свойства, в которые будет сохранятся информация только по заданному счету:
- INV_NAME - название организации
- INV_ADDR - адрес организации
- INV_INN - ИНН организации
- INV_KPP - КПП организации
Далее определим список "BankData", в который будет сохранятся таблица с реквизитами банковских счетов для оплаты - объектов типа "table_INV_BANK".
Данный объект содержит свойства:
- INV_BRNCH - номер отделения банка
- INV_BCODE - номенклатурный номер банка
- INV_BANK - наименование отделения банка
Для запроса данных из SAP напишем реализацию метода "GetDetails()".
Вначале необходимо инициализировать обращение к репозиторию в SAP - rfcDest.Repository.
После этого необходимо создать и инициализировать объект "rfc" типа "IRfcFunction", используя метод "CreateFunction()", которому нужно передать название RFC-модуля. Используя метод "SetValue()" мы передаем входной параметр (INV_CODE - номер счета) в вызываемый модуль. Сам же вызов осуществляется в методе "Invoke()".
Далее нам необходимо получить основную информацию по счету-фактуре.
Для этого создаем и инициализируем объект "mainStruct" типа "IRfcStructure", используя метод "GetStructure()", которому нужно передать имя основного объекта "счет-фактура" (INV_MAIN). После этого, используя метод "GetValue()" и названия выходных параметров объекта "счет-фактура", заполняем свойства основного класса "InvoiceData".
Чтобы получить информацию по реквизитам банковских счетов для оплаты счета-фактуры, выполним следующие действия.
Создадим и инициализируем объект "invTable" типа "IRfcTable", используя метод "GetTable()", которому нужно передать имя таблицы с реквизитами (_FULLTABLENAME). Далее, перебирая в цикле строки в таблице "invTable", заполняем список "BankData" реквизитами банковских счетов.
Для отображения информации по "счету-фактуре" и банковским реквизитам в консоли, напишем реализацию метода "Display()", который (как я надеюсь) в комментариях не нуждается.
Исходный текст класса "InvoiceData" приведен в листинге ниже.
using SAP.Middleware.Connector; using System.Collections.Generic; using NAME = InvoiceDataConsole.Constants.InvoiceTable; using System; namespace InvoiceDataConsole { public class InvoiceData { public string INV_NAME { get; set; } public string INV_ADDR { get; set; } public string INV_INN { get; set; } public string INV_KPP { get; set; } public class table_INV_BANK { public string INV_BRNCH { get; set; } public string INV_BCODE { get; set; } public string INV_BANK { get; set; } } private List <table_INV_BANK> _bankData = new List <table_INV_BANK>(); public List <table_INV_BANK> BankData { get { return _bankData; } set { _bankData = value; } } public void GetDetails(RfcDestination rfcDest, string code) { RfcRepository repo = rfcDest.Repository; IRfcFunction rfc = repo.CreateFunction(NAME.Z_RFC_GET_INV); rfc.SetValue(NAME.INV_CODE, code); rfc.Invoke(rfcDest); IRfcStructure mainStruct = rfc.GetStructure(NAME.INV_MAIN); this.INV_ADDR = mainStruct.GetValue(NAME.INV_ADDR).ToString(); this.INV_INN = mainStruct.GetValue(NAME.INV_INN).ToString(); this.INV_KPP = mainStruct.GetValue(NAME.INV_KPP).ToString(); this.INV_NAME = mainStruct.GetValue(NAME.INV_NAME).ToString(); IRfcTable invTable = rfc.GetTable(NAME.INV_BANK_LIST._FULLTABLENAME); if (invTable.RowCount > 0) { for (int cuIndex = 0; cuIndex < invTable.RowCount; cuIndex++) { table_INV_BANK data = new table_INV_BANK(); invTable.CurrentIndex = cuIndex; data.INV_BANK = invTable.CurrentRow.GetValue(NAME.INV_BANK_LIST.INV_BANK).ToString(); data.INV_BRNCH = invTable.CurrentRow.GetValue(NAME.INV_BANK_LIST.INV_BRNCH).ToString(); data.INV_BCODE = invTable.CurrentRow.GetValue(NAME.INV_BANK_LIST.INV_BVTY).ToString(); this.BankData.Add(data); } } } public void Display() { Console.WriteLine(); Console.WriteLine(); Console.WriteLine("Display invoice data"); Console.WriteLine("INV_NAME: " + this.INV_NAME); Console.WriteLine("INV_ADDR: " + this.INV_ADDR); Console.WriteLine("INV_INN: " + this.INV_INN); Console.WriteLine("INV_KPP: " + this.INV_KPP); Console.WriteLine(); Console.WriteLine("Display banking details"); foreach (var item in this.BankData) { Console.WriteLine("INV_BANK: " + item.INV_BANK); Console.WriteLine("INV_BRNCH: " + item.INV_BRNCH); Console.WriteLine("INV_BCODE: " + item.INV_BCODE); Console.WriteLine(); } } } }
Листинг 4 - Исходный текст файла InvoiceData.cs
Собираем все вместе
Структура итогового проекта изображена на рисунке ниже.Нам осталось написать код главной программы "Main".
Вначале задаем строку для подключения к SAP, в которой указываем необходимые значения параметров через запятую.
Далее инициализируем назначение удаленного вызова "rfcDest", используя метод "InitConnection()" из нашего класса. Для проверки доступности подключения к SAP используется метод "Ping()".
После проверки создаем новый экземпляр "invoice" нашего класса "InvoiceData".
С помощью метода "GetDetails()" получаем информацию из SAP по счету-фактуре с номером "1234" и заполняем данными наш объект "invoice".
Для вывода информации в консоль вызываем метод Display().
Коннектор предоставляет несколько специальных классов-исключений, которые перехватываются с помощью стандартного try{}catch{}.
Листинг файла с главной программой приведен ниже.
using System; using System.Collections.Generic; using System.Linq; using System.Text; using SAP.Middleware.Connector; using SAP.Middleware; namespace InvoiceDataConsole { class Program { static void Main(string[] args) { //Задаем строку подключения с параметрами: sysNum,Host,User,Pass,sysID,mandt string ConnectionString = @"10,http://saphost,User,Password,TST,800"; //Инициализация подключения RfcDestination rfcDest = Connection.InitConnection(ConnectionString); //Открываем скоуп для удаленного вызова RfcSessionManager.BeginContext(rfcDest); try { //Проверка подключения к SAP Console.Write("Testing connection to SAP: "); rfcDest.Ping(); Console.Write("CONNECTION_SUCCESSFUL!"); InvoiceData invoice = new InvoiceData(); invoice.GetDetails(rfcDest, "1234"); invoice.Display(); } catch (RfcCommunicationException ex) { //Ошибка подключения ShowError(ex); } catch (RfcLogonException ex) { //Ошибка аутентификации учетной записи, под которой производится подключение ShowError(ex); } catch (RfcAbapRuntimeException ex) { //Ошибка выполнения ABAP ShowError(ex); } catch (RfcAbapBaseException ex) { //Ошибка ABAP ShowError(ex); } catch (Exception ex) { //Общая ошибка RfcSessionManager.EndContext(rfcDest); ShowError(ex); } finally { //Закрываем скоуп RfcSessionManager.EndContext(rfcDest); Console.WriteLine("Press key..."); Console.ReadKey(); } } private static void ShowError(Exception ex) { Console.WriteLine("Error: " + ex.Message); } } }
Листинг 5 - Исходный текст файла Program.cs
Результат работы программы изображен на рисунке ниже.
Подведем итоги
Как вы успели заметить, на второй взгляд, во взаимодействии с SAP через коннектор нет ничего архисложного.
Настройка и инициализация подключения, описание классов для получения и обработки данных из нужных структур в SAP - все это доступно благодаря .NET коннектору!
Надеюсь, что этот пост поможет вам начать работу с коннектором.
Если у вас появятся предложения по улучшению данного материала, то оставьте свой комментарий ниже.
Если у вас появятся предложения по улучшению данного материала, то оставьте свой комментарий ниже.
Ссылки по теме
1. Используемые в статье материалы
- How-To Use SAP Nco 3 Connector | .Net 4 | Visual Studio 2010
- Call RFC enable function module from asp.net application
- Connecting to SAP and retrieving data using version 3.0 of the SAP .NET connect
Отличная статья, огромное спасибо!
ОтветитьУдалить