Get the last cell (column, row) of a Excel range object - c#

I have a Microsoft.Office.Interop.Excel.Range object and want to estimate the end-coordinates of that range ie (last column, last row).
There are no properties like LastCol, LastRow. The only properties are Column and Row, which specify the first cell. But how can I get the last cell of the range?

there is two way to do this :
Using Worksheet.UsedRange to determine the range. This will give you a range like A1:F10, or use Worksheet.UsedRange.SpecialCells(IExcel.XlCellType.xlCellTypeLastCell) to obtain F10.
With Range.End[IExcel.XlDirection] property, it returns the last continuous no-empty cell in the specified direction. Note that if the Range is empty, it will return the first no-empty cell or last cell(when excel reach its boundaries) in the given direction. Ex: the whole column A is empty, Range["A1"].End[IExcel.XlDirection.xlDown] will be A65535(last row in excel 97-2003, A1048576 for excel 2007)
//Just In case if you are wondering what IExcel is
using IExcel = Microsoft.Office.Interop.Excel;

This should get the first first and last cell of the range:
Initiate Excel.
Open workbook.
Select your range, in this case I got the used range of the active sheet.
Call the get_address method of the range.
Split the result of get_address on the colon.
The first value of the array resulting from the split will have the beginning cell.
The second value of the array resulting from the split will have the ending cell.
Replace the dollar signs with nothing and you will have the beginning and ending cells for the range.
Microsoft.Office.Interop.Excel.Application excel = new Application();
Microsoft.Office.Interop.Excel.Workbook workBook =
excel.Workbooks.Open(fileLocation);
Microsoft.Office.Interop.Excel.Worksheet sheet = workBook.ActiveSheet;
Microsoft.Office.Interop.Excel.Range range = sheet.UsedRange;
string address = range.get_Address();
string[] cells = address.Split(new char[] {':'});
string beginCell = cells[0].Replace("$", "");
string endCell = cells[1].Replace("$", "");
workBook.Close(true);
excel.Quit();
If you want the last column and last row relative to the beginning of the range you can do the following:
int lastColumn = range.Columns.Count;
int lastRow = range.Rows.Count;

Using Excel 2013, we've had lots of cases where UsedRange and xlCellTypeLastCell simply gave horribly wrong values.
For example, we'd have a worksheet containing just 7 columns, and sometimes these two functions would tell our C# code that there were 16,000+ columns of data.
The only method I found which truly worked out the bottom-right cell containing data was to use the tips in this suggestion:
sheet.Cells.Find()

Related

Get the last cell with a value in a selection Excel C#

I want to locate the last cell with a value from the selection made by a user in Excel.
When running the code below the lastCell variable returns the last cell in the sheet instead of the last cell in the selection.
I have no idea why this is happening as I'm telling the lastCell to use my selection.
Any information would be appreciated.
My code is as follows.
Excel.Range selectedRange = excelApp.Selection;
Excel.Worksheet ws = excelApp.ActiveWorkbook.ActiveSheet;
Excel.Range lastCell = selectedRange.Cells.SpecialCells(Excel.XlCellType.xlCellTypeLastCell, Type.Missing);
var newSelectedRange = ws.Cells.Range[selectedRange.Item[1, 1], lastCell];

C#: Finding exact string in excel sheet doesn't work with xlWhole

In my excel sheet I'm looking with my program for a key word like "Tescase". The parameter xlWhole dosen't find any range, but xlPart finds the key word. The problem with xlPart ist that it finds all the words in my excel sheet that contains the word "Testcase". But I would like to search only for the exact key word "Testcase".
Hear is my code:
var app = new Application();
var workbook = app.Workbooks.Open(pExcelFile);
var worksheet = (Worksheet)workbook.Worksheets.get_Item(1);
Range range = worksheet.UsedRange;
Range findTestcaseColumn = range.Find(What: "Testcase", LookIn: XlFindLookIn.xlValues, LookAt: XlLookAt.xlWhole);
if (findTestcaseColumn != null ) {
// found
} else {
//not found
}
But xlPart finds the key word "Testcase":
Range findTestcaseColumn = range.Find(What: "Testcase", LookIn: XlFindLookIn.xlValues, LookAt: XlLookAt.xlPart);
Thanks for suggetions.
Same problem here from VBA inside Excel: I fill a cell with a text, then come back later with .find to add something in the cell next to it. With xlPart I find the cell, with xlWhole it fails. Very strange behaviour. Resetting the style of the search column back to standard is a solution, but that's insane of course. It should ignore the style or have an option to do so.
Please join me giving feedback to Microsoft.
https://learn.microsoft.com/nl-nl/office/vba/api/excel.range.find

C#/Excel: Recover Number Error in Excel

