c# - Quickest excel interop way to copy a big range, sort it and remove unnecessay columns
问题描述
I have a c# code that produces a very big array that I write in an excel worksheet. Then I create another worksheet inside the same workbook with the same big array, and I sort the latter :
using Microsoft.Office.Interop.Excel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Excel = Microsoft.Office.Interop.Excel;
namespace ConsoleApp1
{
class Program
{
static object[,] returnDummyVariant()
{
object[,] res = new object[4,3];
res[0, 0] = "Surname";
res[0, 1] = "Height";
res[0, 2] = "Age";
res[1, 0] = "Julian";
res[1, 1] = "185";
res[1, 2] = "39";
res[2, 0] = "Mark";
res[2, 1] = "173";
res[2, 2] = "63";
res[3, 0] = "Patrick";
res[3, 1] = "193";
res[3, 2] = "23";
return res;
}
private static Excel.Range WriteTopLeft(object[,] variant, Excel.Range topLeft)
{
if (variant == null) return null;
int nL = variant.GetLength(0);
int nC = variant.GetLength(1);
if (nL * nC == 0) return null;
var worksheet = topLeft.Worksheet;
var writeRange = worksheet.Range[topLeft, topLeft.Offset[nL - 1, nC - 1]];
writeRange.Value2 = variant;
return writeRange;
}
static void Main(string[] args)
{
Application excel = new Application();
string path = @"paht\to\file\Book1.xlsx";
Workbook wb = excel.Workbooks.Open(path);
var wsData = (Excel.Worksheet)wb.Worksheets.Item[1];
wsData.Name = "Data";
var variant = returnDummyVariant();
var rData = WriteTopLeft(variant, wsData.Cells[1, 1]);
int rows = rData.Rows.Count;
int columns = rData.Columns.Count;
var ws = (Excel.Worksheet)wb.Worksheets.Add();
ws.Name = "Sorted Data";
rData = WriteTopLeft(variant, ws.Cells[1, 1]);
rData.Sort(rData.Columns[2, Type.Missing], Excel.XlSortOrder.xlDescending,
Type.Missing, Excel.XlSortOrder.xlAscending, Excel.XlSortOrder.xlAscending,
Type.Missing, Excel.XlSortOrder.xlAscending,
Excel.XlYesNoGuess.xlGuess, Type.Missing, Type.Missing,
Excel.XlSortOrientation.xlSortColumns, Excel.XlSortMethod.xlPinYin,
Excel.XlSortDataOption.xlSortNormal,
Excel.XlSortDataOption.xlSortNormal,
Excel.XlSortDataOption.xlSortNormal);
wb.Save();
wb.Close();
}
}
}
The .Sort
bit triggers an exception : System.Runtime.InteropServices.COMException: 'Reference isn't valid.'
and I cannot find why.
I tried several corrections here and there without any success.
解决方案
首先,作为一种好的做法,您应该捕获抛出的异常并查找任何其他信息 - 这将是此异常的 HRESULT。
但在这种情况下,获得的信息并不是特别有用 - 错误代码 0x800a03ec,用于多个故障。
查看Sort方法的文档,我发现您的第 4 个参数不正确 - 它只应在对数据透视表进行排序时使用,否则应作为 Type.Missing 传递。
rData.Sort(rData.Columns[2, Type.Missing], Excel.XlSortOrder.xlDescending,
Type.Missing, Type.Missing, Excel.XlSortOrder.xlAscending,
Type.Missing, Excel.XlSortOrder.xlAscending,
Excel.XlYesNoGuess.xlGuess, Type.Missing, Type.Missing,
Excel.XlSortOrientation.xlSortColumns, Excel.XlSortMethod.xlPinYin,
Excel.XlSortDataOption.xlSortNormal,
Excel.XlSortDataOption.xlSortNormal,
Excel.XlSortDataOption.xlSortNormal);
您还可以通过使用命名参数来简化方法调用,然后它将为您省略的参数使用适当的默认值:
rData.Sort(rData.Columns[2, Type.Missing],
XlSortOrder.xlDescending,
Header: XlYesNoGuess.xlGuess,
Orientation: XlSortOrientation.xlSortColumns);
此外,您应该退出应用程序 - excel.Quit(); 在您的申请结束时。默认情况下,一个 Excel 实例打开但不显示 - 如果您不退出应用程序,那么它将保持打开状态,直到您关闭您的 PC - 尝试运行您的应用程序几次然后打开任务管理器,您将看到一个相等的Excel 进程的数量。
如果您的应用程序像上面的代码一样相对较小,那么您在整理 Excel COM 对象方面应该没有任何问题,如果您的代码更复杂并且您使用许多对象(范围、工作表等都是 COM 对象),那么您应该确保通过使用 Marshal.ReleaseComObject 将它们从内存中释放并将引用设置为 null - 一些人还建议调用 GC.Collect 两次 - 这里有很多讨论:如何正确清理 Excel 互操作对象?
推荐阅读
- c# - 如何从 .NET Core Rest API 发出一个流以在 Angular 中作为 observable 使用?
- python - 在使用 5 折交叉验证时,在高度不平衡的数据中混淆 F1 分数和 AUC 分数
- kubernetes - K8 DNS 无法解析
- python - python矩阵的组合
- c# - 如何通过单击按钮更改另一个对象的动画?
- linux - AWS EC2 的 SCAP 合规性检查器错误
- regex - 用正则表达式 Erlang/Pearl 替换或忽略多个子字符串
- sql - 更改 SQL Server Express 默认 R 库路径
- tableau-api - Tableau - 基于一阶筛选
- reactjs - 从 bitbucket 管道将反应应用程序部署到 S3Bucket