C#实现Excel宏时For Each循环出现COMException错误求助
解决C#操作Excel时的COMException(0x800706BE)错误
核心问题分析
触发0x800706BE远程调用失败错误,主要源于以下几个代码问题:
- 筛选参数逻辑错误:循环中错误将AA列整个区域
machine作为筛选值传入AutoFilter,而非当前遍历的单个设施单元格值,导致筛选逻辑失效。 - 数据范围引用失效:删除列后未重新计算最后一行,原
lastRow2基于删除前列位置计算,导致后续引用的单元格范围无效。 - 工作表创建对象错误:使用
xlApp2.Worksheets.Add可能将工作表添加到错误工作簿,引发RPC调用冲突。 - 未清理旧筛选状态:循环中未关闭上一次筛选,导致多次筛选操作冲突。
修正后的完整代码
private void button3_Click(object sender, EventArgs e) { Excel.Application xlApp2 = new Excel.Application(); Excel.Workbook xlWorkbook2; Excel.Worksheet firstWS; Excel.Range rng3; Excel.Range rng4; long lastRow2; long fullRow; // 打开目标工作簿 xlWorkbook2 = xlApp2.Workbooks.Open(fileExcel, 0, true, 5, "", "", true, Microsoft.Office.Interop.Excel.XlPlatform.xlWindows, "\t", false, false, 0, true, 1, 0); xlApp2.Visible = true; // 获取原始数据工作表 firstWS = xlWorkbook2.Worksheets["Report"]; // 先执行列删除操作,避免后续范围计算出错 firstWS.Range["K:N"].Delete(Excel.XlDeleteShiftDirection.xlShiftToLeft); firstWS.Range["F:I"].Delete(Excel.XlDeleteShiftDirection.xlShiftToLeft); // 更新表头文本 firstWS.Range["F1"].Value = "Current Qty"; firstWS.Range["G1"].Value = "NDC"; firstWS.Range["H1"].Value = "Pkg Sz of Comm. Containers"; firstWS.Range["I1"].Value = "Number of Full Comm. Containers"; // 重新计算当前I列的最后有效行(删除列后必须重新计算) fullRow = firstWS.Rows.Count; lastRow2 = firstWS.Cells[fullRow, "I"].End(Excel.XlDirection.xlUp).Row; // 按C列排序数据 rng3 = firstWS.Range["A1:I" + lastRow2]; rng3.Sort(rng3.Columns[3], Excel.XlSortOrder.xlAscending); // 生成C列的唯一值到AA列,用于后续循环筛选 firstWS.Columns[3].AdvancedFilter(Excel.XlFilterAction.xlFilterCopy, Type.Missing, CopyToRange: firstWS.Range["AA1"], Unique: true); // 复制原始数据到"Reporting"工作表 firstWS.Range["A1:I" + lastRow2].Copy(); Excel.Worksheet newerWSCopy = xlWorkbook2.Worksheets.Add(); newerWSCopy.Name = "Reporting"; rng4 = newerWSCopy.Range["A1"]; rng4.PasteSpecial(Excel.XlPasteType.xlPasteValues); // 获取AA列的筛选值范围(从AA2开始,跳过表头) Excel.Range machine = firstWS.Range["AA2", firstWS.Cells[firstWS.Rows.Count, "AA"].End(Excel.XlDirection.xlUp)]; foreach (Excel.Range facility in machine) { // 先关闭上一次的筛选状态,避免冲突 if (firstWS.AutoFilterMode) { firstWS.AutoFilterMode = false; } // 使用当前遍历的设施值作为筛选条件,筛选第3列(C列) firstWS.Range["A1:I" + lastRow2].AutoFilter(3, facility.Value, Excel.XlAutoFilterOperator.xlFilterValues, Type.Missing, Type.Missing); // 复制筛选后的可见区域 Excel.Range visibleRange = firstWS.AutoFilter.Range.SpecialCells(Excel.XlCellType.xlCellTypeVisible); visibleRange.Copy(); // 在当前工作簿内添加新工作表 Excel.Worksheet newWS = xlWorkbook2.Worksheets.Add(After: xlWorkbook2.Sheets[xlWorkbook2.Sheets.Count]); newWS.AutoFilterMode = false; // 指定粘贴到新工作表的A1单元格 newWS.Range["A1"].PasteSpecial(Excel.XlPasteType.xlPasteAll); } // 清理剪贴板,释放Excel资源 xlApp2.CutCopyMode = false; }
额外优化建议
- COM对象释放:操作完成后需手动释放所有Excel对象(Application、Workbook、Worksheet、Range),避免Excel进程残留,可使用
System.Runtime.InteropServices.Marshal.ReleaseComObject()方法。 - 异常处理:添加
try-catch-finally块,确保即使发生错误也能关闭Excel进程并释放资源。 - 性能优化:减少频繁的Copy/Paste操作,可直接遍历单元格赋值,提升大文件处理效率。
内容的提问来源于stack exchange,提问作者asmcrae1997
相关产品推荐
相关产品推荐

