c# 用SapNwRfc调用sap内置bom函数用TreeView把bom展示出来
一个需求,winform根据料号,查询sap 的bom,然后用控件调用sap内置bom函数,根据料号查询bom用TreeView把bom展示出来树形控件TreeView展示出来,TreeView的好处是父级子级直观明了。
sap关于bom 的tcode 主要是cs11 ,cs12,cs13。cs12可以显示多级bom,查询出来是这样的:
这种表现方式,不是很直观。
sap内置的有一个bom 函数,CS_BOM_EXPL_MAT_V2 可以逐级BOM 展开。但是,CS_BOM_EXPL_MAT_V2是一个常规函数,并不是一个远程函数,c#不能调用。
我自己建一个远程函数,然后在这个远程函数里面去调用CS_BOM_EXPL_MAT_V2。
新建一个远程函数,处理类型设置 成远程启用的模块,
新建导入参数:
参数名称,关联类型参照CS_BOM_EXPL_MAT_V2,有三个参数是必须的,有效起始日期 DATUV,物料编号 MTNRV,工厂 WERKS。
导出和表 这里设置 参照 CS_BOM_EXPL_MAT_V2
然后开始写函数:代码如下
FUNCTION zfm_******bom001. *"---------------------------------------------------------------------- *"*"本地接口: *" IMPORTING *" VALUE(DATUV) LIKE STKO-DATUV OPTIONAL *" VALUE(MTNRV) LIKE MARA-MATNR OPTIONAL *" VALUE(STLAN) LIKE STZU-STLAN OPTIONAL *" VALUE(STLAL) LIKE STKO-STLAL OPTIONAL *" VALUE(MKTLS) LIKE CSDATA-XFELD OPTIONAL *" VALUE(MEHRS) LIKE CSDATA-XFELD OPTIONAL *" VALUE(RNDKZ) LIKE CSDATA-XFELD OPTIONAL *" VALUE(WERKS) LIKE MARC-WERKS OPTIONAL *" EXPORTING *" VALUE(TOPMAT) LIKE CSTMAT STRUCTURE CSTMAT *" VALUE(DSTST) LIKE CSDATA-XFELD *" TABLES *" STB STRUCTURE STPOX *" MATCAT STRUCTURE CSCMAT OPTIONAL *" EXCEPTIONS *" ERROR *"---------------------------------------------------------------------- CALL FUNCTION 'CS_BOM_EXPL_MAT_V2' EXPORTING capid = 'PP01' "应用程序 ID datuv = DATUV "有效日期 mtnrv = MTNRV "物料号 stlan = '1' "BOM Usage#1 is product stlal = '1' "Alternative BOM mehrs = 'X' "多级展开 mktls = 'X' werks = WERKS "工厂号 IMPORTING topmat = topmat "顶级物料数据 TABLES stb = stb "BOM 明细表 matcat = matcat. "父级物料清单表 IF sy-subrc <> 0. WRITE:/ sy-subrc. RAISE error. ENDIF. 激活,测试一下,结果是对的,说明这个远程函数是没问题的。下面开始用c# 去调用这个远程函数。
ENDFUNCTION.
c# 调用sap远程函数,搜索一下,大多人使用 的 是.net connector 3.0。我这次用的是开源程序 SapNwRfc,开源地址是:https://github.com/huysentruitw/SapNwRfc,强烈推荐非常好用!
c#代码,第一步获取连接:
public class SAPConnection { public static SapConnection OpenConnection() { string connectionString = "AppServerHost=192.168.1.**; SystemNumber=00; User=***;Password=***; Client=300; Language=EN; PoolSize=5; Trace=8"; var connection = new SapConnection(connectionString); connection.Connect(); return connection; } }
创建winform窗体,大概是这样的:
查询按钮事件代码,如下,先把bom数据查询出来,然后再通过递归函数 用treeView展示出来:
private void button1_Click(object sender, EventArgs e) { dataGridView1.DataSource = null; dataGridView1.Refresh(); listSTB.Clear(); var connection = SAPConnection.OpenConnection(); var someFunction = connection.CreateFunction("ZFM_****001"); string str1 = someFunction.Metadata.Parameters.Count().ToString(); string strdate = dtp_DATUV.Value.ToString("yyyyMMdd"); var result = someFunction.Invoke<EexportCS_BOMResult>(new ImportParameters_CS_BOM { DATUV = strdate, MTNRV = txt_MTNRV.Text.Trim(), WERKS = txt_WERKS.Text.Trim(), }); if (result.STB.Count() > 0) { foreach (var stb in result.STB) { var someFunction1 = connection.CreateFunction("ZFM_****002"); var result1 = someFunction1.Invoke<EexportZHUBOM002Result>(new ImportParameters_ZHUBOM002 { I_MTNRV = stb.IDNRK, }); stb.OJTXB = result1.T_MAKT[0].MAKTX; listSTB.Add(stb); } } connection.Disconnect(); dataGridView1.AutoGenerateColumns = false; dataGridView1.DataSource = listSTB; treeView1.Nodes.Clear(); treeView1.Refresh(); List<EexportSTB> list1 = listSTB.Where(a => a.STUFE == "1").ToList(); tn.Nodes.Clear(); tn.Text = result.TOPMAT.STLNR + "----" + result.TOPMAT.MATNR; AddChildModuleTreeNode(tn, list1); treeView1.Nodes.Add(tn); treeView1.Nodes[0].ExpandAll(); }
递归函数:
/// <summary> /// 递归函数 /// </summary> private void AddChildModuleTreeNode(TreeNode tn, List<EexportSTB> list1) { for (int i = 0; i < list1.Count; i++) { TreeNode node = new TreeNode(); node.Text = list1[i].IDNRK + "----" + list1[i].STLNR.ToString(); // node.Tag = ds.Tables[0].Rows[i]["module_id"].ToString(); tn.Nodes.Add(node); if (!string.IsNullOrEmpty(list1[i].XTLNR)) { List<EexportSTB> list2 = listSTB.Where(a => a.STLNR == list1[i].XTLNR).ToList(); AddChildModuleTreeNode(node, list2); } } }
最后查询结果展示: