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.
– 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.*/ 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 é: 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;
|
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