Utilizando a DLL de acesso ao SAP em feita em .Net 2003 (Framework 1.1 ) no Visual Studio 2005 (Framework 2.0)

Após criar nossa DLL RFC_READ_TABLE ( já  publicado no blog),  vamos aprender a usá-la.

Abra o Visual Studio 2005,  e inicie uma nova aplicação web.

– Adicione uma referência à DLL RFC_READ_TABLE, criada anteriormente.

– Crie uma classe chamada SAP_util, que será o nosso container de funcionalidades relacionadas ao SAP.

– Seu Solution Explorer deve estar parecido com este

clip_image002[5]
– Nesta classe teremos 3 métodos: Um construtor SAP_util, buscarListaUsuarios e buscarSAP.

– Além disso, teremos algumas declarações públicas:

protected RFC_READ_TABLE.TAB512Table tabData;

protected RFC_READ_TABLE.TAB512 Data;

protected RFC_READ_TABLE.RFC_DB_FLDTable tabFields;

protected RFC_READ_TABLE.RFC_DB_FLD Fields;

protected RFC_READ_TABLE.RFC_DB_OPTTable tabOptions;

protected RFC_READ_TABLE.RFC_DB_OPT Options;

protected RFC_READ_TABLE.RFC_READ_TABLE sap;

protected string strConnSAP;

Todas fazendo referência à nossa DLL, exceto a strConnSAP, que guardará nossa string de conexão.


O Construtor da classe.

Cada instância da classe iniciará a conexão com o SAP, mantendo-a fechada, porém, pronta para ser usada.

Uma dica é criar todos os parâmetros de conexão no Web Config da Aplicação. Isso ajuda na manutenção e na publicação da aplicação, no que diz respeito à troca de apontamento entre servidores diferentes, por exemplos, ambientes de QA, DEV e PRD.

public SAP_util()

{

try

{

//string conexão sap

strConnSAP =

" ASHOST=" + ConfigurationManager.AppSettings["destination1. AppServerHost"] .ToString()

+ " SYSNR=" + Convert.ToInt16 ( ConfigurationManager.AppSettings["destination1. SystemNumber"]).ToString()

+ " CLIENT= " + Convert.ToInt16(ConfigurationManager.AppSettings["destination1. Client"]).ToString()

+ " USER=" + ConfigurationManager.AppSettings["destination1. Username"].ToString()

+ " PASSWD=" + ConfigurationManager.AppSettings["destination1. Password"].ToString();

//conecta no sap

sap = new RFC_READ_TABLE.RFC_READ_TABLE(strConnSAP);

}

catch{}

}

Buscar informações no SAP:

Este método, não estático, em sua própria instância, alimenta uma tabela temporária tabData com os resultados obtidos no SAP.

Ele recebe o nome da tabela do SAP que se deseja consultar e dois vetores de string, contendo a lista de Campos que se deseja retornar e a lista de Filtros a serem aplicados (cláusula Where).

Obs. Esta especificação é diretamente relacionada à rfc RFC_READ_TABLE mapeada em nossa DLL.

Para outras transações é necessário construir a DLL de mapeamento da TRANSAÇÃO SAP, e entender como ela espera seus argumentos.

Entretanto, a lógica a ser seguida será a mesma, ou seja, o SAP preenche tabelas em memória, passadas por referência pelo dotNet e as preenche. Em seguida o dotNet lê o conteúdo dessas tabelas e então o processa.

private DataView buscarSAP(string nomeTabela, string[] pCampos, string[] pFiltros)

