用户编辑Excel单元格时Call rejected by Callee问题的规避方案咨询
解决Excel单元格编辑状态下调用COM插件触发"Call is Rejected by Callee"错误的优化方案
问题背景
我们的应用支持打开并引用Excel表格(.xlsx文件),通过自定义代码GetOrCreateCOMObject获取Excel.Application对象可正常执行,但调用oXApp.COMAddIns.Item("[OurProprietaryAddinName].AddinModule").Object获取自有Excel插件时,若用户在其他Excel表格的单元格处于编辑状态(未退出),会触发**"Call is Rejected by Callee"**错误。现有通过捕获异常检测编辑状态的方案体验较差,易引发客服咨询,以下是更优的错误规避方案。
现有检测代码:
Dim oFocusCheck As Object Dim bFocusedInCell As Boolean = False Try oFocusCheck = oXApp.CommandBars.FindControl(Microsoft.Office.Core.MsoControlType.msoControlButton, 23, System.Reflection.Missing.Value, System.Reflection.Missing.Value) Marshal.ReleaseComObject(oFocusCheck) oFocusCheck = Nothing Catch bFocusedInCell = True End Try
优化方案
方案一:延迟重试机制
捕获目标错误后,不直接提示用户,而是自动延迟一段时间后重试调用插件对象,最多重试3-5次。仅当多次重试失败时,再提示用户退出编辑状态,可覆盖用户临时停留编辑状态的场景,减少不必要的干扰。
示例代码:
Dim retryCount As Integer = 0 Dim maxRetries As Integer = 3 Dim success As Boolean = False Dim pluginObj As Object = Nothing Do While retryCount < maxRetries AndAlso Not success Try pluginObj = oXApp.COMAddIns.Item("[OurProprietaryAddinName].AddinModule").Object success = True Catch ex As Exception When ex.Message.Contains("Call is Rejected by Callee") retryCount += 1 System.Threading.Thread.Sleep(500) End Try Loop If Not success Then MessageBox.Show("请先退出Excel单元格编辑状态,再进行操作") End If
方案二:直接通过Excel API判断编辑状态
替代基于CommandBar的异常捕获检测方式,利用Excel原生属性直接判断编辑状态,逻辑更可靠且避免异常捕获的不优雅实现:
Dim bFocusedInCell As Boolean = False ' 方法1:检查Interactive属性(编辑状态下会返回False) If Not oXApp.Interactive Then bFocusedInCell = True End If ' 方法2:检查光标类型(编辑状态下光标为xlIBeam) If oXApp.Cursor = Microsoft.Office.Interop.Excel.XlMousePointer.xlIBeam Then bFocusedInCell = True End If
方案三:强制退出单元格编辑(谨慎使用)
若业务场景允许,可尝试发送ESC键消息强制退出编辑状态,再调用插件对象。需注意此操作可能丢失用户未保存的单元格输入,建议仅在特定场景下使用,或提前告知用户风险:
' 发送ESC键到Excel窗口 SendKeys.SendWait("{ESC}") ' 等待状态切换完成 System.Threading.Thread.Sleep(100) ' 再尝试获取插件对象 Dim pluginObj As Object = oXApp.COMAddIns.Item("[OurProprietaryAddinName].AddinModule").Object
内容的提问来源于stack exchange,提问作者DinahMoeHumm
相关产品推荐
相关产品推荐

