How do I get specific text from excel worksheet using C#? - c#

I'm wanting to find multiple cells where a string is present. So usually a cell will have a int and the next cell will have a string. Is there anyway to find the string and print the value(int) to the console. So column A would have int and column B would be string. If the int doesn't have a string then it doesn't get printed. I've tried a couple methods on here but can't find what I'm looking for.
string fileExcel = #"C:\test.xlsx";
Application x1Application = new Application();
Workbook x1Workbook = x1Application.Workbooks.Open(fileExcel);
Worksheet x1Worksheet = x1Workbook.ActiveSheet;
var x1Range = (Excel.Range)x1Worksheet.Columns["A:B"];

Office interop isn't the most intuitive API, so you will need to be able to experiment quickly in a test environment to see what works and what doesn't work. Also, there are a lot of examples on MSDN for Office interop, and you will likely need to browse many examples to piece things together. The code below is mostly taken from How to: Programmatically Search for Text in Worksheet Ranges
In the test.xlsx file I have the following data
A
B
1
alpha
2
bravo
3
charlie
string fileExcel = #"C:\test.xlsx";
var application = new Excel.Application();
var workbook = application.Workbooks.Open(fileExcel);
var worksheet = workbook.ActiveSheet;
var range = (Excel.Range)worksheet.Columns["B:B"];
var foundRange = range.Find("bravo",
Type.Missing,
Excel.XlFindLookIn.xlValues,
Excel.XlLookAt.xlPart,
Excel.XlSearchOrder.xlByRows,
Excel.XlSearchDirection.xlNext,
false,
Type.Missing,
Type.Missing);
if (foundRange != null)
{
var numberRange = application.get_Range($"A{foundRange.Row}");
Console.WriteLine(foundRange.Value);
Console.WriteLine(numberRange.Value);
}
The above code should print
bravo
2
Also note, that the above code is very bare bones just to help you get started. One of the reasons that the Office interop is difficult to work with is because things are so dynamic. Likely you will need a lot more null checks and type safety checks to make sure things are stable.

Related

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

Reading data from Excel file in c#

