zoukankan      html  css  js  c++  java
  • .NET连接SAP系统专题:BAPI_TRANSACTION_COMMIT的使用方法(十)

        为什么.net调用SAP的BAPI接口需要调用BAPI_TRANSACTION_COMMIT呢?首先得明白BAPI_TRANSACTION_COMMIT这个BAPI的作用。它功劳很大,在SAP里面很多的BAPI直接调用是不会有结果的,因为需要COMMIT一下才能生效,比如生成资产编号的BAPI:BAPI_FIXEDASSET_CREATE1,如果对他直接在SE37中调用运行或者使用SE38调用它,虽然可以得到一个资产编号,但是在AS03里面查询,系统会很白痴得提示你:该资产编号不存在于XX公司。更搞的是当你在AS01中新建资产编号时,新建的资产编号会跳过之前用BAPI生成“失败”的号码。

        那么,这就需要COMMIT一下,在调用这个BAPI之后再紧接调用BAPI_TRANSACTION_COMMIT这个。但是,在SE38中是可以这样做,而在.net中就没那么简单了,直接在调用完BAPI_FIXEDASSET_CREATE1之后再紧接调用BAPI_TRANSACTION_COMMIT是不可以的,虽然还是生成了资产编号,但仍旧是个废号。跟在SE37中调用无异。

        怎么在.net中解决这个问题呢,这就需要用到RfcSessionManager.BeginContext和RfcSessionManager.EndContext这两个方法了。只有在这两个方法之间调用BAPI才能方保万无一失!

        代码如下:

        1、首先引用:using SAP.Middleware.Connector;

        2、调用代码:

    public void nco(DataSet ds)
    {
    IDestinationConfiguration ID = new RfcConfig();
    RfcDestinationManager.RegisterDestinationConfiguration(ID);
    RfcDestination prd = RfcDestinationManager.GetDestination("PRD_000");
    RfcDestinationManager.UnregisterDestinationConfiguration(ID);
    nco(prd, ds);
    }
    public void nco(RfcDestination prd, DataSet ds)
    {
    bool asset = false;
    //选择要调用的BAPI的名称
    RfcFunctionMetadata BAPI_COMPANYCODE_GETDETAIL_MD = prd.Repository.GetFunctionMetadata("BAPI_REQUISITION_CREATE");
    //新建调用该BAPI的一个“实例”
    IRfcFunction function = null;
    function = BAPI_COMPANYCODE_GETDETAIL_MD.CreateFunction();
    IRfcTable ITEMS = function.GetTable("REQUISITION_ITEMS");
    IRfcTable ACCOUNT = function.GetTable("REQUISITION_ACCOUNT_ASSIGNMENT");
    IRfcTable RETURN = function.GetTable("RETURN");
    int j = 0;
    RfcSessionManager.BeginContext(prd);  //因期间需要同一个时间调用BAPI,而且各个BAPI之间有顺序关联,所以最好用这个包围起来
    for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
    {
    ITEMS.Insert();
    j = j + 1;
    j = j * 10;
    ITEMS.CurrentRow.SetValue("PREQ_ITEM", j.ToString());
    ITEMS.CurrentRow.SetValue("PREQ_NAME", ds.Tables[0].Rows[i]["QGA27"].ToString());
    ITEMS.CurrentRow.SetValue("CREATED_BY", ds.Tables[0].Rows[i]["QGA27"].ToString());
    ITEMS.CurrentRow.SetValue("PREQ_DATE", Convert.ToDateTime(ds.Tables[0].Rows[i]["QGA15"].ToString()).Date);
    ITEMS.CurrentRow.SetValue("MATERIAL", ds.Tables[0].Rows[i]["QGA04"].ToString());
    ITEMS.CurrentRow.SetValue("SHORT_TEXT", ds.Tables[0].Rows[i]["QGA05"].ToString());
    ITEMS.CurrentRow.SetValue("PLANT", "1201");
    ITEMS.CurrentRow.SetValue("QUANTITY", Convert.ToDecimal(ds.Tables[0].Rows[i]["QGA07"].ToString()));
    ITEMS.CurrentRow.SetValue("DELIV_DATE", Convert.ToDateTime(ds.Tables[0].Rows[i]["QGA09"].ToString()).Date);
    ITEMS.CurrentRow.SetValue("C_AMT_BAPI", Convert.ToDecimal(ds.Tables[0].Rows[i]["QGA14"].ToString()));
    ITEMS.CurrentRow.SetValue("ACCTASSCAT", ds.Tables[0].Rows[i]["QGA12"].ToString());
    ITEMS.CurrentRow.SetValue("DOC_TYPE", ds.Tables[0].Rows[i]["QGA28"].ToString());
    ITEMS.CurrentRow.SetValue("UNIT", ds.Tables[0].Rows[i]["QGA06"].ToString());

    ACCOUNT.Insert();
    ACCOUNT.CurrentRow.SetValue("PREQ_ITEM", j.ToString());
    ACCOUNT.CurrentRow.SetValue("COST_CTR", ds.Tables[0].Rows[i]["QGA31"].ToString());
    ACCOUNT.CurrentRow.SetValue("ORDER_NO", ds.Tables[0].Rows[i]["QGA10"].ToString());

    if (ds.Tables[0].Rows[i]["QGA12"].ToString().Trim() == "A")  //如果类别是A,即资产,则需要资产编号
    {
    ACCOUNT.CurrentRow.SetValue("ASSET_NO", GetASSET(prd, i, ds));  //设置新建的资产编号
    ACCOUNT.CurrentRow.SetValue("CO_AREA", "1000");
    ACCOUNT.CurrentRow.SetValue("SUB_NUMBER", "0000");
    }
    }
    function.SetValue("REQUISITION_ITEMS", ITEMS);
    function.SetValue("REQUISITION_ACCOUNT_ASSIGNMENT", ACCOUNT);
    function.Invoke(prd);//提交调用BAPI
    RfcSessionManager.EndContext(prd);
    if (RETURN.GetString("TYPE").ToString().Trim() == "I")
    {
    Suess.Text = RETURN.GetString("MESSAGE").ToString();
    BANFN.Text = "返回的请购单号:" + function.GetString("NUMBER").Trim();
    }
    else if (RETURN.GetString("TYPE").ToString().Trim() == "E")
    {
    Error.Text = RETURN.GetString("MESSAGE").ToString();
    }
    prd = null;
    }
    /// <summary>
    /// 取得资产编号
    /// </summary>
    /// <param name="prd"></param>
    /// <returns></returns>
    public string GetASSET(RfcDestination prd, int i, DataSet ds)
    {
    RfcFunctionMetadata BAPI_COMPANYCODE_GETDETAIL_MD = prd.Repository.GetFunctionMetadata("BAPI_FIXEDASSET_CREATE1");
    IRfcFunction function = null;
    function = BAPI_COMPANYCODE_GETDETAIL_MD.CreateFunction();
    IRfcStructure KEY = function.GetStructure("KEY");
    KEY.SetValue("COMPANYCODE", "2012");
    IRfcStructure GENERALDATA = function.GetStructure("GENERALDATA");
    GENERALDATA.SetValue("ASSETCLASS", "00005990");
    GENERALDATA.SetValue("DESCRIPT", ds.Tables[0].Rows[i]["QGA05"].ToString());
    IRfcStructure GENERALDATAX = function.GetStructure("GENERALDATAX");
    GENERALDATAX.SetValue("ASSETCLASS", "X");
    GENERALDATAX.SetValue("DESCRIPT", "X");
    function.SetValue("KEY", KEY);
    function.SetValue("GENERALDATA", GENERALDATA);
    function.SetValue("GENERALDATAX", GENERALDATAX);

    prd.Repository.ClearFunctionMetadata();  //貌似这句可以省略...
    RfcFunctionMetadata BAPI_COMPANYCODE_GETDETAIL_MD1 = prd.Repository.GetFunctionMetadata("BAPI_TRANSACTION_COMMIT");
    IRfcFunction function1 = null;
    function1 = BAPI_COMPANYCODE_GETDETAIL_MD1.CreateFunction();
    function1.SetValue("WAIT", "X");
    RfcSessionManager.BeginContext(prd);
    function.Invoke(prd);     //提交调用BAPI_FIXEDASSET_CREATE1  生成资产编号
    function1.Invoke(prd);   //提交调用BAPI_TRANSACTION_COMMIT 进行COMMIT一下
    RfcSessionManager.EndContext(prd);
    twMsgbox.AjaxAlert(function.GetValue("ASSET").ToString().Trim());
    return function.GetValue("ASSET").ToString().Trim();
    }

    新建立之后的请购单一切OK,同时,建立的资产编号在AS03已经可以认出来了!!

  • 相关阅读:
    JSP
    Map集合的四种遍历
    过滤器和监听器
    Web常用对象(2)
    Web常用对象(1)
    Java Web了解和Servlet初次见面
    面向对象之继承(1)
    SpringBoot使用简单缓存
    SpringBoot整合mybatis
    Spring Security 入门学习--数据库认证和授权
  • 原文地址:https://www.cnblogs.com/saper/p/2232325.html
Copyright © 2011-2022 走看看