爲何.net調用SAP的BAPI接口須要調用BAPI_TRANSACTION_COMMIT呢?首先得明白BAPI_TRANSACTION_COMMIT這個BAPI的做用。它功勞很大,在SAP裏面不少的BAPI直接調用是不會有結果的,由於須要COMMIT一下才能生效,好比生成資產編號的BAPI:BAPI_FIXEDASSET_CREATE1,若是對他直接在SE37中調用運行或者使用SE38調用它,雖然能夠獲得一個資產編號,可是在AS03裏面查詢,系統會很白癡得提示你:該資產編號不存在於XX公司。更搞的是當你在AS01中新建資產編號時,新建的資產編號會跳過以前用BAPI生成「失敗」的號碼。spa
那麼,這就須要COMMIT一下,在調用這個BAPI以後再緊接調用BAPI_TRANSACTION_COMMIT這個。可是,在SE38中是能夠這樣作,而在.net中就沒那麼簡單了,直接在調用完BAPI_FIXEDASSET_CREATE1以後再緊接調用BAPI_TRANSACTION_COMMIT是不能夠的,雖然仍是生成了資產編號,但仍舊是個廢號。跟在SE37中調用無異。.net
怎麼在.net中解決這個問題呢,這就須要用到RfcSessionManager.BeginContext和RfcSessionManager.EndContext這兩個方法了。只有在這兩個方法之間調用BAPI才能方保萬無一失!接口
代碼以下:ci
一、首先引用:using SAP.Middleware.Connector;string
二、調用代碼:it
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());io
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());function
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已經能夠認出來了