c# 用SapNwRfc调用sap内置bom函数用TreeView把bom展示出来

发布时间 2023-10-06 20:21:40作者: 博客园非著名喷子

一个需求,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);
          }
      }
  }

最后查询结果展示: