I am trying to get the name of the workbook before it actually opens up.
((Excel.AppEvents_Event)this.Application).WorkbookOpen += new Excel.AppEvents_WorkbookOpenEventHandler(App_WorkBookOpen);
private void App_WorkBookOpen(Excel.Workbook Wb)
{
System.Windows.Forms.MessageBox.Show("Shakti " + " " + Wb.Name);
}
With the handler as shown above, Excel application shows the workbook name when it is opened completely.My intention is to do some formal check before it is actually opened up and data is shown to the user.
Is there any way or mechanism to extract the file name before the contents are loaded on to Excel and shown to the user? Any sort of help is highly appreciated.Thanks.
AFAIK you can't do that. But like I mentioned in my comment you could hide the workbook the moment it is visible. So the user will see the workbook open for a split second and then go invisible. In that split second you can read the name of the workbook and then hide the workbook.
Based on your calculations/conclusion you can then close/unhide the workbook as required.
You can hide the workbook using
Wb.Windows[1].Visible = false;
No you can't.
You anyway could create a Macro on a WorkBook Module with Open class tag as here:
Private Sub Workbook_Open()
Dim ws As Workbooks
For Each ws In ActiveWorkbook.Worksheets
MsgBox ws.Name
Next
ActiveWorkbook.Worksheets.Close
End Sub
Then call this sub via c# on opening the file, this sub runs before loading the workbook then it closes it. It has not that sense, because you'll never access the wb again...
Maybe with some tweaking here and there you could accomplish your task, but it depends to you.
Hope it helps...
Isn't Wb.name the same as the filename? In which case, since you must know the filename/location in order to open it, you can check it beforehand?
Related
I have been asked to write a script to crawl through a load of folder locations and list out all the Excel spreadsheets that have connections to a set of SQL and other data sources that are due to be upgraded to a new server.
In order to do this, I need to open each file, then check the connections and return those that match the criterion set. All this happens fine until I hit any file where the end user has made a macro to run on open that refers to a non-existent file - As the C# script opens the file, the file presents the following message:
If I manually click "End", the script moves on to the next file and all is ok, but I would much rather avoid any user input and record the fact that there was a problem with the macro... How would I go about doing that?
I have set the Excel property "Disable all macros without notification" to true on the computer that will be running the script, using the same username as will run it, which I thought would prevent this kind of thing happening. I also open Excel with DisplayAlerts=false, so that isn't the problem...
I don't need to run the macro at all and would rather not..!
for context, the code snippet that opens each file looks like this:
var app = new Application
{
Visible = false,
DisplayAlerts = false,
ScreenUpdating = false
};
Workbook thisFile = null;
try
{
//send a false password to stop Excel asking for one - when it is wrong, the error will be caught.
thisFile = app.Workbooks.Open(file.FullName, ReadOnly: true, Password: "FakePassword");
foreach (WorkbookConnection connection in thisFile.Connections)
{
EDIT: It occurs to me that maybe I could do something with a timeout..? If there were some way to close the popup box from the script, that would do the job - I could just record that the timer expired in the output, which would be enough. So... alternatively is there a way to just close the box after it has popped up?
I have been able to disable startup macros when I open the workbook by holding down shift when opening the file.
I believe the interop way to handle this is to use the application AutomationSecurity property:
Excel.Application app = new Excel.Application();
app.Visible = true;
app.AutomationSecurity = Microsoft.Office.Core.MsoAutomationSecurity.msoAutomationSecurityForceDisable;
I tested this on a simple workbook that popped up a message box and put the current time in A1, and it seemed to work properly.
Excel.Workbook wb = app.Workbooks.Open("c:/cdh/foot.xlsm");
Default, the message box popped up and A1 had a value, and when I set it to disable neither happened.
My C# code has to create an Excel file with two Worksheets and output some data over there. Besides data columns, the Sheet 1 has to be enabled with a VBA macros which would allow a user to perform some mathematical calculations with provided data upon clicking on a particular cell. This VBA macros are stored in a text file, like C:\VBA_MACROS\VBA1.txt.
Right now I can do it manually, i.e.
C# code creates an Excel file and populates it with data.
I do a right click on Sheet1 and select an option "View Code".
I click on the button "Insert" from the Microsoft Visual Basic for Applications Menu and load the file C:\VBA_MACROS\VBA1.txt.
I close the VBA code window.
Question: can steps 2 - 4 be performed automatically by a C# code as well as the step 1? In this case a user would not have to perform them manually which would be a way more comfortable for her.
To be exact, this is how the application is created:
Excel.Application application = new Excel.Application();
Excel.Workbook workbook = application.Workbooks.Add();
Excel.Worksheet worksheet = workbook.Sheets[1];
Excel.Worksheet worksheet2 = workbook.Sheets[2];
// output data to the worksheets
DataTable2Worksheet(tableMain, worksheet, verSize);
DataTable2Worksheet(tableExtra, worksheet2, 0);
// output workbook to the file
string fileDir = #"D:\MyTests\ExcelTests\";
Output2File(fileDir, workbook);
DataTable2Worksheet and Output2File functions are quite trivial, but how to attach the content of the text file to worksheet = workbook.Sheets[1] by using AddFromFile method?
You'll need a reference to Microsoft.Vbe.Interop;.
Then you need to get a handle on the module you want to insert into.
Then you can just use the CodeModule.AddFromFile method to insert the code in your text file into the module.
VBE.VBProjects("NameOfProject").VBComponents.Item("NameOfWorksheet").CodeModule.AddFromFile("C:\Path\to\file.txt");
The default name for a newly created project is "VBAProject" and you the name of the component for a sheet is the name of the sheet.
So, for your particular case, you could add this line of code at the end of your snippet to insert the VBA into Sheet1.
application.VBE.VBProjects("VBAProject").VBComponents.Item("Sheet1").CodeModule.AddFromFile("C:\VBA_MACROS\VBA1.txt");
I just learned that another option is to use the VBProject property of the Workbook, which makes the call a little cleaner.
workbook.VBProject.VBComponents.Item("Sheet1").CodeModule.AddFromFile("C:\VBA_MACROS\VBA1.txt");
Using C# to write a method that takes a single worksheet out of a workbook and saves it as HTML.
I am using the Worksheet.SaveAs method as described on MSDN.
However, when I look at the output it has gone and saved all of the worksheets within the workbook, not just the one I selected. It's as though Worksheet.SaveAs and Workbook.SaveAs just do the same thing.
Simplified code:
public static void saveSingleSheetAsHTML(string workbook, string destination, string sheetName)
{
Application excel = new Application();
excel.Workbooks.Open(Filename: workbook);
Microsoft.Office.Interop.Excel._Worksheet worksheet = excel.Worksheets[sheetName];
var format = Microsoft.Office.Interop.Excel.XlFileFormat.xlHtml;
worksheet.SaveAs(destination, format);
}
Now when I open the resulting HTML file it has only gone and exported the entire workbook, not the sheet.
As said by Tim Williams in a comment I found after hitting a link posted by I love my monkey above:
"You cannot call SaveAs on a worksheet - first call .Copy to create a
standalone new workbook containing only that sheet, then save that
workbook."
No idea why you cannot. The docs on MSDN do not give any clue about this and suggest it should be possible.
So having created a new workbook:
var newbook = excel.Workbooks.Add(1);
Copy the sheet over, which will place it as the first sheet:
excelWorksheet.Copy(newbook.Sheets[1]);
Then delete the default "Sheet1", which will always be the 2nd sheet:
newbook.Worksheets[2].Delete();
Then call the SaveAs method and then close the new book:
newbook.SaveAs(Filename: destination, FileFormat: format);
newbook.Close();
This did save the new workbook as HTML, but also put the tabs at the bottom, which I was hoping to avoid as there is only 1 tab now. It does meet my minimum needs, though I would like to figure out how to make it a bit neater.
I need to read XLTM files without opening it.
With Excel interop, i can read but it will open the file too.
The below link shows reading xlsx file with OLDB. But same wont work for XLTM.
http://codehill.com/2009/01/reading-excel-2003-and-2007-files-using-oledb/
Is there any way i can read XLTM file with out opening the file it self.
Thanks in Advance.
You can definitely use the Excel interop assembly, just set visibility and screenUpdation off like :
Microsoft.Office.Interop.Excel.Application xltmApp = new Microsoft.Office.Interop.Excel.Application();
xltmApp.Visible = false;
xltmApp.ScreenUpdating = false;
Workbook xltmBook = xltmApp.Workbooks.Open(#"C:\test.xltm");
...do stuff
Then close document properly see: http://msdn.microsoft.com/en-us/library/h1e33e36.aspx
Also if you want you can turn off dialog boxes during saving see: Trying to exit C# Excel Workbook without a dialog box.
Im just starting to use EPPLus Lib to create "complex" workbooks via C#, and i just ran into some trouble while trying to create two pivot tables.
The first one creates fine, but when i try to create the second one it doesnt throw any exceptions but when i try to open the worknook using excel it says
"Excel found unreadable content in 'myworkbook.xlsx'. Do you want to
recover the contents of this workbook? If you trust the source of this
workbook, clickYes"
And when i press 'yes':
Repair log ->
Removed Feature: PivotTable report from /xl/pivotTables/pivotTable2.xml part (PivotTable > view) Removed
Records: Workbook properties from /xl/workbook.xml part (Workbook)
Repaired Records: Workbook properties from /xl/workbook.xml part
(Workbook)
Here's the code that i build:
CreatePivotTable("Pivot1", "Pivot1", rng1);
CreatePivotTable("Pivot2", "Pivot2", rng2);
public void CreatePivotTable(string pivotSheet, string pivotName, ExcelRangeBase srcRange)
{
if (m_wb.Worksheets[pivotSheet] != null)
m_wb.Worksheets.Delete(pivotSheet);
var ws = m_wb.Worksheets.Add(pivotSheet);
var pivot = ws.PivotTables.Add(ws.Cells["A1"], srcRange, pivotName);
}
Any ideas?
Thanks!
What was wrong and i didnt put it in my question was that i was reopening the workbook on step before, like this:
CreatePivotTable("Pivot1", "Pivot1", rng1);
Save();
CreatePivotTable("Pivot2", "Pivot2", rng2);
private void Save()
{
m_writer.Save();
m_writer.OpenWorkbook ();
}
And since the save method of epplus closes the workbook, the program lost some sort of reference or just got lost with some info.
In short, to use epplus correctly, you should write everything u need before saving and closing the workbook, its not good to reopen.
Thank you.