{

/* INICIALIZANDO AS VARIÁVEIS */

tabFields = null;

tabOptions = null;

tabData = null;

tabFields = new RFC_READ_TABLE.RFC_DB_FLDTable();

tabOptions = new RFC_READ_TABLE.RFC_DB_OPTTable();

tabData = new RFC_READ_TABLE.TAB512Table();

/* MONTANDO NA tabFields AS COLUNAS A SEREM RETORNADAS PELO SAP */

foreach (string campo in pCampos)

{

Fields = null;

Fields = new RFC_READ_TABLE.RFC_DB_FLD();

Fields.Fieldname = campo;

tabFields.Add(Fields);

}

/*MONTANDO NA tabOptions OS FILTROS A SEREM APLICADOS NA CONSULTA*/

foreach (string filtro in pFiltros)

{

Options = null;

Options = new RFC_READ_TABLE.RFC_DB_OPT();

Options.Text = filtro;

tabOptions.Add(Options);

}

/*REPARE NESTE MOMENTO, QUE O SAP LÊ DUAS TABELAS: FIELDS E OPTIONS, PASSADAS POR REFERÊNCIA E PREENCHE UMA TERCEIRA TABELA, TABDATA, TAMBÉM PASSADA POR REFERÊNCIA, PORÉM, OS OUTROS PARÂMETROS COMO DELIMITADOR E NOME DA TABELA, SÃO PASSADOS POR VALOR E NÃO POR REFERÊNCIA.

ESTA LÓGICA PERMANECE EM QUALQUER RFC QUE SE INVOQUE DO SAP, PORÉM, CADA RFC EXIGIRÁ PARÂMETROS DIFERENTES E PASSAGENS DE FORMA DIFERENTE.*/

/* CHAMADA DA FUNÇÃO SAP PROPRIAMENTE DITA, PASSANDO TODOS OS PARÂMETROS */

sap.Rfc_Read_Table(";", "", nomeTabela, 0, 0, ref tabData, ref tabFields, ref tabOptions);

/* TRATANDO RETORNO DO SAP */

DataView tblRetorno = new DataView(tabData.ToADODataTable());

return tblRetorno;

}

Buscando uma lista de funcionários no módulo de HR do SAP:

public DataTable buscarListaUsuarios()

{

//Variáveis utilizadas na consulta ao SAP

string[] sCampos;

string[] sFiltro;

string tabela;

string strRetorno; //string de retorno do sap

char[] delim = {‘;’}; //delimitador de colunas

//Montando a estrutura da tabela de retorno, com os campos que queremos mostrar na tela

DataTable tblRetorno = new DataTable("funcionarios");

tblRetorno.Columns.Add("PERNR");

tblRetorno.Columns.Add("PERSG");

tblRetorno.Columns.Add("PERSK");

tblRetorno.Columns.Add("BTRTL");

tblRetorno.Columns.Add("SNAME");

tblRetorno.Columns.Add("WERKS");

//***

//Parâmetros da consulta ao SAP

//Campos a serem retornados na consulta

sCampos = new string[] { "PERNR", "PERSG", "PERSK", "BTRTL", "SNAME", "WERKS" };

//Cláusula WHERE da consulta, com uma lógica qualquer

sFiltro = new string[] { " WERKS EQ ‘EWBO’ ", " AND ENDDA EQ ‘99991231’ " };

tabela = "PA0001"; //Nome da tabela do SAP que será consultada

DataView tblPA0001 = buscarSAP(tabela, sCampos, sFiltro); //Ida ao SAP

/*NESTE MOMENTO, UMA TABELA É RETORNADA DO SAP, COMO MOSTRA A FIGURA. (Os dados foram borrados para não exibir os nomes das pessoas).

Repare que a tabela possui apenas uma coluna “WA” e que cada as ascolunas estão separadas pelo delimitador que nós definimos, ou seja, o ponto e vírgula (;).

Parece um arquivo CSV do Excel.

Então precisaremos tratar essas linhas e transforma-las em tabela de forma que possamos trabalhar melhor.*/

clip_image002[7]

if (tblPA0001.Count > 0) //verifica o retorno do SAP, se vieram registros

{

foreach (DataRowView dr in tblPA0001) //Para cada linha da tab. restornada do SAP

{

strRetorno = dr["Wa"].ToString(); //Equivale a 1 linha da tabela de retorno do SAP.

//Cada registro tem suas "COLUNAS" delimitadas com o caracter dilimitador setado na variável acima

//É como se fosse um arquivo csv do Excel. Cada linha

string[] auxPA0001 = strRetorno.Split(delim); //splito a linha, com o delimitador

//Após a string ser splitada um vetor de strings é retornado

//Então é só relacionar cada posição do vetor com sua respectiva tabela

DataRow row = tblRetorno.NewRow();

row["PERNR"] = auxPA0001[0].TrimStart().TrimEnd(); //PERNR

row["PERSG"] = auxPA0001[1].TrimStart().TrimEnd(); //WERKS

row["PERSK"] = auxPA0001[2].TrimStart().TrimEnd(); //BTRTL

row["BTRTL"] = auxPA0001[3].TrimStart().TrimEnd(); //KOSTL

row["SNAME"] = auxPA0001[4].TrimStart().TrimEnd(); //SNAME

row["WERKS"] = auxPA0001[5].TrimStart().TrimEnd(); //ENDDA

//Adiciona as linhas à tabela de retorno

tblRetorno.Rows.Add(row);

}

}

//***

//Libera o objeto SAP da memória

sap.Dispose();

sap = null;

//Retorna uma tabela com os resultados

return tblRetorno;

}

