在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;,直接丢弃刚获取的对象,加剧了资源泄漏问题。
解决方案
- 显式释放COM资源:使用
Marshal.ReleaseComObject()在每个SAP COM对象使用完毕后释放资源,确保引用计数归零。 - 移除错误赋值:删除
objUserFieldsMD = null;这一行,避免对象被提前丢弃。 - 优化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
相关产品推荐
相关产品推荐

