tags:

views:

326

answers:

4

I'm trying to read an excel file from C# using COM, and can get it opened and loaded just fine. However, I don't want to use all of the data on the sheet (it expands monthly), just a certain subset that starts below the top of the sheet (row 3 for headers, row 4 for data) and goes to the end. I can currently get a range representing the entire set of data as Excel.Worksheet.UsedRange, but next I need to either manipulate this down to the desired range, or (preferably) find the end point to pass into another range for my actual data retrieval. Can Anyone tell me how to do either of these? Thanks.

A: 

From MSDN:

"Use the End property, along with a value from the XlDirection enumeration (xlUp, xlToRight, xlToLeft, xlDown), to retrieve a range that represents the cell at the end of the region, as if you'd pressed the key described by the enumerated value;"

rngDown = rng.get_End(Excel.XlDirection.xlDown);
Lance Roberts
there is no such method available, I think you're thinking of get_End
Stan R.
When I tried this, it returned the end of the containing sheet (Row 65536), rather that the end of the UsedRange.
Joseph Sturtevant
@Stan, yes you're right that's a misprint on the MS website, thanks
Lance Roberts
A: 

You should be able to use the Range.Row, Range.Rows.Count, Range.Column, and Range.Columns.Count properties to get the start and end of your range like so:

Dim used As Range, first As Range, last As Range
Set used = Sheet1.UsedRange
Set first = Sheet1.Cells(used.Row, used.Column)
Set last = Sheet1.Cells(used.Row + used.Rows.Count, used.Column + used.Columns.Count)

MsgBox ("First: " + first.Address + " Last: " + last.Address)

That sample code is in VBA, but all of those functions should be available in C# with COM.

Joseph Sturtevant
@Joseph, there was a misprint on the MS website, use get_End instead
Lance Roberts
make sure you either select a cell first, or use it in a union form
Lance Roberts
A: 

Ok, found an answer (after nearly 3 hours total searching, asked here 2 hours in), so will post here for others.

Excel.Range urange = (Excel.Range)xlWorkSheet.UsedRange; // gives us the actual range
string used = urange.get_Address(false, false, Excel.XlReferenceStyle.xlA1, Type.Missing, Type.Missing));

From the MSDN:
public string get_Address (
[OptionalAttribute] Object RowAbsolute,
[OptionalAttribute] Object ColumnAbsolute,
[OptionalAttribute] XlReferenceStyle ReferenceStyle,
[OptionalAttribute] Object External,
[OptionalAttribute] Object RelativeTo
)

which apparently the first two are true/false flags, the next is defined as an Microsoft.Office.Interop.Excel.XlReferenceStyle object, and I'm guessing the External is either a reference to an external file, or a flag of some sort. RelativeTo, I can only guess that it refers to an arbitrary position defined, maybe a range object, maybe a string. Unfortunately, the MSDN is extremely sparse on this topic, so I'm just guessing here and posting my guesses. However, using this code as I've posted, I'm able to retrieve the total used as "A1:B245" which gives me exactly what I want, and I can then create a new range by extracting the second part and can then continue on.

Tom
+1  A: 

I am not sure what you are trying to do. But here are some examples.

Assume I have the following range:

Excel.Worksheet sheet = this.Application.ActiveSheet as Excel.Worksheet;
Excel.Range range = sheet.get_Range("A1", "B5") as Excel.Range;

To Move your Range Down by n-number of row:

   int n = 1;
   int rows = range.Rows.Count;
   int cols = range.Columns.Count;

   Excel.Range newRange = range.get_Offset(n, 0).get_Resize(rows-n,cols);
   newRange.Select(); //will select the new range will be 1 row lower

To Move your bottom row up

   Excel.Range newRange = range.get_Resize(rows-n,cols);
   newRange.Select(); //will select the new range will be 1 row higher

I assume you can figure out how to move it side to side.

get_Offset() will move the whole range over and then you need to resize the range.

EDIT: Now that i know what you want.

To select the Last Cell:

   Excel.Range lastCell = range.Cells[rows, cols] as Excel.Range;
   lastCell.Select();

Now you can use your own starting point like so:

   Excel.Range newRange = sheet.get_Range("B1", lastCell);
   newRange.Select();
Stan R.
you answered your own question, however i still think this answer will be useful to you in the long term.
Stan R.
Yeah, this is great for when I know the positions I want to go to, but i'm trying to find the last data position when I don't know what it will be..
Tom
@Tom, please take look at my updated answer it will show how to do what you want, without get_Address.
Stan R.
Yeah, I like your answer a lot. I just got sidetracked by some client issues. Will look into using this. Thanks.
Tom