Hi I have an excel file settings.xlsx. I want to read the data from this file and assign the variables used in my code with the data.
example
Column1 Column2
Row1 Data 500
Row2 Address 30
Row3 Value FPGA
I have Data,Address and Value as variables in my code.
Can someone assist me with a pseudocode of c# to open a file and read the contents from it as per my requirement?
I want to search "Data" word in the excel file and take the value next to the cell containing "Data" and assign it to the variable "Data". I know it is confusing but I really want the final data to look like something below.
Data=500 //Finally I want my variables to have the data as follows
Address=30
Value= FPGA
I tried opening a file in my code.But since I am new to c#,i am not able to understand what is going wrong in my code.
I am stuck at this point. Open function is giving an error. Kindly help me. I tried to open the excel file in my c# code. But somehow it is saying Open function overload method doesn't take one argument. How to open and read the file?
string Filepath = #Filename;
Excel.Application excelapp = new Excel.Application();
excelapp.Visible = true;
var MyBook = excelapp.Workbooks.Open(Filepath);
It will be really helpful if somone gives a pseudocode for the same.
Hi,
I was able to open the file.
string Filepath = Path.Combine(Directory.GetCurrentDirectory(), Filename);
Excel.Application excelapp = new Excel.Application();
excelapp.Visible = true;
var Workbook = excelapp.Workbooks.Open(Filepath, 0, false, 5, "", "", true, Microsoft.Office.Interop.Excel.XlPlatform.xlWindows, "\t", false, false, 0,true,1, 0);
var xlWorkSheet = (Excel.Worksheet)Workbook.Worksheets.get_Item(2);
Excel.Range range = xlWorkSheet.UsedRange;
But when I try to store the cell value in my variable, it gives me an error. I somehow cannot use Cells.value. I tried using the following but not able to store the data. Can anybody help?
uint pbaudRate2 = Convert.ToUInt32(range.Value2.ToString());
If you can make a slight change in your excel file, there is a much easier way to read the data. You need to have Column names in the first row (any names will do e.g. "ColumnName", "ColumnValue"), and data in subsequent rows. Then you can use code like this:
string xlConnStr = #"Provider=Microsoft.ACE.OLEDB.12.0; Data Source=yourfullfilepathandname.xlsx;Extended Properties='Excel 8.0;HDR=Yes;';";
var xlConn = new OleDbConnection(xlConnStr);
var da = new OleDbDataAdapter("SELECT * FROM [Sheet1$]", xlConn);
var xlDT = new DataTable();
da.Fill(xlDT);
You will now be able to access the values from the DataTable. In your case: xlDT.Rows[1][1] will hold the value of address (in this case 30). One thing to note: numbers in an Excel spreadsheet need to be retrieved as doubles and then cast if you want something else:
int myAddress = (int)(double)xlDT.Rows[1][1];
Here is a small demo how to read a range of Excel cells
// cf. http://support.microsoft.com/kb/302084/en-us
Excel.Application XL = new Microsoft.Office.Interop.Excel.Application();
Excel._Workbook WB = XL.Workbooks.Open(fileName, ReadOnly: true);
Excel._Worksheet WS = (Excel._Worksheet)WB.Sheets[sheetName];
Excel.Range R = WS.get_Range(GetAddress(row1, col1), GetAddress(row2, col2));
object[,] arr = (object[,])R.Value;
....
private string GetAddress(int rowNumber, int columnNumber)
{
int dividend = columnNumber;
string columnName = String.Empty;
int modulo;
while (dividend > 0)
{
modulo = (dividend - 1) % 26;
columnName = Convert.ToChar(65 + modulo).ToString() + columnName;
dividend = (int)((dividend - modulo) / 26);
}
return columnName + rowNumber;
}
The cell values are copied to a 2D array of objects. Further processing depends on the value types.
Note that the transfer of an array is much faster than a nested loop of single cell copy operations.

Excel auto filter

I have a problem while filtering the Excel column by year. I tried the below code but didn't get any success, could anybody help me or offer some suggestions on how I can find the year in excel filters.
For example, if I enter '12/30/2016', it will search successfully but I would like to search by year (e.g. '2016').
Excel.Range range = WorksheetSource.UsedRange;
range.AutoFilter(29, tByear.Text, XlAutoFilterOperator.xlFilterValues,test4[0,0], true);
range.AutoFilter(29, tByear.Text, Excel.XlAutoFilterOperator.xlOr, tByear.Text+ "*", true);
try this
Excel.Range currentFind = null;
xlworkSheet.Cells.Find(date,Type.Missing,Microsoft.Office.Interop.Excel.XlFindLookIn.xlValues,Microsoft.Office.Interop.Excel.XlLookAt.xlWhole,Microsoft.Office.Interop.Excel.XlSearchOrder.xlByRows,Microsoft.Office.Interop.Excel.XlSearchDirection.xlNext, false,Type.Missing, Type.Missing)

Create and set styles in Excel cells using C#?

