I'm new to C#. I have used the code below to read data from Excel, but I need help modifying it to read key-value pairs.
public String getData(int row, int col, String var)
{
Excel.Application excelApp = new Excel.Application();
if (excelApp != null)
{
List<string> prop = new List<string>(var.Split(new string[] {"."}, StringSplitOptions.None));
Excel.Workbook excelWorkbook = excelApp.Workbooks.Open(#"D:\\test.xlsx", 0, true, 5, "", "", true, Excel.XlPlatform.xlWindows, "\t", false, false, 0, true, 1, 0);
Excel.Worksheet excelWorksheet = (Excel.Worksheet)excelWorkbook.Sheets[prop[0]];
excelWorksheet.Select(Type.Missing);
Excel.Range range = (excelWorksheet.Cells[row, col] as Excel.Range);
string cellValue = range.Value.ToString();
excelWorkbook.Close();
excelApp.Quit();
return cellValue;
}
return null;
}
Here is an example; it assumes you have a using clause..
using Excel = Microsoft.Office.Interop.Excel;
..and prepared access to a worksheet:
Excel.Application xl = new Excel.Application();
xl.Workbooks.Open(filename);
Excel.Worksheet ws = xl.Workbooks[1].Worksheets[1]; // pick your sheet!
int keyColum = 3;
Now you can grab a Range of Cells:
Excel.Range keyRange= ws.Range["C3:C53"];
..or the whole column:
Excel.Range keyRange= ws.Range["C:C"];
And search all occurences of a search string:
Excel.Range keysFound = keyRange.Find(textBox1.Text);
Then you can access the range of found cells like this:
string msg1 = keysFound.Count + " records found.";
string msg2 = "1st in row " + keysFound.Row;
string msg3 = "value from next column is "
+ ws.Cells[keysFound.Row + 1, keyColum + 1].value;
notes:
indexing start with 0 in c# but not in excel (hence [keysFound.Row + 1, )
my value column is one column right of the keys. Best use named indices!
if nothing is found keysFound will be null! (do add a check!)
since you want to match a whole key, you will want to do an exact search:
Excel.Range keysFound = keyRange.Find(textBox1.Text, LookAt: Excel.XlLookAt.xlWhole);
I still think grabbing all data and stuffing them into a Dictionary will be the cleanest and fastest solution, unless, that is you only need to do one lookup..
Related
Hi I'd like to know how to highlight cells with same value in existing Excel file. My excel file contains more rows with names. I want highlight names what are equal as I use in textbox.
string workbookPath = #"PathOfExcelFile";
_Excel.Application ExcelApp = new _Excel.Application();
ExcelApp.Visible = true;
_Excel.Workbook workbook = ExcelApp.Workbooks.Open(workbookPath);
_Excel.Worksheet worksheet = workbook.ActiveSheet;
_Excel.Range selectRange;
selectRange = worksheet.get_Range(""); //
Thank you
This is my proposal to highlight cells :
//find last cell if needed
int lastCell = xlWorkSheet.Cells.Find(
"*",
System.Reflection.Missing.Value,
Excel.XlFindLookIn.xlValues,
Excel.XlLookAt.xlWhole,
Excel.XlSearchOrder.xlByRows,
Excel.XlSearchDirection.xlPrevious,
false,
System.Reflection.Missing.Value,
System.Reflection.Missing.Value).Row;
Excel.Range rangeCheck = xlWorkSheet.Range["A1:A" + lastCell];
foreach (Excel.Range cell in rangeCheck.Cells)
{
string checkStrigng = Convert.ToString(cell.Value);//converts cell value to string for comparision
if (checkString == textbox.Text)
{
cell.Interior.Color = System.Drawing.Color.Yellow;
}
}
I want to read the each cell value in excel file, But i am not able to get the cell values even after trying different examples in NET. I am not getting result with the following code, can any one get back on this. I am using .net framework 2.0
string filePath = "F:/BulkTest.xlsx";
Microsoft.Office.Interop.Excel.Application ExcelApp = new Microsoft.Office.Interop.Excel.Application();
ExcelApp.Visible = true;
Microsoft.Office.Interop.Excel.Workbook wb = ExcelApp.Workbooks.Open(filePath, Missing.Value,Missing.Value,Missing.Value,Missing.Value,Missing.Value,Missing.Value,Missing.Value,Missing.Value,Missing.Value,Missing.Value,Missing.Value,Missing.Value,Missing.Value,Missing.Value);
Microsoft.Office.Interop.Excel.Worksheet sh = (Microsoft.Office.Interop.Excel.Worksheet)wb.Sheets["Sheet1"];
Range excelRange = sh.UsedRange;
for (int i=2; i<= excelRange.Count + 1 ; i++)
{
string values = sh.Cells[i,2].ToString();
}
Till now i am trying to take cell values directly to variables, now i will try to take cell values to an array using Range. Thanks!!!! – Teja Varma 13 mins ago
No. I didn't even mean that :) As I mentioned in the comment that you can store the entire range in an array. That doesn't mean that you need to loop though each cell to store it in an array. You can directly assign the values of the range to the array. See this example.
xlRng = xlWorkSheet.get_Range("A1", "A20");
Object arr = xlRng.Value;
foreach (object s in (Array)arr)
{
MessageBox.Show(s.ToString());
}
The correct answer would be to use:
Sheet.Cells[row,col].Value.ToString();
C# code
Tested OK
string s = xlSheet.UsedRange.Cells[1, 7].Value.ToString();
//or
string d = xlSheet.UsedRange.Cells[1, "G"].Value.ToString();
Full Code
Excel.Application xlApp = new Excel.Application();
Excel.Workbook xlBook;
Excel.Worksheet xlSheet;
string Path = System.IO.Path.GetDirectoryName(Application.ExecutablePath);
xlBook = xlApp.Workbooks.Open(Path + "\\myfile.xlsx");
xlApp.Visible = true;
xlSheet = xlBook.ActiveSheet;
string s = xlSheet.UsedRange.Cells[1, 7].Value.ToString();
string d = xlSheet.UsedRange.Cells[1, "G"].Value.ToString();
xlBook.Close();
xlApp.Quit();
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlSheet);
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlBook);
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlApp);
I'm trying to read in the values of the first column into an array. What's the best way to do that? Below is the code I have so far. Basically I'm trying to get the range of data for that column so I can pull the cell values into a system array.
Microsoft.Office.Interop.Excel.Application xlsApp = new Microsoft.Office.Interop.Excel.Application();
if (xlsApp == null)
{
Console.WriteLine("EXCEL could not be started. Check that your office installation and project references are correct.");
return null;
}
//xlsApp.Visible = true;
Workbook wb = xlsApp.Workbooks.Open(filename, 0, true, 5, "", "", true, XlPlatform.xlWindows, "\t", false, false, 0, true);
Sheets sheets = wb.Worksheets;
Worksheet ws = (Worksheet)sheets.get_Item(1);
//***Breaks Here***
ListColumn column = ws.ListObjects[1].ListColumns[1];
Range range = column.DataBodyRange;
System.Array myvalues = (System.Array)range.Cells.Value;
Here is what I ended up using to get it to work. Once you know that Columns actually returns a range, storing it that way seems to compile and run fine. Here is the working method in my ExcelReader class. I plan to use this for test driven data on WebDriver.
public static string[] FirstColumn(string filename)
{
Microsoft.Office.Interop.Excel.Application xlsApp = new Microsoft.Office.Interop.Excel.Application();
if (xlsApp == null)
{
Console.WriteLine("EXCEL could not be started. Check that your office installation and project references are correct.");
return null;
}
//Displays Excel so you can see what is happening
//xlsApp.Visible = true;
Workbook wb = xlsApp.Workbooks.Open(filename,
0, true, 5, "", "", true, XlPlatform.xlWindows, "\t", false, false, 0, true);
Sheets sheets = wb.Worksheets;
Worksheet ws = (Worksheet)sheets.get_Item(1);
Range firstColumn = ws.UsedRange.Columns[1];
System.Array myvalues = (System.Array)firstColumn.Cells.Value;
string[] strArray = myvalues.OfType<object>().Select(o => o.ToString()).ToArray();
return strArray;
}
First, I'd work out how many rows are actually being used:
Excel.Range allCellsInColumn = xlWorksheet.Range["A:A"];
Excel.Range usedCells = allCellsInColumn.Find("*", Missing.Value, Missing.Value, Missing.Value,
Excel.XlSearchOrder.xlByRows, Excel.XlSearchDirection.xlPrevious, false, Missing.Value, Missing.Value);
Once you have that you can retrieve the values:
System.Array values = usedCells.Values;
Once you have the values in the array you can skip over the elements with nothing in them. I don't think there is a way of retrieving just the cells with something in them without looping through them one at a time, which is very time consuming in Interop.
Is your data in a list? Your code seems to be looking for an Excel List which may not be present. If not you can just get the entire first column (A:A) into a Range and get it's Value:
Range firstCol = ws.Range("A:A");
System.Array values = range.Value as System.Array;
public bool StoreInExecel(String name,String csFIleName)
{
int cellno = ;//Initialize to current row no
Microsoft.Office.Interop.Excel.Application excelApp = new Microsoft.Office.Interop.Excel.Application();
Microsoft.Office.Interop.Excel.Workbook workbook = (Microsoft.Office.Interop.Excel.Workbook)excelApp.Workbooks.Add(Missing.Value);
Worksheet worksheet;
// Opening excel file
workbook = excelApp.Workbooks.Open(fileName, 0, false, 5, "", "", true, XlPlatform.xlWindows, "\t", false, false, 0, true, 1, 0);
// Get first Worksheet
worksheet = (Microsoft.Office.Interop.Excel.Worksheet)workbook.Sheets.get_Item(1);
// Setting cell values
((Microsoft.Office.Interop.Excel.Range)worksheet.Cells[cellno,"B"]).Value2 = "5";
((Microsoft.Office.Interop.Excel.Range)worksheet.Cells[cellno,"B"]).Value2 = "7";
workbook.Save();
workbook.Close(0, 0, 0);
//excelApp.Quit();
return true;
}
I want to initialize "cellno" to current row index of excel file so that data should not get overridden. Is there any specific function to get filled row count?
You can use
Excel.Range range = (Excel.Range)excelApp.ActiveCell;
int cellno = range.Row;
You can also get the used range in a worksheet using the UsedRange property.
I am writing a program that will allow me to open excel spreadsheets and get some specific information off of them. Each sheet contains the same information that I need, but the information is not always in the same location.
I am trying to find a way to search for specific text in an Excel sheet and have the address of the cell that text is in.
For example:
If I was looking for the text "apples", the function will find the cell that contains apples and return its address (i.e., A5).
For accessing the Excel spreadsheet I am using Excel = Microsoft.Office.Interop.Excel.
I have been looking all weekend for an efficient way to to do this and have been horribly unsuccessful so far. Any help I can get would be greatly appreciated.
Edit:
This is part of a much larger project, but for this particular function, I have the ability to open and close the Excel file. I have yet to start writing the search function yet, because to be perfectly honest, I am not exactly sure on even how to go about doing this. But here is what I have at this point.
public string searchExcel(string findThis)
{
Excel.Application xlApp;
Excel.Workbook xlWorkBook;
Excel.WorkSheet xlWorkSheet;
object misvalue;
//This part will open the Excel document.
misValue = System.Reflection.Missing.Value;
xlApp = new Excel.ApplicationClass();
xlWorkBook = xlApp.Workbooks.Open("C:\\temp2\\excelDocument.xlsm",
0, true, 5, "", "", true, Microsoft.Office.Interop.Excel.XlPlatform.xlWindows,
"\t", false, false, 0, true, 1, 0);
//Search and get address of cell
//This part will close the Excel document
xlWorkBook.Close(true, misValue, misvalue);
xlApp.Quit();
releaseObject(xlWorkSheet);
releaseObject(xlWorkBook);
releaseObject(xlApp);
xlWorkSheet = null;
xlWorkBook = null;
xlApp = null;
}
private void releaseObject(object obj)
{
try
{
System.Runtime.Interopservices.Marshal.ReleaseComObject(obj);
obj = null;
}
catch(Exception e)
{
obj = null;
MessageBox.Show("Unable to release the object " + e.ToString());
}
finally
{
GC.Collect();
}
}
I think something like this should do what you want:
var app = (Excel.Application)Marshal.GetActiveObject("Excel.Application");
var wb = app.ActiveWorkbook;
var ws = wb.Worksheets[1] as Excel.Worksheet;
var cells = ws.Cells;
var match = cells.Find("apples", LookAt:=Excel.XlLookAt.xlPart) as Excel.Range;
var matchAdd = match != null ? match.Address : null;
This will search in the first Worksheet of the current active workbook of a current Excel session.
Adjusting to fit your code:
xlWorksheet = xlWorkBook.Worksheets[1] as Excel.Worksheet;
Excel.Range cells = ws.Cells;
Excel.Range match = cells.Find("apples", LookAt:=Excel.XlLookAt.xlPart) as Excel.Range;
string matchAdd = match != null ? match.Address : null;
if (match != null) releaseObject(match);
releaseObject(cells);
One thing, is this assumes .Net 4.0 as I use missing arguments for the find call. If you are using a previous version you will need to pass in misValue for any parameter not used.