The standard method to get the range of an Excel spreadsheet in use is the UsedRange-method. I can copy all the used cells like this:
xlWorkSheet.UsedRange.Copy(misValue);
Unfortunately it is not a good method because cells are “activated” if the user write something in one and then delete it again. It can have the unintentional consequense that thousands of empty rows and columns are marked (and printed out in my case).
So I have translated this method to C# to get a more accurate range. On debugging, it gives FirstRow = 1, FirstColumn = 1, LastRow = 600, LastColumn = 2, which is what I wanted using my test worksheet as input.
But I still need to set the real used range and copy it. In VB, it is done like this:
Set RealUsedRange = Range(Cells(FirstRow, FirstColumn), Cells(LastRow, LastColumn))
How do I set a range and copy it in C#? I want to replace this line:
xlWorkSheet.UsedRange.Copy(misValue);
With the (1,1) to (600,2) range.
I have tried this:
return Excel.Range(xlWorkSheet.Cells[FirstRow, FirstColumn], xlWorkSheet.Cells[LastRow, LastColumn]);
But it gives Excel.Range is a ‘type’, which is not valid in the given context. I don’t know the proper way to write it.
// this struct is just to make the result more readable
public struct RealRange
{
public int FirstRow;
public int FirstColumn;
public int LastRow;
public int LastColumn;
public RealRange(int fr, int fc, int lr, int lc)
{
FirstRow = fr;
FirstColumn = fc;
LastRow = lr;
LastColumn = lc;
}
}
public RealRange RealUsedRange()
{
int FirstRow = xlWorkSheet.Cells.Find(
"*",
xlWorkSheet.get_Range("IV65536", misValue),
Excel.XlFindLookIn.xlValues,
Excel.XlLookAt.xlPart,
Excel.XlSearchOrder.xlByRows,
Excel.XlSearchDirection.xlNext,
System.Reflection.Missing.Value,
System.Reflection.Missing.Value,
System.Reflection.Missing.Value
).Row;
int FirstColumn = xlWorkSheet.Cells.Find(
"*",
xlWorkSheet.get_Range("IV65536", misValue),
Excel.XlFindLookIn.xlValues,
Excel.XlLookAt.xlPart,
Excel.XlSearchOrder.xlByColumns,
Excel.XlSearchDirection.xlNext,
System.Reflection.Missing.Value,
System.Reflection.Missing.Value,
System.Reflection.Missing.Value
).Column;
int LastRow = xlWorkSheet.Cells.Find(
"*",
xlWorkSheet.get_Range("IV65536", misValue),
Excel.XlFindLookIn.xlValues,
Excel.XlLookAt.xlPart,
Excel.XlSearchOrder.xlByRows,
Excel.XlSearchDirection.xlPrevious,
System.Reflection.Missing.Value,
System.Reflection.Missing.Value,
System.Reflection.Missing.Value
).Row;
int LastColumn = xlWorkSheet.Cells.Find(
"*",
xlWorkSheet.get_Range("IV65536", misValue),
Excel.XlFindLookIn.xlValues,
Excel.XlLookAt.xlPart,
Excel.XlSearchOrder.xlByColumns,
Excel.XlSearchDirection.xlPrevious,
System.Reflection.Missing.Value,
System.Reflection.Missing.Value,
System.Reflection.Missing.Value
).Column;
return new RealRange(FirstRow, FirstColumn, LastRow, LastColumn);
}
Solution
Notice I have changed the return value from void to the struct RealRange. This is to make the result more readable. The ‘range’ in a spreadsheet is the span between 2 cells. You can copy the range by using the get_range-function like I did below. Thank you to D. Hilgarth for the help.
rr = RealUsedRange();
this.workSheet.get_Range(
this.workSheet.Cells[rr.FirstRow, rr.FirstColumn],
this.workSheet.Cells[rr.LastRow, rr.LastColumn]).Copy(missing);
I think you want
RealUsedRangeto return an object of typeRange, just as the original function does.Something like this: