C# Excel - How to switch to existing Worksheet and edit it? - c#

So I open an existing Excel Application with a few Worksheets and add one Worksheet and edit it. That works perfectly fine.
Now I try to switch to another Worksheet to edit this one. Code here:
Excel.Worksheet OptimaPruefliste = OptimaWorkbook.Worksheets.get_Item(1);
OptimaPruefliste.Activate();
try
{
OptimaPruefliste.Range["A1:ZZ9999"].Borders.LineStyle = true;
OptimaPruefliste.Range["A1:ZZ9999"].Interior.Color = XlRgbColor.rgbWhite;
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
It doesn´t throw an exception and it does get "OptimaPruefliste" as active sheet but it just doesn´t change anything.

So these three lines did the job:
OptimaPruefliste = (Worksheet)OptimaExcelApp.Worksheets.get_Item(1);
OptimaPruefliste.Activate();
OptimaPruefliste = OptimaExcelApp.ActiveSheet as Excel.Worksheet;

Related

C# code that remove all macros from Excel file

I have a Windows form app project (C#).
I am trying unsuccessfully to write code so that when I click a button I created, it will load an excel file that actually has macros in it and delete them all.
I know you can delete macros manually in the excel file itself but I need a way to do it programmatically (I just delete them all for the user).
I know that the macros in Excel files are written in VBA language, so I try to use the related libraries in c# but I get an error when I try to use VBProject, VBComponent.
This what I tried so far:
using Microsoft.Office.Interop.Excel;
namespace MacroRemover
{
public partial class Main : Form
{
private void Btn_Click(object sender, EventArgs e)
{
string filePath = "path\\to\\file.xlsm";
Application excel = new Application();
Workbook workbook = excel.Workbooks.Open(filePath);
VBProject vbProject = workbook.VBProject;
foreach (VBComponent component in vbProject.VBComponents)
{
vbProject.VBComponents.Remove(component);
}
workbook.Save();
workbook.Close();
excel.Quit();
}
}
}
Any way that works will help me, I would appreciate the help
Thanks in advance guys!!!
If you don't need to save xlsm format of the file, you can save this file to xlsx format and all scripts will be removed.
using Aspose.Cells;
var workbook = new Workbook("input.xlsm");
workbook.Save("Output.xlsx");
Thanks for all the replies, #tttony's response helped me to understand more deeply and #Bushuev's response here is definitely a possible and simple solution for deleting the macros.
I finally managed to delete all the macros like this:
string filePath = Path_TxtBox.Text;
Microsoft.Office.Interop.Excel.Application excel = new Microsoft.Office.Interop.Excel.Application();
Workbook workbook = excel.Workbooks.Open(filePath);
VBProject project = workbook.VBProject;
for (int i = project.VBComponents.Count; i >= 1; i--)
{
VBComponent component = project.VBComponents.Item(i);
try
{
project.VBComponents.Remove(component);
}
catch (ArgumentException)
{
continue;
}
}
for (int i = project.VBComponents.Count; i >= 1; i--)
{
VBComponent component = project.VBComponents.Item(i);
component.CodeModule.DeleteLines(1, component.CodeModule.CountOfLines);
}
workbook.Save();
workbook.Close();
excel.Quit();
MessageBox.Show("Macros Removed");
It should only be noted that I encountered an error: 'Programmatic access to Visual Basic Project is not trusted'
It was solved after I realized that I had to change the option to access the VBA Project object model in the Trust Center settings.

System.Runtime.InteropServices error when exporting dataGridView to Excel workbook

I have an application that displays certain database data, and includes a function to save that data to an excel workbook on request using the Microsoft.Office.Interop.Excel assembly. One of my users reports the following error when trying to save to an excel workbook:
System.Runtime.InteropServices.COMException (0x8002000B): Invalid index. (Exception from HRESULT: 0x8002000B (DISP_E_BADINDEX))
at Microsoft.Office.Interop.Excel.Sheets.get__Default(Object Index)
at WorkCalendar.Form1.saveBtn_Click(Object sender, EventArgs e)
We've verified that he does have Excel 2013 installed and all of the necessary assemblies came through ok according to the full exception details, so I hope one of you can shed some light on what's going on here.
Here's the saveBtn_Click event method mentioned in the error above (edited for conciseness)
private void saveBtn_Click(object sender, EventArgs e)
{
// creating Excel Application
_Application app = new Microsoft.Office.Interop.Excel.Application();
_Workbook workbook;
_Worksheet worksheet;
string fetchString = fetch.ToString("HH.mm.ss");
try
{
// Check for existing workbook and add new page
}
catch
{
// If no workbook found, create a brand new one
workbook = app.Workbooks.Add(Type.Missing);
worksheet = null;
worksheet = workbook.Sheets["Sheet1"];
}
try
{
// do not show the excel sheet being created
app.Visible = false;
worksheet = workbook.ActiveSheet;
worksheet.Name = fetchString;
// Get dataGridView data, insert it into the excel worksheet and format it
}
catch { }
finally
{
// save the application
// Exit from the application
app.Quit();
}
}
As I said, the application works fine on my and other computers on which it's been tested. Any ideas?
EDIT: Altered code example slightly to show the method looking for an existing workbook, and creating one if no workbook found.

Closing an open excel workbook in C#

There is one issue that I have been having, and I am trying to fix it because if the program crashes (the excel file stays open in the background), or the user has the excel workbook already open the program will crash because it is unable to open an already opened workbook.
Was trying to counter this issue by using the method from this question : C#: How can I open and close an Excel workbook?
But much to my dismay no success.
With this setup I get an error at wb.Close(true) saying I cannot use an unassigned local variable. To me it kind of makes sense, but I don't see how that is the case. It's not like an if statement where if the condition isn't met it doesn't jump in the loop. The try block will always execute.
Excel.Workbook wb;
try
{
wb = exApp.Workbooks.Open(#file);
}
catch (Exception)
{
wb.Close(true);
}
I also tried this way :
Excel.Workbook wb = new Excel.Workbook();
try
{
wb = exApp.Workbooks.Open(#file);
}
catch (Exception)
{
wb.Close(true);
}
but this time, I get a error: 80040154 Class not registered on the line Excel.Workbook wb = new Excel.Workbook(); when running the program. again... don't know why.
Any help is greatly appreciated.
Try this:
Excel.Workbook wb = null;
try
{
wb = exApp.Workbooks.Open(#file);
}
catch (Exception)
{
if (wb != null) wb.Close(true);
}
You want finally instead of catch. A finally block will always execute, whether there is an exception or not. Even if there isn't an Exception thrown, you still want to close the workbook to clear up the resources.
Something like this should be what you need.
Excel.Workbook wb = new Excel.Workbook();
try {
wb = exApp.Workbooks.Open(#file);
//More code...
}
catch (Exception ex) {
// Do any error handling you need/want to here.
}
finally {
// If there's a way to determine if the workbook is open, try that first.
wb.Close(true);
}

Microsoft.Office.Interop.Excel for Office 2007

I want to try the Windows form application that converts a office file (Excel, Word, Powerpoint) into a PDF file.
My client's PC will not install Visual Studio and Office version is 2007.
My application uses Microsoft.Office.Iterop.Excel.dll to covert to the PDF format.
This dll file cannot be found on my client's PC and an error has occurred as following.
System.AugumentException: Value does not fall within the expected range.
at Microsoft.Office.Interop.Excel._Workbook.ExportAsFixedFromat(.......)
How can I solve this problem?
My code is following
public bool ExportWorkbookToPdf(string workbookPath, string outputPath)
{
// If either required string is null or empty, stop and bail out
if (string.IsNullOrEmpty(workbookPath) || string.IsNullOrEmpty(outputPath))
{
return false;
}
// Create COM Objects
Microsoft.Office.Interop.Excel.Application excelApplication;
Microsoft.Office.Interop.Excel.Workbook excelWorkbook;
// Create new instance of Excel
excelApplication = new Microsoft.Office.Interop.Excel.Application();
// Make the process invisible to the user
excelApplication.ScreenUpdating = false;
// Make the process silent
excelApplication.DisplayAlerts = false;
// Open the workbook that you wish to export to PDF
excelWorkbook = excelApplication.Workbooks.Open(workbookPath);
MessageBox.Show(workbookPath);
// If the workbook failed to open, stop, clean up, and bail out
if (excelWorkbook == null)
{
excelApplication.Quit();
excelApplication = null;
excelWorkbook = null;
MessageBox.Show("in null");
return false;
}
var exportSuccessful = true;
try
{
// Call Excel's native export function (valid in Office 2007 and Office 2010, AFAIK)
excelWorkbook.ExportAsFixedFormat(Microsoft.Office.Interop.Excel.XlFixedFormatType.xlTypePDF, outputPath);
}
catch (System.Exception ex)
{
MessageBox.Show(ex.Message);
// Mark the export as failed for the return value...
exportSuccessful = false;
// Do something with any exceptions here, if you wish...
// MessageBox.Show...
}
finally
{
// Close the workbook, quit the Excel, and clean up regardless of the results...
excelWorkbook.Close();
excelApplication.Quit();
excelApplication = null;
excelWorkbook = null;
}
// You can use the following method to automatically open the PDF after export if you wish
// Make sure that the file actually exists first...
if (System.IO.File.Exists(outputPath))
{
MessageBox.Show(outputPath);
System.Diagnostics.Process.Start(outputPath);
}
return exportSuccessful;
}
As already said in the comments, each client needs to install the 2007 Microsoft Office Add-in: Microsoft Save as PDF. It doesn't matter if you are on Windows 8.1 or have any PDF reader installed. You need that Add-in to write PDFs with Office 2007. (You don't need any Add-In with Office 2010 or 2013.)

Interop.Excel 0x800A03EC - Out of memory error code 7

I am trying to cycle through a excel workbook and copy paste values over the top
of each sheet within that workbook. But I am running into a memory issue on line:
ws.select(true), when going to the next sheet.
Errors encountered:
Exception from HRESULT: 0x800A03EC:
and when I go to close out of the workbook at this point excel throws:
Out of memory (Error 7)
Additional information:
File size 3mb, 20 tabs and lots of database formulae reading from olap database TM1.
Microsoft office 2007
The code I am running is below. Is there a more efficient way of running it that may prevent the Out of Memory Error OR is this something different??
Any help would be much appreciated!
#
public bool wbCopyValueOnly(string workBook)
{
Workbook wb = excel.ActiveWorkbook;
Worksheet ws;
Range rng;
int WS_Count = wb.Sheets.Count;
for (int i = 0; i < WS_Count; i++)
{
try
{
ws = wb.Sheets[i + 1];
ws.Activate();
ws.Select(true);
//ws.Select(Type.Missing);
//ws.Cells.Select();
ws.UsedRange.Select();
//ws.Cells.Copy();
ws.UsedRange.Copy(Type.Missing);
ws.UsedRange.PasteSpecial(Excel.XlPasteType.xlPasteValues, Excel.XlPasteSpecialOperation.xlPasteSpecialOperationNone, false, false);
// select of range to get around memory issue
excel.Application.CutCopyMode = (Excel.XlCutCopyMode)0;
//rng = ws.get_Range("A1");
//rng.Select();
NAR(ws);
}
catch (System.Runtime.InteropServices.COMException err)
{
cLogging.write(LogLevel.Error, err.Message);
Debug.Print(err.Message);
return false;
}
}
NAR(wb);
return true;
}
private void NAR(object o)
{
try
{
while (System.Runtime.InteropServices.Marshal.ReleaseComObject(o) > 0) ;
}
catch { }
finally
{
o = null;
}
}
I have a program that copies from up to 100 tabs back to the first summary page and I found that using .Copy() caused several problems. Especially if your program runs for a length of time; the current user cannot use the copy-paste function without strange results. I recommend using variables to store what you need and then write to the intended range. Recording Macros is invaluable if you need to change the format of the range.
ws.Activate();
ws.Select(true);
ws.UsedRange.Select();
I think these code isn't necessary.
You can record a Marco to learn how to modify your code.

Categories