简体   繁体   中英

C# excel data validation drop down list throwserror

I'm trying to add drop down list to a range using c#.

This is what I have done so far.

 Worksheet ws = PPTAddIn.thisAddin2Obj.Application.ActiveWorkbook.ActiveSheet;
            ws.get_Range("a1").Validation.Delete();
            ws.get_Range("a1").Validation.InCellDropdown = true;
            ws.get_Range("a1").Validation.IgnoreBlank = true;
            ws.get_Range("a1").Validation.Add(XlDVType.xlValidateList, XlDVAlertStyle.xlValidAlertWarning, "opt1,opt2,opt3", Missing.Value);

at 3rd line of code it throws below exception
Exception from HRESULT: 0x800A03EC

错误图像

this is the stack trace

   at System.RuntimeType.ForwardCallToInvokeMember(String memberName, BindingFlags flags, Object target, Int32[] aWrapperTypes, MessageData& msgData)    at Microsoft.Office.Interop.Excel.Validation.set_InCellDropdown(Boolean ) at MS.ProductionPlanningTool.Excel.Ribbon_PPT.ribbon_signin_Click(Object sender, RibbonControlEventArgs e) in D:\MidasCloud\CloudTFS\ProductionPlanning\MSP2\MS.ProductionPlanningTool.Excel\UI\Ribbon_PPT.cs:line 1328    at Microsoft.Office.Tools.Ribbon.RibbonPropertyStorage.ControlActionRaise(IRibbonControl control)    at Microsoft.Office.Tools.Ribbon.RibbonPropertyStorage.ButtonClickCallback(RibbonComponentImpl component, Object[] args)    at Microsoft.Office.Tools.Ribbon.RibbonManagerImpl.Invoke(RibbonComponentCallback callback, Object[] args)    at Microsoft.Office.Tools.Ribbon.RibbonMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)    at Microsoft.Office.Tools.Ribbon.RibbonManagerImpl.System.Reflection.IReflect.InvokeMember(String name, BindingFlags invokeAttr, Binder binder, Object target, Object[] args, ParameterModifier[] modifiers, CultureInfo culture, String[] namedParameters)

The sequence of commands is incorrect. Move the Add statement to be immediately after the Delete statement. You can not set the other values on the Validation object if a validation does not exist.

Worksheet ws = PPTAddIn.thisAddin2Obj.Application.ActiveWorkbook.ActiveSheet;
ws.get_Range("a1").Validation.Delete();
ws.get_Range("a1").Validation.Add(XlDVType.xlValidateList, XlDVAlertStyle.xlValidAlertWarning, "opt1,opt2,opt3", Missing.Value);
ws.get_Range("a1").Validation.InCellDropdown = true;
ws.get_Range("a1").Validation.IgnoreBlank = true;

Side Note:

Use the macro recorder in Excel to get the syntax for an operation. While the output is in VBA, the syntax is not that different that you can not decipher the commands and translate to C#. VBA is close enough VB.Net that a VB to C# converter will yield code that you can clean up and use. The only issue will be that the macro-recorder makes extensive use of the Selection object and you should convert that to whatever the Selection object represents (most likely it is an Excel.Range ). You will also need to make the corrections for VB's indexed properties to the equivalent method calls (ie: Range("a1") -> get_Range("a1") ).

Edit: I originally did not check the syntax of your Add statement, but it appears that you are missing a parameter.

From the documentation :

void Add(
    XlDVType Type,
    Object AlertStyle,
    Object Operator,
    Object Formula1,
    Object Formula2
)

and your Add staterment:

Add(XlDVType.xlValidateList, 
    XlDVAlertStyle.xlValidAlertWarning, 
    "opt1,opt2,opt3", 
    Missing.Value)

It appears the you are missing the Operator parameter. Using the macro recorder, it appears that the default value is XlFormatConditionOperator.xlBetween .

You should also define a Validation object and use that instead of ws.get_Range("a1").Validation for setting/calling each property/method.

Try moving your ".InCellDropDown = true" to the end of the code.

I mean:

 Worksheet ws = PPTAddIn.thisAddin2Obj.Application.ActiveWorkbook.ActiveSheet;
            ws.get_Range("a1").Validation.Delete();
            ws.get_Range("a1").Validation.IgnoreBlank = true;
            ws.get_Range("a1").Validation.Add(XlDVType.xlValidateList, XlDVAlertStyle.xlValidAlertWarning, "opt1,opt2,opt3", Missing.Value);
            ws.get_Range("a1").Validation.InCellDropdown = true;

Hope that helps.

Try to take a look at this, it might help you:

(focus on the Part 2 - Restrict Entry to Predefined Items in a List)

https://www.codeproject.com/Tips/1089368/Apply-Data-Validation-to-Excel-Cells-in-Csharp

Thanks to the accepted answer for getting me most of the way there, but alas it didn't work first off. There was a missing paramater, as Jayakrishnan correctly points out in the comments under that answer. Because future visitors like me may not look at those comments for a while, I'll post my code here. My code shows the usage of named parameters to skip over the optional operator parameter. It also shows how to add data validation as a function taking any list of strings (I just do a .join beforehand!). Enjoy.

public void SetDropdownValidation(params string[] values)
{
    string valuesJoined = string.Join(",", values);
    Validation validation = RawRange.Validation;
    validation.Delete();
    validation.Add(XlDVType.xlValidateList, XlDVAlertStyle.xlValidAlertWarning, Formula1: valuesJoined, Formula2: Missing.Value);
    validation.InCellDropdown = true;
}

Notes

  • This function is written in the context of a class where RawRange is a member variable of type Range .
  • This code could be tweaked / made more flexible to deal with stuff like IgnoreBlank, but the basic idea is in the above

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