I have a prob lem with excel and c#. When I set in the cell A1 a number like 123456789.
In all column A when the format is Number, next code is working without problems:
Workbook workbook = new Workbook(stream);
Worksheet worksheet = workbook.Worksheets[0];
var count = worksheet.Cells.Count; // count is 1
If I have column A design in format Text, converts that cell as '123456789 and then the code is wrong and returns me count=126 and when I query the cells all cells from 2 to 126 are empty or null and A1 as '1234567890
Why is happening that behavior?
Try out something like
Excel.Range range;
range = worksheet.UsedRange;
var count = range.Count;
It's a problem othersalready got.
Source : Interop Excel UsedRange Rows Count incorrect

excel cell coloring

I am using c# to color particular cells of excel file.
I am using:
Application excel = new Application();
Workbook wb = excel.Workbooks.Open(destPath);
Worksheet ws = wb.Worksheets[1];
ws.get_Range(ws.Cells[row, clmn]).Cells.Interior.Color = 36;
...to color cells, but this is not working.
Can anyone help me out?
Try something like that
ws.Cells[row, clmn].Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.Red)
Cells[row, clmn] is a range so you don't need to call get_Range() and there is a enum that you can use for colors.
ws.Cells[row, clmn].Interior.Color = XlRgbColor.rgbBlack;
If you want to set color by color index, you need to use this method:
Cells[row, col].Interior.ColorIndex = 36;
You can color a cell or a entire column or entire row.
The below code will help you out.
xlWorkSheet.get_Range(xlWorkSheet.Cells[2, 2], xlWorkSheet.Cells[2, 4]).Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.Green);
else
xlWorkSheet.get_Range(xlWorkSheet.Cells[2, 3], xlWorkSheet.Cells[2, 3]).Interior.Color = Excel.XlRgbColor.rgbRed;
Here xlWorksheet is the object excel Worksheet object.
get_Range takes 2 variable one start cell and other is end cell.
so if you specify both the values same then only one cell is colored.
xlWorkSheet.cells[row, column] is used to specify a cell.
System.Drawing.ColorTranslator.ToOle(SystemDrawing.Color.Green) is used to define the color in OLE format.
Excel.XlRgbColor.rgbRed is a excel way of coloring the cells
This method gives access to large number of colors which can be found here list of colors
The below code is the way i defined the excel worksheet.
Excel.Workbook xlWorkBook;
Excel.Worksheet xlWorkSheet;
Excel.Range xlwidthadjust; //used this to adjust width of columns
object misValue = System.Reflection.Missing.Value;
xlWorkBook = xlApp.Workbooks.Add(misValue);
xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1);
with this code i am sure that you wont get this exception Exception from HRESULT: 0x800A03EC
Make sure you are using:
using Excel = Microsoft.Office.Interop.Excel;
If you have a variable for the range you want to change, then use:
chartRange = xlWorkSheet.get_Range("a5", "a8");
chartRange.Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.Black);
If you want to just change the color of a specific cell, then use:
xlWorkSheet.Cells[row, col].Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.Black);
...where 'row' is the row number, and 'col' is the column number assigned to the given lettered columns (starting at 1).
Exception from HRESULT: 0x800A03EC
Solution: Change the misValue to sheet1, sheet2 or sheet3.
xlWorkBook = xlApp.Workbooks.Add("sheet1");
This works for me. system.reflaction.missing.value what was that, it is not related to Excel.workbooks.add came from a Excel file default value.
When you create a Excel file, the default worksheets are sheet1, sheet2 and sheet3.

Format an Excel column (or cell) as Text in C#?