How to create and set styles in Excel cells using C#?
I want to write something like "April 1st" with st as a superscript.
I would be using a string format not a date format.
I have tried http://msdn.microsoft.com/en-us/library/f1hh9fza.aspx but getting an The name 'Globals' does not exist in the current context error. I have added assembly Microsoft.Office.Interlop.Excel. Am I missing any other assembly?
Excel.Style style = Globals.ThisWorkbook.Styles.Add("NewStyle");
You actually don't want to change the font of the whole cell but you to change a portion of the text in the cell I take it.
You'll still need to retrieve the cell range and then adjust the characters within that range. here is an example where it's just adjusting the first cell. A1.
If you wanted to change the whole cell range to be superscript it would be done like this
currentRange.Font.Superscript = true;
void Main()
{
var app = new Application();
app.Visible = true;
var workbook = app.Workbooks.Add(1);
Sheets excelSheets = workbook.Worksheets;
string currentSheet = "Sheet1";
Worksheet worksheet1 = (Worksheet)excelSheets.get_Item(currentSheet);
worksheet1.Cells[1, 1] = "April 1st";
worksheet1.Cells[1, 2] = "April 2nd";
worksheet1.Cells[1, 3] = "April 3rd";
worksheet1.Cells[1, 4] = "April 4th";
// fill in the starting and ending range programmatically this is just an example.
string startRange = "A1";
string endRange = "A1";
Range currentRange = worksheet1.get_Range(startRange , endRange );
var text = currentRange.Text.ToString();
int length = text.Length;
int index = 0;
if(text.Contains("st"))
{
index =text.IndexOf("st");
}
//The other checks for "nd", "rd", "th" obviously check to see a # precedes these.
if(index > 0)
{
currentRange.get_Characters( index+1, 2).Font.Superscript = true;
}
}
As the MSDN article you've linked to states:
Applies to: The information in this topic applies to document-level
projects and application-level projects for Office 2013 and Office
2010. See Features Available by Office Application and Project Type.
To use Globals class you have to create Office project. For another reference you can check this question about creating Office add-in:
Globals.ThisAddin.Application can be only used in VSTO Add-In

Accessing Excel cells by name instead of "coordinates" like A1

I have an Excel Sheet where I've named the cells I have to fill from my code.
The reason for the named fields is that the customer has the possibility to re-arrange the cells.
To make it a little clearer: I used the field shown below to name the cells.
My problem is now that I have no idea how to address these fields from C# using office interop.
Range r = Sheet.get_Range("M_Leitung", Type.Missing);
doesn't work. Since I don't have any ranges defined, just single cells where I have to insert the values, I'd need a function that returns the named cell.
I just simulated your scenario and the following code worked like a charm (where I labeled A1 in sheet2 as M_Leitung):
Edit: updated code - When you have multiple sheets, you need to refer the names at workbook scope which will return fully qualified address (and hence the resulting range knows which sheet to pick the address from)
private static void Main(string[] args)
{
string FileName = Path.Combine(Path.GetDirectoryName(System.Windows.Forms.Application.ExecutablePath), "Book2.xlsx");
Application excelApp = new Application();
Workbooks excelWorkbooks = excelApp.Workbooks;
Workbook report = excelWorkbooks.Open(FileName, 0, false, 5, "", "", true, XlPlatform.xlWindows, "", true, false, 0, false, false, false);
var y = report.Names.Item("M_Leitung").RefersToRange.Value;
Console.WriteLine(y);
excelWorkbooks.Close();
excelApp.Quit();
}
Note that you do create a named range automatically when you rename a cell. If you created a range of say A1:B1 and you selected that. Excel would show you the named range in that corner label rather than the addresses which proves it works both ways.
HTH
Defined Names in Excel have scope, either Workbook or Sheet (ie Global or Local). Typing them in like you've done creates them as Workbook scope. Use the Name Manager to check scope.
Use the Names & RefersToRange properties, not Range to access them. The syntax is slightly different:
Workbook scope: Workbook.Names("M_Leitung").RefersToRange.Value
Worksheet scope: Workbook.Sheet.Names("M_Leitung").RefersToRange.Value
The reason for this is so you can create the same Name on different sheets.
Excel.Application app = new Excel.ApplicationClass();
Excel.Workbook book = app.Workbooks.Open(Filename: System.IO.Path.Combine( Environment.CurrentDirectory, "Book1.xls"));
Excel.Name MyRange = book.Names.Item(Index:"MyRange");
Console.WriteLine(MyRange.RefersToRange.Value);
MyRange.RefersToRange.Value = "55";
book.Save();
app.Quit();
Above code open a file and get the value from workbook and update the range. I think this will solve the problem.

Categories

Resources