C# VSTO:为数据透视表单元格着色
嗨,我正在尝试为数据透视表添加一些代码颜色。 它可以很好地为单元格着色,但是如果我刷新表格,所有颜色都会消失,就好像颜色没有正确附加到数据透视表一样。
我有以下代码(这是较大代码的片段):
myPivotTable.PivotSelect("'" + item["Name"].ToString() + "'[All;Total]", XlPTSelectionMode.xlDataAndLabel, true);
((Range)Globals.ThisWorkbook.Application.Selection).Interior.Color = 15962653;
我尝试在 VB 中的 Excel 中执行宏,当它运行时,它工作得很好,所以我不明白为什么 C# VSTO 不会'不工作...
ActiveSheet.PivotTables("PivotTable1").PivotSelect "'ItemName'[All;Total]", xlDataAndLabel, True
Selection.Interior.Color = 15962653
非常感谢帮助:)
编辑
这里有更多的代码。 BaseVars.GlobalWB 是一个引用活动工作簿 (Globals.ThisWorkBook) 的变量。这使得可以同时使用 2 个 Excel,而 VSTO 不会在错误的工作簿上运行代码。
foreach (DataRow item in myPivotTableFields.Tables[0].Rows)
{
// Field name from data sheet
myPivotField = (PivotField)myPivotFields.Item(item["Name"].ToString());
// Field name in the pivot table
myPivotField.Caption = item["Caption"].ToString();
// Their subtotal value
myPivotField.set_Subtotals(Type.Missing, GenerateSubTotalArray(item["SubTotal"].ToString()));
#region Attribs
//Include new items in manual filter
if (item["Attrib01"].ToString() == "True")
{
myPivotField.IncludeNewItemsInFilter = true;
}
else
{
myPivotField.IncludeNewItemsInFilter = false;
}
// Show items labels in outline form
if (item["Attrib02"].ToString() == "Outline")
{
myPivotField.LayoutForm = XlLayoutFormType.xlOutline;
}
else
{
myPivotField.LayoutForm = XlLayoutFormType.xlTabular;
}
// Display labels from the next field in the same column
if (item["Attrib03"].ToString() == "True")
{
myPivotField.LayoutCompactRow = true;
}
else
{
myPivotField.LayoutCompactRow = false;
}
// Display subtotals at the top of each group
if (item["Attrib04"].ToString() == "AtBottom")
{
myPivotField.LayoutSubtotalLocation = XlSubtototalLocationType.xlAtBottom;
}
else
{
myPivotField.LayoutSubtotalLocation = XlSubtototalLocationType.xlAtTop;
}
// Insert blank line after each item label
if (item["Attrib05"].ToString() == "True")
{
myPivotField.LayoutBlankLine = true;
}
else
{
myPivotField.LayoutBlankLine = false;
}
// Show items with no data
if (item["Attrib06"].ToString() == "True")
{
myPivotField.ShowAllItems = true;
}
else
{
myPivotField.ShowAllItems = false;
}
// Insert page break after each item
if (item["Attrib07"].ToString() == "True")
{
myPivotField.LayoutPageBreak = true;
}
else
{
myPivotField.LayoutPageBreak = false;
}
#endregion
// Set up the pivot table selection
if (item["Selection"].ToString() != "(blank)")
{
myItems = new List<string>();
myItems = GlobalFunc.Explode(item["Selection"].ToString());
SetUpPivotTableSelection(myPivotTable, item["Name"].ToString(), myItems);
}
else if (item["Selection"].ToString() == "(blank)" && item["Orientation"].ToString() == "Filter")
{
myPivotField.ClearAllFilters();
myPivotField.CurrentPage = "(All)";
}
try
{
myPivotField.ClearValueFilters();
myPivotField.ShowDetail = true;
}
catch (Exception ex)
{
GlobalFunc.DebugWriter("Error during Pivot Table Reset: " + ex.Message);
}
try
{
myPivotTable.PivotSelect("'" + item["Name"].ToString() + "'[All;Total]", XlPTSelectionMode.xlDataAndLabel, true);
// Set up the fields borders if it has any
myRange = BaseVars.GlobalWB.Application.get_Range(BaseVars.GlobalWB.Application.Selection, BaseVars.GlobalWB.Application.Selection);
myRange.Borders[XlBordersIndex.xlEdgeBottom].LineStyle = (XlLineStyle)InsertLineStyle(item["Attrib12"].ToString());
myRange.Borders[XlBordersIndex.xlEdgeLeft].LineStyle = (XlLineStyle)InsertLineStyle(item["Attrib13"].ToString());
myRange.Borders[XlBordersIndex.xlEdgeRight].LineStyle = (XlLineStyle)InsertLineStyle(item["Attrib14"].ToString());
myRange.Borders[XlBordersIndex.xlEdgeTop].LineStyle = (XlLineStyle)InsertLineStyle(item["Attrib15"].ToString());
}
catch (Exception ex)
{
GlobalFunc.DebugWriter("<LI>Error occured: " + ex.Message + "</LI>");
}
// Insert the colors of the field, gradient or solid
if (item["Color_Total2"].ToString() != null && item["Color_Total2"].ToString() != "")
{
Base.InsertGradient(myRange, int.Parse(item["Color_Total1"].ToString().Replace("0x", ""), System.Globalization.NumberStyles.HexNumber), int.Parse(item["Color_Total2"].ToString().Replace("0x", ""), System.Globalization.NumberStyles.HexNumber), false);
}
else if (item["Color_Total1"].ToString() != null && item["Color_Total1"].ToString() != "")
{
BaseVars.GlobalWB.Application.get_Range(BaseVars.GlobalWB.Application.Selection, BaseVars.GlobalWB.Application.Selection).Interior.Color = int.Parse(item["Color_Total1"].ToString().Replace("0x", ""), System.Globalization.NumberStyles.HexNumber);
}
}
HI, I'm trying to make some code color a PivotTable.
It works just fine coloring the cells it's supposed to, but if I refresh the table, all the colors disappear, as if the colors haven't been properly attached to the PivotTable.
I have the following code (this is a snip from a larger code):
myPivotTable.PivotSelect("'" + item["Name"].ToString() + "'[All;Total]", XlPTSelectionMode.xlDataAndLabel, true);
((Range)Globals.ThisWorkbook.Application.Selection).Interior.Color = 15962653;
I've tried doing a macro in Excel in VB, and when it runs, it work works perfectly, so I don't understand why the C# VSTO won't work...
ActiveSheet.PivotTables("PivotTable1").PivotSelect "'ItemName'[All;Total]", xlDataAndLabel, True
Selection.Interior.Color = 15962653
Help is much appreciated :)
EDIT
Here's a bit more of the code.
BaseVars.GlobalWB is a variable which refers to the active workbook (Globals.ThisWorkBook). This makes it possible to work with 2 Excels at the same time, without the VSTO running code on the wrong workbook.
foreach (DataRow item in myPivotTableFields.Tables[0].Rows)
{
// Field name from data sheet
myPivotField = (PivotField)myPivotFields.Item(item["Name"].ToString());
// Field name in the pivot table
myPivotField.Caption = item["Caption"].ToString();
// Their subtotal value
myPivotField.set_Subtotals(Type.Missing, GenerateSubTotalArray(item["SubTotal"].ToString()));
#region Attribs
//Include new items in manual filter
if (item["Attrib01"].ToString() == "True")
{
myPivotField.IncludeNewItemsInFilter = true;
}
else
{
myPivotField.IncludeNewItemsInFilter = false;
}
// Show items labels in outline form
if (item["Attrib02"].ToString() == "Outline")
{
myPivotField.LayoutForm = XlLayoutFormType.xlOutline;
}
else
{
myPivotField.LayoutForm = XlLayoutFormType.xlTabular;
}
// Display labels from the next field in the same column
if (item["Attrib03"].ToString() == "True")
{
myPivotField.LayoutCompactRow = true;
}
else
{
myPivotField.LayoutCompactRow = false;
}
// Display subtotals at the top of each group
if (item["Attrib04"].ToString() == "AtBottom")
{
myPivotField.LayoutSubtotalLocation = XlSubtototalLocationType.xlAtBottom;
}
else
{
myPivotField.LayoutSubtotalLocation = XlSubtototalLocationType.xlAtTop;
}
// Insert blank line after each item label
if (item["Attrib05"].ToString() == "True")
{
myPivotField.LayoutBlankLine = true;
}
else
{
myPivotField.LayoutBlankLine = false;
}
// Show items with no data
if (item["Attrib06"].ToString() == "True")
{
myPivotField.ShowAllItems = true;
}
else
{
myPivotField.ShowAllItems = false;
}
// Insert page break after each item
if (item["Attrib07"].ToString() == "True")
{
myPivotField.LayoutPageBreak = true;
}
else
{
myPivotField.LayoutPageBreak = false;
}
#endregion
// Set up the pivot table selection
if (item["Selection"].ToString() != "(blank)")
{
myItems = new List<string>();
myItems = GlobalFunc.Explode(item["Selection"].ToString());
SetUpPivotTableSelection(myPivotTable, item["Name"].ToString(), myItems);
}
else if (item["Selection"].ToString() == "(blank)" && item["Orientation"].ToString() == "Filter")
{
myPivotField.ClearAllFilters();
myPivotField.CurrentPage = "(All)";
}
try
{
myPivotField.ClearValueFilters();
myPivotField.ShowDetail = true;
}
catch (Exception ex)
{
GlobalFunc.DebugWriter("Error during Pivot Table Reset: " + ex.Message);
}
try
{
myPivotTable.PivotSelect("'" + item["Name"].ToString() + "'[All;Total]", XlPTSelectionMode.xlDataAndLabel, true);
// Set up the fields borders if it has any
myRange = BaseVars.GlobalWB.Application.get_Range(BaseVars.GlobalWB.Application.Selection, BaseVars.GlobalWB.Application.Selection);
myRange.Borders[XlBordersIndex.xlEdgeBottom].LineStyle = (XlLineStyle)InsertLineStyle(item["Attrib12"].ToString());
myRange.Borders[XlBordersIndex.xlEdgeLeft].LineStyle = (XlLineStyle)InsertLineStyle(item["Attrib13"].ToString());
myRange.Borders[XlBordersIndex.xlEdgeRight].LineStyle = (XlLineStyle)InsertLineStyle(item["Attrib14"].ToString());
myRange.Borders[XlBordersIndex.xlEdgeTop].LineStyle = (XlLineStyle)InsertLineStyle(item["Attrib15"].ToString());
}
catch (Exception ex)
{
GlobalFunc.DebugWriter("<LI>Error occured: " + ex.Message + "</LI>");
}
// Insert the colors of the field, gradient or solid
if (item["Color_Total2"].ToString() != null && item["Color_Total2"].ToString() != "")
{
Base.InsertGradient(myRange, int.Parse(item["Color_Total1"].ToString().Replace("0x", ""), System.Globalization.NumberStyles.HexNumber), int.Parse(item["Color_Total2"].ToString().Replace("0x", ""), System.Globalization.NumberStyles.HexNumber), false);
}
else if (item["Color_Total1"].ToString() != null && item["Color_Total1"].ToString() != "")
{
BaseVars.GlobalWB.Application.get_Range(BaseVars.GlobalWB.Application.Selection, BaseVars.GlobalWB.Application.Selection).Interior.Color = int.Parse(item["Color_Total1"].ToString().Replace("0x", ""), System.Globalization.NumberStyles.HexNumber);
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
如果您使用的是 C# VSTO,请勿使用 Selection.Interior.Color。请改用 Selection.Interior.ColorIndex。 Excel 使用 56 色调色板,您在 C# 中指定的任何颜色都会“转换”为这些调色板颜色之一。有效的 ColorIndex 值介于 1 和 56 之间。另请参阅有关调色板和 Excel 的有用参考。
http://www.mvps.org/dmcritchie/excel/colors.htm
If you're using C# VSTO, don't use Selection.Interior.Color. Use Selection.Interior.ColorIndex instead. Excel uses a 56-color palette, and any colors you specify in C# is "translated" into one of those palette colors. Valid ColorIndex values are between 1 and 56. Also check out this helpful reference on the color palette and Excel.
http://www.mvps.org/dmcritchie/excel/colors.htm
尝试使用十六进制值,例如
0xFFFFFF
。如果这不起作用,请尝试使用 XlRgbColor 颜色常量,例如
((Range)Globals.ThisWorkbook.Application.Selection).Interior.Color = Excel.XlRgbColor.rgbCornflowerBlue;
这里的限制是您只能使用 Excel 的调色板 - 如果您想要除此之外的颜色,则必须更改调色板 以编程方式 或 手动。如果调色板中没有您的颜色,Excel 将选择最接近的匹配颜色。
Try using a hex value instead, like
0xFFFFFF
.If that doesn't work, try using XlRgbColor color constants like
((Range)Globals.ThisWorkbook.Application.Selection).Interior.Color = Excel.XlRgbColor.rgbCornflowerBlue;
The limitation here is that you can only use Excel's palette - if you want a color outside of that, you'll have to change the palette either programatically or manually. If your color isn't in the palette, Excel will choose the closest match.
我找到了对此功能完全不同的解决方案,因此我不再需要对数据透视表中的任何内容进行着色 =)
我进行了完全重写,因此我只需将数据透视表保存到 xlsx 文件中,而不是将数据透视表保存到数据库并重新生成它们,然后从那里恢复它们。
I found a totally different solution to this functionality, so I no longer need to color anything in the PivotTable =)
I made a total rewrite, so instead of saving PivotTables to a databse and regenerating them, I simply save the PivotTables to xlsx files and recover them from there.