I am losing the leading zeros when I copy values from a datatable to an Excel sheet. That's because probably Excel treats the values as a number instead of text.
I am copying the values like so:
myWorksheet.Cells[i + 2, j] = dtCustomers.Rows[i][j - 1].ToString();
How do I format a whole column or each cell as Text?
A related question, how to cast myWorksheet.Cells[i + 2, j] to show a style property in Intellisense?
Below is some code to format columns A and C as text in SpreadsheetGear for .NET which has an API which is similar to Excel - except for the fact that SpreadsheetGear is frequently more strongly typed. It should not be too hard to figure out how to convert this to work with Excel / COM:
IWorkbook workbook = Factory.GetWorkbook();
IRange cells = workbook.Worksheets[0].Cells;
// Format column A as text.
cells["A:A"].NumberFormat = "#";
// Set A2 to text with a leading '0'.
cells["A2"].Value = "01234567890123456789";
// Format column C as text (SpreadsheetGear uses 0 based indexes - Excel uses 1 based indexes).
cells[0, 2].EntireColumn.NumberFormat = "#";
// Set C3 to text with a leading '0'.
cells[2, 2].Value = "01234567890123456789";
workbook.SaveAs(#"c:\tmp\TextFormat.xlsx", FileFormat.OpenXMLWorkbook);
Disclaimer: I own SpreadsheetGear LLC
If you set the cell formatting to Text prior to adding a numeric value with a leading zero, the leading zero is retained without having to skew results by adding an apostrophe. If you try and manually add a leading zero value to a default sheet in Excel and then convert it to text, the leading zero is removed. If you convert the cell to Text first, then add your value, it is fine. Same principle applies when doing it programatically.
// Pull in all the cells of the worksheet
Range cells = xlWorkBook.Worksheets[1].Cells;
// set each cell's format to Text
cells.NumberFormat = "#";
// reset horizontal alignment to the right
cells.HorizontalAlignment = XlHAlign.xlHAlignRight;
// now add values to the worksheet
for (i = 0; i <= dataGridView1.RowCount - 1; i++)
{
for (j = 0; j <= dataGridView1.ColumnCount - 1; j++)
{
DataGridViewCell cell = dataGridView1[j, i];
xlWorkSheet.Cells[i + 1, j + 1] = cell.Value.ToString();
}
}
Solution that worked for me for Excel Interop:
myWorksheet.Columns[j].NumberFormat = "#"; // column as a text
myWorksheet.Cells[i + 2, j].NumberFormat = "#"; // cell as a text
This code should run before putting data to Excel. Column and row numbers are 1-based.
A bit more details. Whereas accepted response with reference for SpreadsheetGear looks almost correct, I had two concerns about it:
I am not using SpreadsheetGear. I was interested in regular Excel
communication thru Excel interop without any 3rdparty libraries,
I was searching for the way to format column by number, not using
ranges like "A:A".
Before your write to Excel need to change the format:
xlApp = New Excel.Application
xlWorkSheet = xlWorkBook.Sheets("Sheet1")
Dim cells As Excel.Range = xlWorkSheet.Cells
'set each cell's format to Text
cells.NumberFormat = "#"
'reset horizontal alignment to the right
cells.HorizontalAlignment = Excel.XlHAlign.xlHAlignRight
I've recently battled with this problem as well, and I've learned two things about the above suggestions.
Setting the numberFormatting to # causes Excel to left-align the value, and read it as if it were text, however, it still truncates the leading zero.
Adding an apostrophe at the beginning results in Excel treating it as text and retains the zero, and then applies the default text format, solving both problems.
The misleading aspect of this is that you now have a different value in the cell. Fortuately, when you copy/paste or export to CSV, the apostrophe is not included.
Conclusion: use the apostrophe, not the numberFormatting in order to retain the leading zeros.
Use your WorkSheet.Columns.NumberFormat, and set it to string "#", here is the sample:
Excel._Worksheet workSheet = (Excel._Worksheet)_Excel.Worksheets.Add();
//set columns format to text format
workSheet.Columns.NumberFormat = "#";
Note: this text format will apply for your hole excel sheet!
If you want a particular column to apply the text format, for example, the first column, you can do this:
workSheet.Columns[0].NumberFormat = "#";
or this will apply the specified range of woorkSheet to text format:
workSheet.get_Range("A1", "D1").NumberFormat = "#";
if (dtCustomers.Columns[j - 1].DataType != typeof(decimal) && dtCustomers.Columns[j - 1].DataType != typeof(int))
{
myWorksheet.Cells[i + 2, j].NumberFormat = "#";
}
I know this question is aged, still, I would like to contribute.
Applying Range.NumberFormat = "#" just partially solve the problem:
Yes, if you place the focus on a cell of the range, you will read text in the format menu
Yes, it align the data to the left
But if you use the type formula to check the type of the value in the cell, it will return 1 meaning number
Applying the apostroph behave better. It sets the format to text, it align data to left and if you check the format of the value in the cell using the type formula, it will return 2 meaning text
//where [1] - column number which you want to make text
ExcelWorksheet.Columns[1].NumberFormat = "#";
//If you want to format a particular column in all sheets in a workbook - use below code. Remove loop for single sheet along with slight changes.
//path were excel file is kept
string ResultsFilePath = #"C:\\Users\\krakhil\\Desktop\\TGUW EXCEL\\TEST";
Excel.Application ExcelApp = new Excel.Application();
Excel.Workbook ExcelWorkbook = ExcelApp.Workbooks.Open(ResultsFilePath);
ExcelApp.Visible = true;
//Looping through all available sheets
foreach (Excel.Worksheet ExcelWorksheet in ExcelWorkbook.Sheets)
{
//Selecting the worksheet where we want to perform action
ExcelWorksheet.Select(Type.Missing);
ExcelWorksheet.Columns[1].NumberFormat = "#";
}
//saving excel file using Interop
ExcelWorkbook.Save();
//closing file and releasing resources
ExcelWorkbook.Close(Type.Missing, Type.Missing, Type.Missing);
Marshal.FinalReleaseComObject(ExcelWorkbook);
ExcelApp.Quit();
Marshal.FinalReleaseComObject(ExcelApp);
You need to format the column to be a string.
You can use the link https://supportcenter.devexpress.com/ticket/details/t679279/import-from-excel-to-gridview
For converting the ExcelDataSource, you can also refer to https://supportcenter.devexpress.com/ticket/details/t468253/how-to-convert-exceldatasource-to-datatable

Categories

Resources