简体   繁体   中英

C# Excel Check cell contains a name in VSTO

I am trying to check if a cell contains name or is a named range, if not, I will assign a name. Here is my code:

if (cell.Name.Name == null) 
{ 
    Globals.ThisWorkbook.Names.Add("Temp", cell);
}
else
{
    // Move on
}

However, the above code will throw a COMException . Instead, I tried to get around it by doing this:

try
{
    if (cell.Name.Name == null) { }
}
catch (COMException)
{
    Globals.ThisWorkbook.Names.Add("Temp", cell);
}

The second code snippet worked but my spreadsheet is taking a serious performance hit. The operation went from ~80 ms to 1700 ms. This may not seem much but I am looping over a range selection.

The error message was:

System.Runtime.InteropServices.COMException was unhandled by user code
  HResult=-2146827284
  Message=Exception from HRESULT: 0x800A03EC
  Source=""
  ErrorCode=-2146827284
  StackTrace:
       at System.RuntimeType.ForwardCallToInvokeMember(String memberName, BindingFlags flags, Object target, Int32[] aWrapperTypes, MessageData& msgData)
       at Microsoft.Office.Interop.Excel.Range.get_Name()
       at ExcelTemplate1.Sheet1.button2_Click(Object sender, EventArgs e) in c:\Users\User\Desktop\ExcelTemplate1\ExcelTemplate1\Sheet1.cs:line 116
       at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
       at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
       at System.Windows.Forms.Control.WndProc(Message& m)
       at System.Windows.Forms.ButtonBase.WndProc(Message& m)
       at System.Windows.Forms.Button.WndProc(Message& m)
       at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
  InnerException: 

Question is, is there a better way to check for cell named range?

You are getting an error because cell.Name itself raises exception, let alone cell.Name.Name.

Globals.ThisWorkbook.Names.Item(1) gives you first of the names defined in your workbook. It gives values like =Sheet1!$E$10:$F$12 and =Sheet1!$C$5 to indicate what that named range refers to.

Globals.ThisWorkbook.Names.Item(1).Name shall give you actual name of the range. eg Temp in your case. That is one way to check.

Other way, in your code you are checking if the Name is null and if it is you are assigning it again. There is no harm in running this code multiple number of times:

Globals.ThisWorkbook.Names.Add("Temp", cell);

You can skip the check and run this statement instead. If the name is already there, it'll overwrite. Big deal!!!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM