為什麼.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已經可以認出來了