【问题标题】:BAPI_ACTTYPE_CHANGEMULTIPLE returns empty and doesn't change anything in the DatabaseBAPI_ACTTYPE_CHANGEMULTIPLE 返回空并且不会更改数据库中的任何内容
【发布时间】:2020-03-28 03:39:51
【问题描述】:

我需要一些帮助才能使我的 RFC 调用正常工作。我的连接工作正常,BAPI_ACTIVITYTYPE_GETLISTBAPI_ACTIVITYTYPE_GETDETAIL 也正常工作。但是下面的一段代码给了我一个空的 RETURN 表。也没有提交到数据库的更改。 我已经尝试了一切,但我似乎无法让它工作。

ActivityTypeStruct 是一个结构,它存储了我从之前的BAPI_ACTIVITYTYPE_GETDETAIL 得到的单个 ActivityType 的所有数据。

public void Change(ActivityTypeStruct currentActivityType)
{
    IRfcFunction transaction = repo.CreateFunction("BAPI_TRANSACTION_COMMIT");

    IRfcFunction function = repo.CreateFunction("BAPI_ACTTYPE_CHANGEMULTIPLE");
    function.SetValue("COAREA", "1000");

    IRfcTable table = function.GetTable("ACTIVITYTYPELIST");
    table.Append();
    table.SetValue("ACTTYPE", currentActivityType.actType);
    table.SetValue("DESCRIPT", "Test-Description");
    table.SetValue("VALID_FROM", currentActivityType.valid_from);
    table.SetValue("VALID_TO", currentActivityType.valid_to);

    function.Invoke(dest);
    transaction.Invoke(dest);
    var returnValue = function.GetTable("RETURN");
    var returnValue2 = transaction.GetStructure("RETURN");
}

BAPI_ACTTYPE_CREATEMULTIPLE 有同样的问题。一个解决方案可能会解决这两种方法。

【问题讨论】:

  • BAPI_TRANSACTION_COMMIT 必须在 BAPI_ACTTYPE_CHANGEMULTIPLE 之后调用
  • 感谢您的回答。我试过了,但似乎没有解决问题。
  • 哪些消息让您返回 RETURN?
  • 如果表 RETURN 为空,则表示一切正常,所以我没有其他想法。
  • 你应该总是首先在SAP系统本地运行BAPI,如果它执行良好,然后才继续在C#中测试它。它不起作用可能有多种原因,有些可能与 RFC 有关。尽可能排除所有可能的原因总是更好

标签: c# erp sap-erp saprfc bapi


【解决方案1】:

我终于找到了成功提交更改的方法。下面的代码 sn -p 修复了它。

RfcTransaction transaction = new RfcTransaction();
transaction.AddFunction(function);
RfcSessionManager.BeginContext(dest);
function.Invoke(dest);
transaction.Commit(dest);
RfcSessionManager.EndContext(dest);

