You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在SAP B1中创建表时遭遇错误代码-1120的技术求助

SAP B1 创建用户表时遭遇错误代码-1120("引用计数大于0")

问题描述

从JSON文件读取数据批量创建SAP B1用户表时,调用objUserTableMD.Add()返回错误代码-1120,错误描述为**"Ref Count for this object is higher than 0"**(引用计数大于0)。

错误原因

该错误由SAP B1 COM对象未正确释放导致,代码存在两个核心问题:

  • 循环创建UserTablesMD、UserFieldsMD对象后,未显式释放非托管COM资源,GC无法及时回收这些对象,引发引用计数累积。
  • 创建UserFieldsMD时错误执行objUserFieldsMD = null;,直接丢弃刚获取的对象,加剧了资源泄漏问题。

解决方案

  1. 显式释放COM资源:使用Marshal.ReleaseComObject()在每个SAP COM对象使用完毕后释放资源,确保引用计数归零。
  2. 移除错误赋值:删除objUserFieldsMD = null;这一行,避免对象被提前丢弃。
  3. 优化GC调用:在释放COM对象后调用GC,提升非托管资源回收效率。

修正后的代码

string text = File.ReadAllText(@"C:\Users\vijay\Documents\Visual Studio 2015\Projects\TestAddon_03\TestAddon_03\json1.json");
var tableInfo = JsonConvert.DeserializeObject<TableInfo>(text);

try
{
    foreach (var table in tableInfo.tables)
    {
        string tbName = table.tableName;
        string tbDis = table.tableDescription;
        string tbType = table.tableType;

        SAPbobsCOM.UserTablesMD objUserTableMD = (SAPbobsCOM.UserTablesMD)oCompany.GetBusinessObject(SAPbobsCOM.BoObjectTypes.oUserTables);
        objUserTableMD.TableName = tbName;
        objUserTableMD.TableDescription = tbDis;

        switch (tbType)
        {
            case "Document":
                objUserTableMD.TableType = SAPbobsCOM.BoUTBTableType.bott_Document;
                break;
            case "MasterData":
                objUserTableMD.TableType = SAPbobsCOM.BoUTBTableType.bott_MasterData;
                break;
            case "NoObject":
                objUserTableMD.TableType = SAPbobsCOM.BoUTBTableType.bott_NoObject;
                break;
            default:
                Application.SBO_Application.MessageBox("无效的表类型");
                break;
        }

        int result = objUserTableMD.Add();

        if(result != 0)
        {
            Application.SBO_Application.MessageBox("表创建失败" + "\n --------- \n" + oCompany.GetLastErrorDescription() );
        }
        else
        {
            Application.SBO_Application.MessageBox("表创建成功");
            foreach (var field in table.fields)
            {
                string fieldNm = field.fieldName;
                string fieldType = field.fieldType;
                int fieldSize = field.fieldSize;

                SAPbobsCOM.UserFieldsMD objUserFieldsMD = (SAPbobsCOM.UserFieldsMD)oCompany.GetBusinessObject(SAPbobsCOM.BoObjectTypes.oUserFields);
                objUserFieldsMD.TableName = tbName;
                objUserFieldsMD.Name = field.fieldName;

                switch (fieldType)
                {
                    case "Numeric":
                        objUserFieldsMD.Type = SAPbobsCOM.BoFieldTypes.db_Numeric;
                        break;
                    case "String":
                        objUserFieldsMD.Type = SAPbobsCOM.BoFieldTypes.db_Alpha;
                        break;
                    case "Date":
                        objUserFieldsMD.Type = SAPbobsCOM.BoFieldTypes.db_Date;
                        break;
                    case "Float":
                        objUserFieldsMD.Type = SAPbobsCOM.BoFieldTypes.db_Float;
                        break;
                    case "Memo":
                        objUserFieldsMD.Type = SAPbobsCOM.BoFieldTypes.db_Memo;
                        break;
                    default:
                        Application.SBO_Application.MessageBox("无效的字段类型");
                        break;
                }

                objUserFieldsMD.Size = field.fieldSize;
                int fieldResult = objUserFieldsMD.Add();

                if (fieldResult != 0)
                {
                    Application.SBO_Application.MessageBox("字段创建失败");
                }
                else
                {
                    Application.SBO_Application.MessageBox("字段创建成功");
                }

                // 释放UserFieldsMD对象
                System.Runtime.InteropServices.Marshal.ReleaseComObject(objUserFieldsMD);
                objUserFieldsMD = null;
            }
        }

        // 释放UserTablesMD对象
        System.Runtime.InteropServices.Marshal.ReleaseComObject(objUserTableMD);
        objUserTableMD = null;
        GC.Collect();
        GC.WaitForPendingFinalizers();
    }
}
catch(Exception Create)
{
    Application.SBO_Application.MessageBox(Create.ToString());
}

额外说明

所有SAP B1的COM对象(如UserTablesMD、UserFieldsMD)在使用完毕后必须显式释放,否则会持续占用资源并引发引用计数类错误;循环处理COM对象时,建议每次循环结束都释放当前对象,避免资源累积。

内容的提问来源于stack exchange,提问作者CoolMaster

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 06:20:53