I need to color Excel cells in a fast manner. I found similar method to write to Excel cells which for me is really fast, so I tried applying the same method when coloring the cells. Consider the following code:
xlRange = xlWorksheet.Range["A6", "AS" + dtSchedule.Rows.Count];
double[,] colorData = new double[dtSchedule.Rows.Count, dtSchedule.Columns.Count];
for (var row = 0; row < dtSchedule.Rows.Count; row++)
{
for (var column = 0; column < dtSchedule.Columns.Count; column++)
{
if (column <= 3)
{
colorData[row, column] = GetLightColor2("#ffffff");
continue;
}
if (dtSchedule.Rows[row][column].ToString() != "#000000" && !string.IsNullOrEmpty(dtSchedule.Rows[row][column].ToString()))
{
string[] schedule = dtSchedule.Rows[row][column].ToString().Split('/');
string color = schedule[0].Trim();
colorData[row, column] = GetLightColor2(color);
continue;
}
colorData[row, column] = GetLightColor2("#000000");
}
}
xlRange.Interior.Color = colorData;
This is the GetLightColor2 function:
private double GetLightColor2(string hex)
{
return ColorTranslator.ToOle(ColorTranslator.FromHtml(hex));
}
When I ran the code, an error was thrown at
xlRange.Interior.Color = colorData;
With the following error:
System.Runtime.InteropServices.COMException (0x80020005): Type mismatch. (Exception from HRESULT: 0x80020005 (DISP_E_TYPEMISMATCH)) at System.RuntimeType.ForwardCallToInvokeMember(String memberName, BindingFlags flags, Object target, Int32[] aWrapperTypes, MessageData& msgData) at Microsoft.Office.Interop.Excel.Interior.set_Color(Object value)
I could not find any other workaround unless coloring the cell by looping through each cell which is really slow. Or is it that I'm doing it the wrong way.
Thank you for your kind attention guys.
If your question is not about excel addin, I would strongly recommend to follow Akhil R J's advice. It's not the last big problem you'll encounter in interop, this technology is just one big problem and bug. If for some reason you cannot, I can tell you some things about your problem:
1) There is no way to do what you want using arrays. It is possible only for values and formulas.
2) Set Application.ScreenUpdating = false
, when you set colors or any other operation with excel. Then it freezes user input, things go faster.
3) If many cells have the same color - use Application.Union to make a range from separated cells of the same color. But it's effective only to merge up to 50 cells in one time. If you take more, merging operation takes too much time, and it's not effective. After that, just set one color to the whole merged range. Pretty effective, around 5-10 times faster in my case.
4) There is another way, difficult one. I going to try it myself for the same problem (I have an addin, so I cannot just start to use OpenXML). Using interop, you can copy the target range to the windows clipboard. In the clipboard it is stored in many formats, including something OpenXMl-like. So you can edit it in the clipboard and paste back, using interop again. I think it's the fastest way, but it must be very time consuming to write this code.
User contributions licensed under CC BY-SA 3.0