【讨论】:

  • 很抱歉,但这不是您问题的解决方案。这是不属于一起的不同事物的混合(RfcTransaction 用于将 tRfc 与有状态的调用上下文声明混合,对 RfcTransaction 没有意义)。此外,您还调用了 BAPI 两次,一次是同步的,一次是通过事务性 RFC (tRfc)。不通过 tRfc 返回响应参数。您不应为此使用RfcTransaction。请考虑删除此错误答案。我很确定我在回答中写的内容是正确的并且会起作用。
  • 对不起,这是完全错误的。您混淆了两个不相关的场景:“有状态 RFC”(同步)和“事务 RFC”(“有点异步”,或者至少可以异步)。
  • PS:可能你对函数模块BAPI_TRANSACTION_COMMIT的名称感到困惑?这个名字确实很不幸...... :-( 它应该被命名为 BAPI_DB_COMMIT 之类的东西,因为它就是这样做的,但它与事务性 RFC 无关。
  • 我对此进行了更多思考,以及为什么它看起来好像您的代码“有效”。首先:您的代码不起作用,相反:它非常危险!那么为什么它似乎有效呢?因为你执行了两次功能模块!一次作为同步 RFC(但没有 BAPI_TRANSACTION_COMMIT,因此更改永远不会提交到数据库),然后第二次作为事务性 RFC...(触发“隐式 COMMIT WORK”并因此保留更改)在下一条评论中继续.
  • 为什么它很危险?因为真正的工作是在事务性 RFC (tRFC) 中完成的,而 BAPI 不适合 tRFC:
【解决方案2】:

关于有状态 RFC 和事务性 RFC 这两个概念似乎有点混淆,所以让我解释一下区别。

  1. 所谓的“更新 BAPI”需要有状态 RFC,即在 V1 或 V2 工作流程中运行并对数据库进行更改的 BAPI。

    代码示例基本上是上面Trixx给出的:

    • 通过 RfcSessionManager.BeginContext(dest) 在后端启动有状态的用户会话;
    • 执行 BAPI
    • 检查 RETURN 是否有错误(和/或捕获异常,如果 BAPI 行为不端)
    • 如果一切正常,调用 BAPI_TRANSACTION_COMMIT(在同一用户会话上执行数据库 COMMIT WORK),否则调用 BAPI_TRANSACTION_ROLLBACK
    • 通过 RfcSessionManager.EndContext(dest) 结束有状态的用户会话; (这对于避免后端和 .NET 端的连接和资源泄漏是必要的!)
  2. 事务性 RFC 用于实现“事务性安全性”,即保证执行(可能是多个 FM)以原子方式(“全有或全无”)按顺序只发生一次。如果使用队列版本,FMs首先被记录在后端的队列中,然后由调度程序异步执行。 请注意,无论哪种情况,RFC 层都不会返回任何返回值!(这是异步处理的本质。)

    请参阅 NCo 概述文档,了解如何最好地实现这一点。基本上,您创建一个 RfcTransaction 对象,向其中添加功能模块,然后定期提交事务,直到一个 Commit() 最终确定(通常第一次尝试就可以了,但为了保证“恰好一次” ,您需要准备好重试失败的提交)。一旦 Commit() 正常结束,您需要在本地删除此事务的所有数据(以避免“重复”),然后调用 ConfirmTransactionID() 方法。 注意:ConfirmTransactionID 与数据库 COMMIT 无关。它只是告诉后端它不再需要防止重复,现在可以安全地从其状态表中删除 TID。 (所以基本上这是一个清理步骤。)

【讨论】:

    【解决方案3】:

    您需要在有状态的调用序列中调用您的写操作 BAPI 函数模块,否则 BAPI_TRANSACTION_COMMIT 将通过新的 RFC 连接被调用,而不是在与前面的 BAPI_ACTTYPE_CHANGEMULTIPLE 相同的上下文 (LUW) 中。因此,第一个 LUW 中的数据没有提交,因此也没有持久化到数据库中。

    试试这个:

        RfcSessionManager.BeginContext(dest);
        try
        {
            function.Invoke(dest);
            transaction.Invoke(dest);
        }
        finally
        {
            RfcSessionManager.EndContext(dest);
        }
    

    【讨论】:

      【解决方案4】:

      在调用 BAPI 时没有收到任何 RETURN 条目的原因可能不止一个,而且通常取决于具体情况。例如:

      1. 函数运行正常,根本没有触发消息(在这种情况下检查是否真的在 SAP 中完成了更改)

      2. 函数执行中止或发生一些严重错误(在这种情况下检查函数异常,例如使用 try/catch 语句)

      3. 存在未填写RETURN 表的程序错误(在这种情况下,请查看support.sap.com 进行更正)

      关于您的职能

      我在我们的 SAP 环境中检查了如何使用 BAPI_ACTTYPE_CHANGEMULTIPLE

      在某些情况下,BAPI 会返回异常而不填写 RETURN 表。我认为您可以尝试类似

      try{
        . . .
        function.Invoke(dest);
        transaction.Invoke(dest);
        var returnValue = function.GetTable("RETURN");
        var returnValue2 = transaction.GetStructure("RETURN");
      
      }catch (Exception ex){
        ErrorMessage = ex.ToString()
      }
      

      另外:我不知道您使用的是哪个 SAP 组件版本,但我还发现了一个旧的 OSS 注释1888336 - BAPI_ACTTYPE_CHANGEMULTIPLE: Several errors are not issued。也许它已经过时了,但你永远不知道。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-10-08
        • 2019-03-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多