Below is a generic attempt at creating dependent picklists dynamically from C#. When value 'A' is selected from pick1, pick2 is supposed to display the values from the SecondaryRangeA.
This code almost works, but instead of displaying the SecondaryRangeA it displays the literal value 'A'.
pick2.Validation.Add(XlDVType.xlValidateList,
XlDVAlertStyle.xlValidAlertStop,
XlFormatConditionOperator.xlBetween,
"=INDIRECT(\"A5\")");
When I open excel after it exports and modify the data validation it shows the formula.
=INDIRECT("A5")
If I modify the formula manually in Excel to exclude the quotes it works as expected.
=INDIRECT(A5)
When I modify the code to the following I get an exception. Any ideas?
pick2.Validation.Add(XlDVType.xlValidateList,
XlDVAlertStyle.xlValidAlertStop,
XlFormatConditionOperator.xlBetween,
"=INDIRECT(A5)");
Exception:
System.Runtime.InteropServices.COMException was unhandled
ErrorCode=-2146827284
Message=Exception from HRESULT: 0x800A03EC
Source=""
StackTrace:
at System.RuntimeType.ForwardCallToInvokeMember(String memberName, BindingFlags flags, Object target, Int32[] aWrapperTypes, MessageData& msgData)
at Microsoft.Office.Interop.Excel.Validation.Add(XlDVType Type, Object AlertStyle, Object Operator, Object Formula1, Object Formula2)
at TestExcelValidation.Program.Main(String[] args) in C:\TFS\ExcelInterop\TestExcelValidation\Program.cs:line 44
at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException:
Full Example:
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.Office.Interop.Excel;
namespace TestExcelValidation
{
class Program
{
static void Main(string[] args)
{
string temporaryPath = Path.GetTempPath();
string temporaryFile = Path.GetTempFileName();
Application appl = new Application();
appl.Visible = true;
Workbook workbook = appl.Workbooks.Open(temporaryFile, 0, true, 5, "", "", true, XlPlatform.xlWindows, "\t", false, false, 0, true, 1, 0);
Worksheet worksheet = (Worksheet)workbook.Worksheets.Add();
List<string> primaryList = new List<string>();
primaryList.Add("A");
primaryList.Add("B");
List<string> secondaryListA = new List<string>();
secondaryListA.Add("A1");
secondaryListA.Add("A2");
secondaryListA.Add("A3");
List<string> secondaryListB = new List<string>();
secondaryListB.Add("B1");
secondaryListB.Add("B2");
secondaryListB.Add("B3");
Range primaryRange = AddToExcelNamedRange(worksheet, primaryList, 'A', 1, "PrimaryRange");
Range secondaryRangeA = AddToExcelNamedRange(worksheet, secondaryListA, 'B', 1, "A");
Range secondaryRangeB = AddToExcelNamedRange(worksheet, secondaryListB, 'C', 1, "B");
Range pick1 = worksheet.Range["A5"];
pick1.Validation.Add(XlDVType.xlValidateList, XlDVAlertStyle.xlValidAlertStop, XlFormatConditionOperator.xlBetween, "=PrimaryRange");
Range pick2 = worksheet.Range["A6"];
pick2.Validation.Delete();
pick2.NumberFormat = "Text";
pick2.Validation.Add(XlDVType.xlValidateList, XlDVAlertStyle.xlValidAlertStop, XlFormatConditionOperator.xlBetween, "=INDIRECT(\"A5\")");
pick2.Validation.InCellDropdown = true;
pick2.Validation.IgnoreBlank = true;
}
private static Range AddToExcelNamedRange(Worksheet worksheet, List<string> primaryList, char col, int row, string rangeName)
{
Range range = worksheet.Range[col.ToString() + row.ToString(), col.ToString() + primaryList.Count().ToString()];
range.Name = rangeName;
foreach (string item in primaryList)
{
worksheet.Cells[row, col - 64] = item;
row++;
}
return range;
}
}
}