I know it is possible load a range of cell data into a system array in C#.
For Example:
Excel.Range r1 = ws.get_Range("A1", "Q55");
Array dataflds = (Array)r1.Cells.Value2;
Is there a way to do the same with the number formats for each cell in that range? Inspecting them one at a time is very slow. My attempts yield an error stating that you can not convert a string to a system array.
Related
I am attempting to read timestamps out of an excel sheet, which go down to a millisecond level.
e.g. 00:00:15.480, 00:00:24.640
However when i read the text value of the cell, it is rounding to the nearest second.
var ts = sheet.Cells[rowIndex, 2].Text; /* would produce 00:00:15.000 and 00:00:25.000 in above examples */
I have tried setting the number format on the cells to the be same custom format referenced in the sheet itself, but this has no effect:
sheet.Cells[rowIndex, 2].Style.Numberformat.Format = "hh:mm:ss.000";
If I try to access the value directly with
var ts = sheet.Cells[rowIndex, 2].Value;
it returns a double, e.g. 2.9166666666666666E-05
How can I get the timestamps with their millisecond values? Does EPPlus simply not allow this level of granularity?
As per Walter Vehoeven's comment, my issue was the format should have been "hh:mm:ss.fff"
I am using Excel as a reporting tool, for my desktop application. The app is written in C# (VS 2019).
The gist of my code is to obtain a range object from the worksheet, populate an array of null-able integers and write it back out to the same worksheet.
So far I have obtained a range of cells, where startRow is the first row highlighted in yellow:
Range startRow = (Range) input.Range["E" + row.ToString(), "K" + row.ToString()];
Initialise the local array as:
double?[,] startArray = new double?[1, 7];
Set the relevant values:
startArray[1,2] = 9.75;
And finally, write the data back:
startRow.Value2 = startArray;
When I write the array back, I get the error
The parameter is incorrect. (Exception from HRESULT: 0x80070057 (E_INVALIDARG))
In this case, I assume that it is because I have some null-able values in the array, as if I do not use a null-able array and as a result its values are zero by default, this works OK, but wites zeros out into the spreadsheet.
I did try using:
string[,] startArray = new string[1, 7];
which does work, but any fields that does have a value, are not seen as numeric and causes Excel formulae not to work.
So to my question, can I get the array to write back to Excel with nulls, or do I have to revert to using the cell object and only update the cells which contain a value?
As it happens, just the fact of writing this post has enabled me to fix it.
The simple answer is to write directly to the range only the values which contain a value.
So something like this:
for (int i = 0; i < 7; i++)
{
if (startArray[0, i] != null) startRow[1, i + 1] = startArray[0, i];
}
As for EPPlus, it looks a fantastic product, but as I already pay for an Excel license would find this a little over kill as a paid license would also be needed for EPPlus.
I have a column and i'm looking to cut rows 3-37 and move it to the column directly to the right of it.
I tried the following and it moves the values correctly to the right but the cell styles don't copy over.
Range copyRange = ws1.Range["L5:L37"];
Range insertRange = ws1.Range["M5:M37"];
insertRange = copyRange;
I've also tried solution from here Cut and Paste Columns in Excel Range with c# but nothing seem to copy
Range copyRange = ws1.Range["L5:L37"];
Range insertRange = ws1.Range["M5:M37"];
//insertRange.Insert(copyRange.Cut());
insertRange.Insert(XlInsertShiftDirection.xlShiftToRight, copyRange.Cut());
If you want to just replace the contents of the destination cells with the contents of the source cells, and delete the contents of the source cells, then the Range.Cut method ought to do the trick if you call it with the destination range as an argument:
Range sourceRange = ws1.Range["L5:L37"];
Range destinationRange = ws1.Range["M5:M37"];
sourceRange.Cut(destinationRange);
This will not copy sourceRange to the clipboard, but it will clear the clipboard if you already have a range on the clipboard.
You can also specify only the upper left cell of the destination range, and it will do the same thing:
Range sourceRange = ws1.Range["L5:L37"];
Range destinationRange = ws1.Range["M5"];
sourceRange.Cut(destinationRange);
If you want to keep the contents of the source cells, use Copy instead of Cut.
(Note that the statement insertRange = copyRange; definitely should never copy any cells anywhere if insertRange is a local variable. That could only happen if C# supported overloaded assignment (which, to my knowledge, it does not) or if some other code somehow "sensed" the assignment.)
Having some problems parsing numbers out of the following excel spread sheet.
The code:
var curQOH = toolkit.ExcelWorksheet.Cells[i, 28] as Range;
var curQAV = toolkit.ExcelWorksheet.Cells[i, 29] as Range;
if (!curQOH.Text.Contains("("))
Int32.TryParse(curQOH.Text, out lastQOH);
else
Int32.TryParse(curQOH.Value as string, out lastQOH);
if (!curQAV.Text.Contains("("))
Int32.TryParse(curQAV.Text, out lastQAV);
else
Int32.TryParse(curQAV.Value as string, out lastQAV);
The code above parses the positive numbers just fine. No issues. But it seems like it cannot parse negative number.
To my knowledge, Text is suppose to give me what the viewer sees so I would get (10) as an output. Value does give the right number but I cannot seem to parse that after casting to string. (this issue why I cant store the value as string or cast it to int, Excel cell value as string won't store as string)
Stoped using Excel Interlop and started using OpenXML Excel library
I am trying to use Microsoft.Office.Interop.Excel to read excel file in c#.
I want to read range of cells as it is way faster than reading cell one by one:
Range rbeg = (Range)sheet.Cells[1, i + 1];
Range rend = (Range)sheet.Cells[totalRowCount, i + 1];
Range range = sheet.get_Range(rbeg, rend);
column = (object[,])range.Value2;
The problem is when I want to get number format of cells by calling:
range.NumberFormat
I get System.DBNull. It works when I call it for single cell.
I want to distinguish between cells with numerical values and "%" values.
Any ideas?
See the documentation:
[NumberFormat] returns Null if all cells in the specified range
don't have the same number format.
What were you expecting it to do in this case?