我怎样才能以编程方式创build一个Excel“sorting/filtercombobox”?

我正在为手动创build的dynamic创build电子表格进行反向工程。 大多数单元格都是用简单的数据填充的,但有一些是“sort / Filter”下拉菜单,如下所示:

在这里输入图像说明

我怎样才能dynamic地创build这样的控制?

有没有办法在Excel电子表格中“查看源代码”来查看生成这些控件可能需要什么types的代码?

UPDATE

调整MacroMark的代码,编译:

var rangeMonthYears = _xlSheet.Range[_xlSheet.Cells[7, 3], _xlSheet.Cells[7, 15]]; object sortFilterCombobox = (object)rangeMonthYears.AutoFilter(1, System.Reflection.Missing.Value, XlAutoFilterOperator.xlAnd, System.Reflection.Missing.Value, true); _xlSheet.Cells["6", "C"] = sortFilterCombobox; //MonthLabel; 

…但它崩溃,给我提出这个刁钻的注意:

在这里输入图像说明

我怎么走错了?

更新2

要在下面的评论中回答MacroMarc,下面是遗留/模型电子表格(我是逆向工程)中的filter控件的屏幕截图:

在这里输入图像说明

在这种情况下,我从列表中取消了“十一月”,所以它被删除,你可以看到。 所以用户select什么影响下面的列的可见性。

更新3

随着所有这些花哨的东西被烘焙到传统的电子表格中,我正在考虑将它保存为模板,并根据需要简单地replace单元格内容。 这有什么理由不可行吗?

如果没有,为了做到这一点,我应该保存现有的扩展“作为Excelmacros的工作簿”?

更新4

我试图调整MacroMarc的答案,如下所示:

 Range monthYearCells = _xlSheet.Range[_xlSheet.Cells[COLUMN_HEADING_ROW, MONTH1_COL], _xlSheet.Cells[COLUMN_HEADING_ROW, MONTH13_COL]]; object monthFilter = (object)monthYearCells.AutoFilter(1, System.Reflection.Missing.Value, XlAutoFilterOperator.xlAnd, System.Reflection.Missing.Value, true); var monthFilterCell = (Range)_xlSheet.Cells[6, 3]; monthFilterCell.Value = monthFilter; 

…但得到了运行时exception:

在这里输入图像说明

是否是导致问题的最后一行(将monthFilter分配给范围的Value属性)? 如果是这样,我应该怎么指定monthFilter,或者我应该怎么做?

filter由Excel表格中的范围本身创build,或者可以通过Excel界面上的“过滤”button创build。 正如约书亚所说,你可以尝试在VBA中编写脚本,但是你的问题标签似乎使用了C#和Excel-Interop(??)

尝试使用C#代码中的范围对象句柄并应用.Autofilter方法。

 object result = (object)oRange.AutoFilter(1, System.Reflection.Missing.Value,ExApp.XlAutoFilterOperator.xlAnd,System.Reflection.Missing.Value, true); 

上面的ExApp是我的Interop.Excel命名空间的别名。

至于“开发人员”选项卡,请查看您的Excel版本的Google自定义function区选项。 右键点击function区或者文件 – >选项 – 等等

UPDATE

好的,所以要修改pivotfield的sorting和过滤属性,你需要抓住pivotField的句柄,例如,如果你的“Month”filter在单元格D5中,你可以这样做:

 Range oRange = oSheet.get_Range("D5", "D5"); PivotField pf = oRange.PivotField; pf.AutoSort((int)XlSortOrder.xlDescending, "Month"); //this sorts in reverse order pf.PivotItems(2).Visible = false; //this makes the second item deselected in filter 

不,您无法在Excel电子表格上“查看源代码”。 但是,您可以打开VBA编辑器并查看已经写入的代码。 在现代版本的Excel中,如何做到这一点可能不是那么明显。 在Excel窗口顶部,find小箭头,点击它,然后会出现一个下拉菜单。

在这里输入图像说明

在列表底部,您会看到一个标题为“更多命令”的选项。 点击那里,打开下面的窗口。

在这里输入图像说明

您可以过滤命令列表。 select“开发人员选项卡”,在右侧你会看到一个名为“Visual Basic”的命令。 您还有其他命令来录制macros,所以添加整个列表。 正如您从第一张截图中可以看到的,我已经将这些添加到Excel的副本中了。

请注意,您可能还需要调整安全设置。

现在您已经知道如何打开VBA编辑器,并且您有macros命令,您可以查看创buildfilter的代码,也可以自己创build一个filter,并logging一个macros以查看它是如何完成的。 生成的macros将在VBA中,您可以根据需要对其进行修改。

首先单击“录制macros”的“快速访问工具栏”图标,然后通过select要过滤的最上面一行中的单元格来添加filter,然后单击数据选项卡; 点击filter。

录制完macros后,你应该在VBA编辑器中看到如下所示的内容:

 Sub Macro1() ' ' Macro1 Macro ' ' Selection.AutoFilter ActiveSheet.Range("$A$1:$D$6").AutoFilter Field:=3, Criteria1:="1023123" Selection.AutoFilter End Sub 

现在我们已经涵盖了整个“开源”问题,这里是互操作问题的解决scheme。 我已经把你的代码,改变了,并testing它重现错误,并已经发现了什么问题。 该过程必须仅select表格的一部分或电子表格的完全空白区域。 当Excel试图find要过滤的范围的angular落时,它会遇到问题,因为没有可识别的angular落find。 以此为例:

  Excel.Application app = new Excel.Application(); app.Visible = true; Excel.Workbook wk = app.Workbooks.Add(); Excel.Worksheet sh = wk.Sheets[1]; sh.Cells[1, 1] = "col1"; sh.Cells[1, 2] = "col2"; sh.Cells[1, 3] = "col3"; sh.Cells[1, 4] = "col4"; sh.Cells[2, 1] = "data"; sh.Cells[2, 2] = "data"; sh.Cells[2, 3] = "data"; sh.Cells[2, 4] = "data"; sh.Cells[3, 1] = "data2"; sh.Cells[3, 2] = "data2"; sh.Cells[3, 3] = "data2"; sh.Cells[3, 4] = "data2"; //Excel.Range r1 = sh.Range[sh.Cells[1, 1], sh.Cells[3, 4]]; //this works Excel.Range r2 = sh.Range[sh.Cells[7, 3], sh.Cells[7, 15]]; //this fails //object sortFilterCombobox1 = (object)r1.AutoFilter(1, System.Reflection.Missing.Value, Excel.XlAutoFilterOperator.xlAnd, System.Reflection.Missing.Value, true); object sortFilterCombobox2 = (object)r2.AutoFilter(1, System.Reflection.Missing.Value, Excel.XlAutoFilterOperator.xlAnd, System.Reflection.Missing.Value, true); 

在下面的屏幕截图中,我突出显示了代码试图放置filter的那一行,它是空的。 所以,这里发生的是代码是由于某种原因没有引用您正在使用的电子表格的正确区域。

解决这个问题的方法之一是引用顶行中的第一个单元格而不是整行。 只要表格中没有空白,Excel就会查找整个表格。

在这里输入图像说明

所以尝试应用AutoFilter而不是整个范围:

 _xlSheet.Cells[7, 3] 

此外,我应该指出,如果你不知道,但是当你给一个单元格分配“sortFilterCombobox”,你实际上是一个布尔值popup单元格。 AutoFilter函数返回一个布尔值,而不是filter对象本身。