I am trying to add a new worksheet to an Excel workbook and make this the last worksheet in the book in C# Excel Interop.
It seems really simple, and I thought the below code would do it:
using System.Runtime.InteropServices;
using Excel = Microsoft.Office.Interop.Excel;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
var excel = new Excel.Application();
var workbook = excel.Workbooks.Open(#"C:\test\Test.xlsx");
workbook.Sheets.Add(After: workbook.Sheets.Count);
workbook.Save();
workbook.Close();
Marshal.ReleaseComObject(excel);
}
}
}
No such luck. I get this helpful error:
COMException was unhandled - Exception from HRESULT: 0x800A03EC
I found this page on Microsoft.com which suggested I try and add the sheet first and then move it so I tried that as shown below. I know that this webpage targets Excel 95 but the VBA is still there to use so I was hoping it would still work:
using System.Runtime.InteropServices;
using Excel = Microsoft.Office.Interop.Excel;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
var excel = new Excel.Application();
var workbook = excel.Workbooks.Open(#"C:\test\Test.xlsx");
workbook.Sheets.Add();
workbook.Sheets.Move(After: workbook.Sheets.Count);
workbook.Save();
workbook.Close();
Marshal.ReleaseComObject(excel);
}
}
}
I get the same error as above. I have also tried passing the name of my last worksheet as a string as the After parameter in both the Add and Move methods, no joy!
That is what I have tried, so my question is how do I add a worksheet to an Excel workbook and make this the last sheet in the workbook using C# Excel Interop?
Thanks
Looking at the documentation here http://msdn.microsoft.com/en-us/library/microsoft.office.tools.excel.worksheet.move(v=vs.80).aspx, it indicates that the 'after' object isn't a numerical position; it's the object representing the sheet you want to position your sheet after. The code should probably be something like (untested):
workbook.Sheets.Add(After: workbook.Sheets[workbook.Sheets.Count]);
This should do the job:
wSheet.Move(Missing.Value, workbook.Sheets[workbook.Sheets.Count]);
This is the only way that works for me:
xlWorkSheet = (Microsoft.Office.Interop.Excel.Worksheet)xlWorkBook.Worksheets.Add
(System.Reflection.Missing.Value,
xlWorkBook.Worksheets[xlWorkBook.Worksheets.Count],
System.Reflection.Missing.Value,
System.Reflection.Missing.Value);
it works for me
WorkBook.Worksheets.Add(
System.Reflection.Missing.Value,
WorkBook.Worksheets[WorkBook.Worksheets.Count],
1,
System.Reflection.Missing.Value);
Related
I would like to export a specific worksheet of my excel file to PDF.
When I do wbk.ExportAsFixedFormat it work but it dosn't work when I do worksheet.ExportAsFixedFormat.
Someone can help me?
I have to "activate" the worksheet maybe ?
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using Microsoft.Office.Interop.Excel;
namespace XLConvert
{
class Program
{
static void Main(string[] args)
{
Application app = new Application();
Workbook wkb = app.Workbooks.Open(#"C:\Users\ALPIC\Desktop\XL\0000351608.xlsx");
var worksheet = wkb.Sheets["FRA"];
worksheet.ExportAsFixedFormat(XlFixedFormatType.xlTypePDF, #"C:\Users\ALPIC\Desktop\XL\0000351608.pdf");
wkb.Close(false, #"C:\Users\ALPIC\Desktop\XL\0000351608.xlsx");
Marshal.ReleaseComObject(wkb);
}
}
}
Thanks!
I found !
I tried this and it works :
static void Main(string[] args)
{
Application app = new Application();
Workbook wkb = app.Workbooks.Open(#"C:\Users\ALPIC\Desktop\XL\0000351608.xlsx");
((Worksheet)wkb.Sheets["FRA"]).ExportAsFixedFormat(XlFixedFormatType.xlTypePDF, #"C:\Users\ALPIC\Desktop\XL\0000351608.pdf");; //activates first sheet
wkb.Close(false, #"C:\Users\ALPIC\Desktop\XL\0000351608.xlsx");
Marshal.ReleaseComObject(app);
}
From the looks of it, var worksheet = wkb.Sheets["FRA"]; gets assigned as a worksheet collection, while you specifically assigned wkb as a workbook, which has that function.
I'm currently trying to copy a worksheet from a different workbook which i succeed by using Copy() and PasteSpecial(). However, I would like to know why the following code does not work even though many solutions online seems to use this approach.
Workbook currBook = Globals.ThisAddIn.GetActiveWorkbook();
Workbook copyBook = Globals.ThisAddIn.OpenWorkbook(Globals.ThisAddIn.Application.ActiveWorkbook.Path + #"\copyFile.xlsm", true, true);
//required worksheet
Worksheet copySheet = Globals.ThisAddIn.GetWorksheet(copyBook, "ToCopy");
copySheet.Copy(currBook.Worksheets[1]);
//close workbook
copyBook.Close();
Function used to get specific sheet:
public Excel.Worksheet GetWorksheet(Excel.Workbook book, string sheetName, bool create = false)
{
foreach (Excel.Worksheet sheet in book.Worksheets)
{
//worksheet with name found
if (sheet.Name == sheetName)
{
sheet.Activate();
return sheet;
}
}
//worksheet can't be found
if (create)
{
Excel.Worksheet sheet = book.Worksheets.Add();
sheet.Name = sheetName;
sheet.Activate();
return sheet;
}
return null;
}
There is no error from the stated code and the worksheet has been tested to exist. The program simply does not create a copy into currBook
Interestingly, I was just working on something else where this came up...
In order to specify a destination it's necessary to use Range.Copy, not Sheet.Copy:
copySheet.UsedRange.Copy(currBook.Worksheets[1].Range["A1"]);
If a destination can't be specified, then Excel puts the data in a new workbook.
I am using oledb to read .xls files in my application. It is working fine but real issue comes when my excel contains merged cells in rows or in column.
This is the data in excel
This is how it show on screen using webgrid
The VERY first thing that I would say is STAY VERY FAR AWAY FROM MERGED CELLS IN EXCEL!! That is the work of the DEVIL. Ok, if you still want to do this, consider the following options (you don't have many options) . . .
using Spire.Xls;
namespace Detect_Merged_Cells
{
class Program
{
static void Main(string[] args)
{
Workbook workbook = new Workbook();
workbook.LoadFromFile("Sample.xlsx");
Worksheet sheet = workbook.Worksheets[0];
CellRange[] range = sheet.MergedCells;
foreach (CellRange cell in range)
{
cell.UnMerge();
}
workbook.SaveToFile("Output.xlsx",ExcelVersion.Version2010);
}
}
}
OR
Excel.Range firstCell = excelWorksheet.get_Range("A1", Type.Missing);
Excel.Range lastCell = excelWorksheet.Cells.SpecialCells(Excel.XlCellType.xlCellTypeLastCell, Type.Missing);
object[,] cellValues;
object[,] cellFormulas;
Excel.Range worksheetCells = excelWorksheet.get_Range(firstCell, lastCell);
cellValues = worksheetCells.Value2 as object[,];
cellFormulas = worksheetCells.Formula as object[,];
How would you rename a "Using Directive" Using C#?
Because some times You copy a class from somewhere (Example below)
//Other Code
Excel.ApplicationClass excel;
Excel.Workbooks workbooks;
Excel.Workbook workbook;
Excel.Worksheet worksheet;
Excel.Sheets worksheets;
//Other Code
and instead of renaming everything to
//Other Code
Microsoft.Office.Interop.Excel.ApplicationClass excel;
Microsoft.Office.Interop.Excel.Workbooks workbooks;
Microsoft.Office.Interop.Excel.Workbook workbook;
Microsoft.Office.Interop.Excel.Worksheet worksheet;
Microsoft.Office.Interop.Excel.Sheets worksheets;
//Other Code
So having something like
Using Microsoft.Office.Interop.Excel.ApplicationClass as 'Excel'
You can create an alias like this:
// for whole namespace
using Excel = Microsoft.Office.Interop.Excel;
// use like this
Excel.ApplicationClass excel = /* ... */;
// or for single type
using ExcelApp = Microsoft.Office.Interop.Excel.ApplicationClass;
// use like this
ExcelApp excel = /* ... */;
I think you're just looking for:
using Excel = Microsoft.Office.Interop.Excel;
(I don't think you wanted ApplicationClass here. That would be an alias for the type rather than the Microsoft.Office.Interop.Excel namespace. It's not really clear from your question though.)
This is called a using-alias-directive. From section 9.4.1 of the C# 4 spec:
A using-alias-directive introduces an identifier that serves as an alias for a namespace or type within the immediately enclosing compilation unit or namespace body.
So after that using directive, it would be valid to have:
Excel.ApplicationClass excel = new Excel.ApplicationClass();
... which is what I think you wanted?
What about:
using Excel = Microsoft.Office.Interop.Excel;
As the msdn documentation says http://msdn.microsoft.com/en-us/library/sf0df423%28v=vs.71%29.aspx
using [alias = ]class_or_namespace;
So in your case:
using Excel = Microsoft.Office.Interop.Excel;
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.Cells[row, clmn].Interior.Color = XlRgbColor.rgbBlack;
to color cells..But this is not working..
It is giving an exception on the last line where i am coloring the cells
"Exception from HRESULT: 0x800A03EC"
I am unable to fix the exception
Can anyone help me out..
It might not work because the worksheet is protected.
You can check it the following way:
Application excel = new Application();
Workbook wb = excel.Workbooks.Open(destPath);
Worksheet ws = wb.Worksheets[1];
bool wasProtected = ws.ProtectContents;
if (wasProtected == true)
{
// unprotect the worksheet
}
else
{
ws.Cells[row, clmn].Interior.Color = XlRgbColor.rgbBlack;
}
...
if (wasProtected == true)
{
// protect back the worksheet
}
In my previous project I used the following snippet to Color Cells in Excel:
ws.Cells[row, clmn].Interior.Color = System.Drawing.ColorTranslator.ToWin32(Color.Black);
I tested the code that you have on a new Excel file and it works fine. However, I was able to reproduce the error when testing with a row value of 0. So maybe the problem is with the row and clmn values. Otherwise it must be something specific to your Excel file... maybe a protected cell or something along those lines.