A aplicação web que exibirá o resultado.

Na página default.aspx, adicione um GridView e no Load da página, acrescente o seguinte código.

protected void Page_Load(object sender, EventArgs e)

{

try

{

SAP_util sap = new SAP_util(); //Instância de nossa classe SAP_util

GridView1.DataSource = sap.buscarListaUsuarios(); //Invoca o método que retorna a lista de funcionarios do SAP

GridView1.DataBind(); //Preenchendo o grid

}

catch(Exception ex)

{

throw new Exception(ex.Message);

}

}

O resultado esperado é:

clip_image004

Espero que essas dicas ajudem a todos.

Boa Sorte!

Michel Viana

.Net/BI Consulting – SAP Integrator Specilist

Código completo da classe SAP_util

using System;

using System.Data;

using System.Configuration;

using System.Web;

using System.Web.Security;

using System.Web.UI;

using System.Web.UI.WebControls;

using System.Web.UI.WebControls.WebParts;

using System.Web.UI.HtmlControls;

/// <summary>

/// utiliza a DLL que conecta no SAP e executa a rfc standard rfc_read_table

/// esta rfc lê uma tabela qq no sap e retorna o resultado query, de acordo com os filtros informados

/// </summary>

public class SAP_util

{

protected RFC_READ_TABLE.TAB512Table tabData;

protected RFC_READ_TABLE.TAB512 Data;

protected RFC_READ_TABLE.RFC_DB_FLDTable tabFields;

protected RFC_READ_TABLE.RFC_DB_FLD Fields;

protected RFC_READ_TABLE.RFC_DB_OPTTable tabOptions;

protected RFC_READ_TABLE.RFC_DB_OPT Options;

protected RFC_READ_TABLE.RFC_READ_TABLE sap;

protected string strConnSAP;

public SAP_util()

{

try

{

//string conexxão sap

strConnSAP = " ASHOST=" + ConfigurationManager.AppSettings["destination1.AppServerHost"].ToString() +

" SYSNR=" + Convert.ToInt16(ConfigurationManager.AppSettings["destination1.SystemNumber"]).ToString() +

" CLIENT= " + Convert.ToInt16(ConfigurationManager.AppSettings["destination1.Client"]).ToString() +

" USER=" + ConfigurationManager.AppSettings["destination1.Username"].ToString() +

" PASSWD=" + ConfigurationManager.AppSettings["destination1.Password"].ToString();

//conecta no sap

sap = new RFC_READ_TABLE.RFC_READ_TABLE(strConnSAP);

}

catch

{

}

}

public DataTable buscarListaUsuarios()

{

//Variáveis utilizadas na consulta ao SAP

string[] sCampos;

string[] sFiltro;

string tabela;

string strRetorno; //string de retorno do sap

char[] delim = {‘;’}; //delimitador de colunas

//Montando a estrutura da tabela de retorno

DataTable tblRetorno = new DataTable("funcionarios");

tblRetorno.Columns.Add("PERNR");

tblRetorno.Columns.Add("PERSG");

tblRetorno.Columns.Add("PERSK");

tblRetorno.Columns.Add("BTRTL");

tblRetorno.Columns.Add("SNAME");

tblRetorno.Columns.Add("WERKS");

//***

//Parâmetros da consulta ao SAP

sCampos = new string[] { "PERNR", "PERSG", "PERSK", "BTRTL", "SNAME", "WERKS" }; //Campos a serem retornados na consulta

sFiltro = new string[] { " WERKS EQ ‘EWBO’ ", " AND ENDDA EQ ‘99991231’ " }; //Cláusula WHERE da consulta

tabela = "PA0001"; //Nome da tabela do SAP que será consultada

DataView tblPA0001 = buscarSAP(tabela, sCampos, sFiltro); //Ida ao SAP propriamente dita

if (tblPA0001.Count > 0) //verifica o retorno do SAP, se vieram registros

{

foreach (DataRowView dr in tblPA0001) //Para cada registro restornado do SAP

{

strRetorno = dr["Wa"].ToString(); //Equivale a 1 registro da tabela de retorno do SaP.

//Cada registro tem suas "COLUNAS" delimitadas com o caracter dilimitador setado na variável acima

//É como se fosse um arquivo csv do Excel. Cada linha

string[] auxPA0001 = strRetorno.Split(delim);

//Após a string ser splitada um vetor de strings é retornado

//Então é só relacionar cada posição do vetor com sua respectiva tabela

DataRow row = tblRetorno.NewRow();

row["PERNR"] = auxPA0001[0].TrimStart().TrimEnd(); //PERNR

row["PERSG"] = auxPA0001[1].TrimStart().TrimEnd(); //WERKS

row["PERSK"] = auxPA0001[2].TrimStart().TrimEnd(); //BTRTL

row["BTRTL"] = auxPA0001[3].TrimStart().TrimEnd(); //KOSTL

row["SNAME"] = auxPA0001[4].TrimStart().TrimEnd(); //SNAME

row["WERKS"] = auxPA0001[5].TrimStart().TrimEnd(); //ENDDA

//Adiciona as linhas à tabela de retorno

tblRetorno.Rows.Add(row);

}

}

//***

sap.Dispose(); //Libera o objeto SAP da memória

sap = null;

return tblRetorno;

}

private DataView buscarSAP(string nomeTabela, string[] pCampos, string[] pFiltros)

{

/* DECLARAÇÕES */

tabFields = null;

tabOptions = null;

tabData = null;

tabFields = new RFC_READ_TABLE.RFC_DB_FLDTable();

tabOptions = new RFC_READ_TABLE.RFC_DB_OPTTable();

tabData = new RFC_READ_TABLE.TAB512Table();

/* COLUNAS A SEREM RETORNADAS DO SAP */

foreach (string campo in pCampos)

{

Fields = null;

Fields = new RFC_READ_TABLE.RFC_DB_FLD();

Fields.Fieldname = campo;

tabFields.Add(Fields);

}

/*FILTROS*/

foreach (string filtro in pFiltros)

{

Options = null;

Options = new RFC_READ_TABLE.RFC_DB_OPT();

Options.Text = filtro;

tabOptions.Add(Options);

}

/* CHAMADA DA FUNÇÃO SAP */

sap.Rfc_Read_Table(";", "", nomeTabela, 0, 0, ref tabData, ref tabFields, ref tabOptions);

/* TRATANDO RETORNO DO SAP */

DataView tblRetorno = new DataView(tabData.ToADODataTable());

return tblRetorno;

2 comentários
  1. Luiz disse:

    Cara, Parabéns. esse Artigo é uma valiosa fonte para quem está iniciando!

    um abraço.
    Luiz

    • Bom dia,

      Agradeçemos o interesse pelo Blog.

      Por favor divulgue para os amigos.

      Sds,
      AbapBrasil

Deixe um comentário