Hello There,
I am trying to enter data from text to excel and save it under particular worksheet name. It works if there is only 1 worksheet but it doesn't work when I call same code again as it overwrites the excel file. I was wondering if I can copy data from text and add to worksheet. I have used clipboard method but it throws STA error. I repeat copy text file to worksheet again and again. Here is my code: help is appreciated.
a_Books.OpenText(reportloc + ".txt", Microsoft.Office.Interop.Excel.XlPlatform.xlWindows, 1,
Microsoft.Office.Interop.Excel.XlTextParsingType.xlDelimited, Microsoft.Office.Interop.Excel.XlTextQualifier.xlTextQualifierDoubleQuote,
false, true, false, false, false, false, a_Opt, a_Opt, a_Opt, a_Opt, a_Opt);
a_Book = a_Excel.Workbooks.Add(a_Opt);
a_Book.Sheets.Add();
Microsoft.Office.Interop.Excel.Worksheet worksheet = (Microsoft.Office.Interop.Excel.Worksheet)a_Book.ActiveSheet;
worksheet.Activate();
worksheet.Name = reportname;
FormatRaw_Data(worksheet);
a_Book.SaveAs(reportloc + ".xls", Microsoft.Office.Interop.Excel.XlFileFormat.xlWorkbookNormal, a_Opt, a_Opt, a_Opt, a_Opt, Microsoft.Office.Interop.Excel.XlSaveAsAccessMode.xlExclusive, a_Opt, a_Opt, a_Opt, a_Opt, a_Opt);
I am not sure how you insert the new data, but if you are writing to the same worksheet and writing to the same cells, then yes it would always override it.
Solution:
Add a new worksheet, or change the range where you write to, to avoid loss of data.
EDIT:
On your code when you add the worksheet you select the active worksheet thats why it always writes to the same worksheet you have to select the new worksheet like this:
a_Book.Sheets.Add();
Microsoft.Office.Interop.Excel.Worksheet worksheet = a_Book.Sheets[a_Book.Sheets.Count - 1];
worksheet .Name = "You can put a name";
Use Code Below:
Read the excel. Make sure it exists:
a_Book = a_Excel.Workbooks.Open(reportloc + ".xls", 0, false, 5, "", "", false, XlPlatform.xlWindows, "\t", true, false, 0, true, false, false);
Use TexttoColumns Property:
for (int i = 0; i < range.Rows.Count; i++)
{
range.Rows[i].Value = lines[i];
range.Rows[i].TextToColumns(
range.Rows[i],
Microsoft.Office.Interop.Excel.XlTextParsingType.xlDelimited,
Microsoft.Office.Interop.Excel.XlTextQualifier.xlTextQualifierNone,
false,
true
);
}
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 which contains a Signature Line. I tried to copy this sheet to another workbook, but the values of the sheet can be copied, except the signature line. I think this copy method is based on cells.
How to get signature line to another workbook. Here is my code
Excel._Application xlApp;
Excel.Workbook xlTemplateWB;
Excel.Workbook xlTempWB;
object missing = System.Reflection.Missing.Value;
xlApp = new Excel.Application();
xlApp.Visible = true;
//Open Bench Sheet Template
xlTemplateWB = xlApp.Workbooks.Open(#"C:\TempProjects\test.xlsx", 0, true, 5, "",
"", false, Excel.XlPlatform.xlWindows, "", true, false, 0, true, false, false);
//Save As a temporary workbook
xlTemplateWB.SaveAs(#"C:\\TempProjects\mytmp.xlsx");
//Open temporary workbook
xlTempWB = xlApp.Workbooks.Open(#"C:\TempProjects\my.xlsx", 0, false, 5, true, "",
true, Excel.XlPlatform.xlWindows, "\t", false, false, 0, true, 1, 0);
xlTemplateWB.Worksheets.Copy(xlTempWB.Worksheets["Sheet1"]);
xlTemplateWB.Close(true, missing, missing);
releaseObject(xlTemplateWB);
xlTempWB.Save();
//Close Workbooks
xlTempWB.Close(true, missing, missing);
xlApp.Quit();
//Release Objects
releaseObject(xlTempWB);
releaseObject(xlApp);
I have been searching online for an answer to this. There are dozens of "solutions", but nothing seems to work right. The application I'm building (using C#) pulls data from a mdb querydef and creates an Excel workbook with two worksheets. That part works perfectly. Now for the part that should be simple: I have a workbook with multiple worksheets (each worksheet will calculate the data differently) I need the code to open the "template" workbook, copy the correct worksheet, and place the copy in the newly created workbook with the other two worksheets. Here's a sample of the code that I feel "should" work:
_Application xlApp;
Workbook xlTemplateWB;
Workbook xlTempWB;
object missing = System.Reflection.Missing.Value;
xlApp = new ApplicationClass();
xlApp.Visible = true;
//Open Bench Sheet Template
xlTemplateWB = xlApp.Workbooks.Open(Elmnt.getDBPath() + TEMPLATENAME, 0, true, 5, "", "",
false, XlPlatform.xlWindows, "", true, false, 0, true, false, false);
//Open temporary workbook
xlTempWB = xlApp.Workbooks.Open(XLTempDir + XLTempName, 0, false, 5, true, "", true,
XlPlatform.xlWindows, "\t", false, false, 0, true, 1, 0);
//Copy "BOD" Worksheet
xlTempWB.Worksheets.Copy(xlTemplateWB.Worksheets["BOD"]);
xlTempWB.Save();
//Close Workbooks
xlTempWB.Close(true, missing, missing);
xlTemplateWB.Close(true, missing, missing);
xlApp.Quit();
//Release Objects
releaseObject(xlTempWB);
releaseObject(xlTemplateWB);
releaseObject(xlApp);
Based on my reading of the MSDN documentation, Worksheet.Copy() will only work within a Workbook. Your C# syntax looks correct.
There are a couple of ways to approach this:
Duplicate the entire template workbook (using WorkBook.SaveCopyAs()) and delete what you don't need.
Select the range you want to move and use the clipboard (Range.Select; Range.Copy; Range.Paste;) to copy it.
Hope this helps.
Thank you for your help. After trying a few more things, I found that the only thing I could get to work was copying the whole workbook and deleting the non-applicable worksheets. I feel that this is very cumbersome, so if anyone finds a better way to do it, I'm all ears. Here's the code that I ended up using:
_Application xlApp;
Workbook xlTemplateWB;
Workbook xlTempWB;
object missing = System.Reflection.Missing.Value;
xlApp = new ApplicationClass();
xlApp.Visible = true;
//Open Bench Sheet Template
xlTemplateWB = xlApp.Workbooks.Open(Elmnt.getDBPath() + TEMPLATENAME, 0, true, 5, "", "",
false, XlPlatform.xlWindows, "", true, false, 0, true, false, false);
//Save As a temporary workbook
xlTemplateWB.SaveAs(XLTempDir + XLTempName);
xlTemplateWB.Close(true, missing, missing);
releaseObject(xlTemplateWB);
//Open temporary workbook
xlTempWB = xlApp.Workbooks.Open(XLTempDir + XLTempName, 0, false, 5, true, "", true,
XlPlatform.xlWindows, "\t", false, false, 0, true, 1, 0);
//Remove non-applicable worksheets
for (int i = xlTempWB.Sheets.Count; i > 0; i--)
{
if (((Worksheet)xlTempWB.Sheets[i]).Name != bchSheet)
{
xlApp.DisplayAlerts = false;
((Worksheet)xlTempWB.Sheets[i]).Delete();
xlApp.DisplayAlerts = true;
}
}
xlTempWB.Save();
//Close Workbooks
xlTempWB.Close(true, missing, missing);
xlApp.Quit();
//Release Objects
releaseObject(xlTempWB);
releaseObject(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;
I want to append a data to a existing excel file using c#.I Tried it using below codes,but it is giving wrong column value after opening of the excel file(if my excel file contains 4 columns,but here it is returning column count as 1 only).
xlApp = new Excel.Application();
xlApp.Visible = true;
xlWorkBook = xlApp.Workbooks.Open(fileName, 0, false, 5, "", "", false,
Microsoft.Office.Interop.Excel.XlPlatform.xlWindows, "", true, false, 0, true, 1, 0); //#"H:\TestFile.xlsx"
xlWorkSheet = (Excel.Worksheet)xlWorkBook.Sheets.get_Item(sheetNum);
rng = xlWorkSheet.UsedRange;
int colCount = rng.Columns.Count;
int rowCount = rng.Rows.Count;
rng = (Excel.Range)xlWorkSheet.Cells[rowCount, colCount];
Excel.Range newColumn = rng.EntireColumn;
xlWorkSheet.Cells[1, colCount + 3] = "Udupi";
xlWorkBook.Save();
xlWorkBook.Close(misValue, misValue, misValue);
xlApp.Quit();
How can i append a data to excel file?Is there any other methods are available to achieve this one!
Have you tried Epplus library for creating and editing Excel spreadsheets and workbooks in C#? I have worked on it before some weeks ago. It is super. I recommend to use it.