I am performing search within excel workbook using small c# application.
now, when match found I am trying to get the full row details and the bounded into datagridview as shown below, but my problem is that
get_Address(true, true, Excel.XlReferenceStyle.xlR1C1, missing, missing)
is not show in correct format within the select statement
SELECT * FROM [Sheet1$B14:I24] //correct format
SELECT * FROM [sheet$B952]
so I am getting error message says
The Microsoft Access database engine could not find the object
'sheet$B952'. Make sure the object exists and that you spell its name
and the path name correctly. If 'sheet$B952' is not a local object,
check your network connection or contact the server administrator.
I tried to use get_AddressLocal or the xlA1 style but that is wont help me
to get the correct format
please if anyone can help or provide me with better solution or scenario
Thank alot
private void B_General_Search_Click(object sender, EventArgs e)
{
Microsoft.Office.Interop.Excel.Application oXL = new Microsoft.Office.Interop.Excel.Application();
Microsoft.Office.Interop.Excel.Workbook oWB;
Microsoft.Office.Interop.Excel.Range currentFind = null;
Microsoft.Office.Interop.Excel.Range firstFind = null;
string ConnStr = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + DefaultDirectory + #"\new29.xlsx" + ";Extended Properties=\"Excel 12.0 Xml;HDR=YES\";";
Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
if (string.IsNullOrEmpty(TB_Search_Text.Text))
{
MessageBox.Show("enter text for search");
return;
}
object missing = System.Reflection.Missing.Value;
oWB = oXL.Workbooks.Open(DefaultDirectory + #"\new29.xlsx", //---Filename OR FilePath
0, //---object UpdateLinks
true, //---object ReadOnly
missing, //5//---object Format
"", //---object Password
"", //---object WriteResPassword
false, //---object ReadOnlyRecommend
Excel.XlPlatform.xlWindows, //---object Origin
"", //---object Delimiter
true, //---object Editable
false, //---object Notify
0, //---object Converter
true, //---object AddToMru
false, //---object Local
false); //---object CorruptLoad;
//loop to search witin all excel sheets (workbook)
foreach (Excel.Worksheet SheetID in oWB.Worksheets)
{
Excel.Range oRng = oXL.get_Range("A1", "XFD1048576");
currentFind = oRng.Find(TB_Search_Text.Text,
missing,
Excel.XlFindLookIn.xlValues,
Excel.XlLookAt.xlPart,
Excel.XlSearchOrder.xlByRows,
Excel.XlSearchDirection.xlNext,
false,
missing,
missing);
while (currentFind != null)
{
//Keep track of the first range you find.
if (firstFind == null)
{
firstFind = currentFind;
}
else if (currentFind.get_Address(true, true, Excel.XlReferenceStyle.xlR1C1, missing, missing) == firstFind.get_Address(true, true, Excel.XlReferenceStyle.xlR1C1, missing, missing))
{
break;
}
//currentFind.Font.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.Red);
//currentFind.Font.Bold = true;
currentFind = oRng.FindNext(currentFind);
//SELECT * FROM [Sheet1$B14:I24] correct format
//SELECT * FROM [sheet$B952] XXXXX
string cmdtxt = #"select * from [" + SheetID.Name + "$" + currentFind.get_Address(true, true, Excel.XlReferenceStyle.xlR1C1, missing, missing) + "]";
MessageBox.Show(cmdtxt);
using (OleDbConnection conn = new OleDbConnection(ConnStr))
{
OleDbDataAdapter DA = new OleDbDataAdapter(cmdtxt, conn);
DA.Fill(dt);
DGV_Data.DataSource = dt;
conn.Close();
}
}
}
oWB.Close(false, missing, missing);
//oSheet = null;
oWB = null;
oXL.Quit();
}
Related
I have the below code which works to delete the first row of a specified excel workbook. After this is done I would like to save (Overwrite changes) and exit the excel applications.
I gathered this may be achieved by Workbook.Close(True) but the popups still occur and the Object workbook is not referenced.
Any help would be much appreciated.
public void DeleteRows(string workbookPath)
{
// New Excel Application
Microsoft.Office.Interop.Excel.Application excelApp = new Microsoft.Office.Interop.Excel.Application();
//Open WorkBook
Microsoft.Office.Interop.Excel.Workbook excelWorkbook = excelApp.Workbooks.Open(workbookPath,
0, false, 5, "", "", false, Microsoft.Office.Interop.Excel.XlPlatform.xlWindows, "",
true, false, 0, true, false, false);
Microsoft.Office.Interop.Excel.Sheets excelSheets = excelWorkbook.Worksheets;
string currentSheet = "Sheet1";
Microsoft.Office.Interop.Excel.Worksheet excelWorksheet = (Microsoft.Office.Interop.Excel.Worksheet)excelSheets.get_Item(currentSheet);
Microsoft.Office.Interop.Excel.Range excelCell = (Microsoft.Office.Interop.Excel.Range)excelWorksheet.get_Range("A1", "A1");
Microsoft.Office.Interop.Excel.Range row = excelCell.EntireRow;
row.Delete(Microsoft.Office.Interop.Excel.XlDirection.xlUp);
}
Honestly, all I think that's missing from your code is a save and close. Once you save, the warning should not be issued.
using Excelx = Microsoft.Office.Interop.Excel;
public void DeleteRows(string workbookPath)
{
// New Excel Application
Excelx.Application excelApp = new Excelx.Application();
//Open WorkBook
Excelx.Workbook excelWorkbook = excelApp.Workbooks.Open(workbookPath,
0, false, 5, "", "", false, Excelx.XlPlatform.xlWindows, "",
true, false, 0, true, false, false);
Excelx.Sheets excelSheets = excelWorkbook.Worksheets;
string currentSheet = "Sheet1";
Excelx.Worksheet excelWorksheet = (Excelx.Worksheet)excelSheets.get_Item(currentSheet);
Excelx.Range excelCell = (Excelx.Range)excelWorksheet.get_Range("A1", "A1");
Excelx.Range row = excelCell.EntireRow;
row.Delete(Excelx.XlDirection.xlUp);
// This should be all you need:
excelWorkbook.Save();
excelWorkbook.Close();
}
I'd be puzzled if this doesn't work, but if it doesn't, it might help when you are debugging to make Excel visible and step through the code:
excelApp.Visible = true;
As a final last attempt, before you save, you can disable warnings which will tell Excel to dispense with any of the dialogs to try to save you from yourself:
excelApp.DisplayAlerts = false;
excelWorkbook.Save();
excelWorkbook.Close();
excelApp.DisplayAlerts = true;
And again, I think you shouldn't even get to step 2 for this to work, but let me know if it doesn't. We would have quite a puzzle.
I have an excel sheet containing single column and multiple rows like:
000500114673HY340216-00 CT TAPING WORK DTYPE-OSKF 245 TWB.T H/C 37990110000250000100
I am trying to create a new Excel file through my C# code, but not getting the desired result. In my new Excel file I need six columns with each column assigned a particular range, say for first column 12, for second 20 and so on (spaces also included). I used the text to column method, but I'm not able to parse it to fixed width. My code sample is:
xlAppNew = new Application();
xlAppNew.DisplayAlerts = true;
workbooks = xlAppNew.Workbooks;
workbook = workbooks.Open(#filepath, 0, true, 1, "", "", true,
Microsoft.Office.Interop.Excel.XlPlatform.xlWindows, "\t",
false, false, 0, true, 1, 0);
xlWorkSheet = (Microsoft.Office.Interop.Excel.Worksheet)workbook.Worksheets.get_Item(1);
((Range)xlAppNew.Cells[1, 1]).EntireColumn.TextToColumns(Type.Missing,
Microsoft.Office.Interop.Excel.XlTextParsingType.xlFixedWidth,
Microsoft.Office.Interop.Excel.XlTextQualifier.xlTextQualifierNone,
Type.Missing, Type.Missing, Type.Missing, true, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing);
I think the problem lies with the fourth last parameter, the fieldinfo object which I am not able to provide properly, I also used the array object, but it produced error. I took help from this question 4945621. But the exact solution is not provided there.
Actually what I had to do was first convert a DAT file to Excel and then divide it into fixed number of columns through my C# code. So in my first step what I did was converted the DAT file into an Excel file having a single column and given number of rows as my temporary Excel file.
xlAppNew1 = new Application();
xlAppNew1.DisplayAlerts = true;
workbooks1 = xlAppNew1.Workbooks;
workbook1 = workbooks1.Open(#filepath, 0, true, 1, "", "", true, Microsoft.Office.Interop.Excel.XlPlatform.xlWindows, "\t", false, false, 0, true, 1, 0);
xlAppNew1.ActiveWorkbook.SaveAs(#filepathNew, -4143, "", "", false, false, Microsoft.Office.Interop.Excel.XlSaveAsAccessMode.xlNoChange,
missing, missing, missing, missing, missing);
Now make sure to close all the instances of the COM object that you have created otherwise it will create hell lot of a problem.Secondly in another function I opened my temporary Excel file, and all the data in a Dataset and then with the help of Range object and the following method:
range = range.get_Resize(range.Rows.Count, 9);
string[,] saRet = new string[range.Rows.Count, 9];
range.set_Value(Missing.Value, saRet);
The whole code goes something loke this:
xlAppNew = new Application();
xlAppNew.DisplayAlerts = true;
workbooks = xlAppNew.Workbooks;
workbook = workbooks.Open(#filepathnew, 0, true, 1, "", "", true, Microsoft.Office.Interop.Excel.XlPlatform.xlWindows, "\t", false, false, 0, true, 1, 0);
xlWorkSheet = (Microsoft.Office.Interop.Excel.Worksheet)workbook.Worksheets.get_Item(1);
if (getExtension.ToLower() == ".xls")
connString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + filepath_second + ";Extended Properties=\"Excel 8.0;HDR=YES;IMEX=1;\"";
else
connString = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + filepath_second + ";Extended Properties=Excel 12.0 Xml;HDR=Yes;IMEX=1;";
OleDbConnection con = new OleDbConnection(connString);
con.Open();
System.Data.DataTable dtSheet = con.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
string tname = dtSheet.Rows[0]["TABLE_NAME"].ToString();
OleDbDataAdapter ad = new OleDbDataAdapter(#"Select * FROM [" + tname + "];", con);
DataSet dset = new DataSet();
ad.Fill(dset);
range = xlWorkSheet.UsedRange;
range = range.get_Resize(range.Rows.Count, 9);
//Create an array.
string[,] saRet = new string[range.Rows.Count, 9];
//Fill the array.
for (int iRow = 0; iRow < range.Rows.Count - 1; iRow++)
{
for (int iCol = 0; iCol < 9; iCol++)
{
switch (iCol)
{
case 0:
saRet[iRow, iCol] = dset.Tables[0].Rows[iRow][0].ToString().Substring(3, 9);//iRow.ToString() + "|" + iCol.ToString();
break;
case 1:
saRet[iRow, iCol] = dset.Tables[0].Rows[iRow][0].ToString().Substring(12, 4);
break;
case 2:
saRet[iRow, iCol] = dset.Tables[0].Rows[iRow][0].ToString().Substring(16, 18);
break;
case 3:
saRet[iRow, iCol] = dset.Tables[0].Rows[iRow][0].ToString().Substring(34, 8);
break;
case 4:
saRet[iRow, iCol] = dset.Tables[0].Rows[iRow][0].ToString().Substring(42, 4);
break;
case 5:
saRet[iRow, iCol] = dset.Tables[0].Rows[iRow][0].ToString().Substring(46, 18);
break;
case 6:
saRet[iRow, iCol] = dset.Tables[0].Rows[iRow][0].ToString().Substring(64, 40);
break;
case 7:
saRet[iRow, iCol] = dset.Tables[0].Rows[iRow][0].ToString().Substring(104, 3);
break;
case 8:
saRet[iRow, iCol] = dset.Tables[0].Rows[iRow][0].ToString().Substring(107, 5);
break;
}
}
}
//Set the range value to the array.
range.set_Value(Missing.Value, saRet);
FieldInfo myf = typeof(MyNewService).GetField("saRet");//Fieldinfo object is also an important part
//**********************
((Range)xlAppNew.Cells[1, 1]).EntireColumn.TextToColumns(Type.Missing, Microsoft.Office.Interop.Excel.XlTextParsingType.xlFixedWidth, Microsoft.Office.Interop.Excel.XlTextQualifier.xlTextQualifierNone, Type.Missing, Type.Missing, Type.Missing, true, Type.Missing, Type.Missing, Type.Missing, myf, Type.Missing, Type.Missing, Type.Missing);
xlAppNew.ActiveWorkbook.SaveAs(#temp_path, -4143, "", "", false, false, Microsoft.Office.Interop.Excel.XlSaveAsAccessMode.xlNoChange, missing, missing, missing, missing, missing);
Hope it helps others to save their time.Thank You.
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;
The whole app works fine, when merging single tabbed workbooks. But then I added functionality to also merge all worksheets in a book, before merging the book with another.
It merges them (tested on a single multitabbed wbook), but at some point starts to mess it up.
For example
outcome:
sheet1
-empty lines- sheet2
-empty lines- sheet3+ half of sheet4
-empty lines- sheet2 again not all, with some values missing
etc...
Im not sure if is the code that needs something extra, or problems in certain worksheets.
Heres the crucial parts:
for (int i = 0; i < pathList.Count; i++)
{
List<string> Sheet = GetSheetName(path);
filename = GetFileName(path);
MyConnection = new System.Data.OleDb.OleDbConnection("provider=Microsoft.Jet.OLEDB.4.0;Data Source='" + path + "';Extended Properties='Excel 8.0;IMEX=1;'");
foreach (string SheetName in Sheet)
{
//OLEDB SECTION ***********************************************
MyCommand = new System.Data.OleDb.OleDbDataAdapter("select * from [" + SheetName + "$]", MyConnection);
MyCommand.TableMappings.Add(pathList.Count.ToString(), filename);
MyCommand.Fill(table);
lstTable.Add(table);
MyConnection.Close();
MyCommand.Dispose();
//*************************************************************
}
}
and the getSheetNames
List<string> GetSheetName(string path)
{
Microsoft.Office.Interop.Excel.Application xlApp;
Microsoft.Office.Interop.Excel.Workbook xlWorkBook;
Microsoft.Office.Interop.Excel.Worksheet xlWorkSheet;
List<string> names = new List<string>();
xlApp = new Microsoft.Office.Interop.Excel.Application();
xlWorkBook = xlApp.Workbooks.Open(path, 0, true, 5, "", "", true, Microsoft.Office.Interop.Excel.XlPlatform.xlWindows, "\t", false, false, 0, true, 1, 0);
foreach (Microsoft.Office.Interop.Excel.Worksheet i in xlWorkBook.Worksheets)
if (i.UsedRange.Count > 0)
names.Add(i.Name);
return names ;
}
I'm gonna make a project to convert data and chart to powerpoint file to excel file.
but I found some problem here,,
I have make a project to convert chart, with this script
public static void GetChart(string strFilePath, string strDestPath)
{
xl.Application xlApp;
xl.Workbook xlWorkBook;
xl.Worksheet xlWorkSheet;
object misValue = System.Reflection.Missing.Value;
xlApp = new xl.ApplicationClass();
xlWorkBook = xlApp.Workbooks.Open(strFilePath, 0, true, 5,
"", "", true,
Microsoft.Office.Interop.Excel.XlPlatform.xlWindows,
"\t", false, false, 0, true, 1, 0);
xlWorkSheet =
(xl.Worksheet)xlWorkBook.Worksheets.get_Item(1);
xl.ChartObjects xlCharts =
(xl.ChartObjects)xlWorkSheet.ChartObjects(Type.Missing);
xl.ChartObject myChart = (xl.ChartObject)xlCharts.Item(1);
xl.Chart chartPage = myChart.Chart;
and then I convert it into an image with this script
GetChart(#"" + textBox1.Text + "", #"d:\" + textBox2.Text + ".jpeg");
label5.Text = #"D:\" + textBox2.Text + ".jpeg";
pictureBox1.Image = new Bitmap(#"" + label5.Text +
"");
but I think not all of excel file contains a chart, so I try to search a validation about how to detect a chart in every excel file.
How should I do ?
Try checking the number of items in the charts collection, ie xlCharts.Count