I am using an excel interop to open an excel file, edit and save it with some other name in some other location. For that I have used:
workbook.saveAs(newFileName)
But it is prompting in the application for compatibility like how it is used to prompt while saving .xls file in office 2007. I have to click on continue in the front end application in order to continue. How can it be resolved?
Thanks in advance,
Sarath
There is an Application.DisplayAlerts property which you can set to False during your SaveAs operation (and then set back to True).
Here are the details: http://msdn.microsoft.com/en-us/library/microsoft.office.interop.excel._application.displayalerts(v=office.11).aspx
... I'm not sure I 100% understand what it is you're experiencing, but if it's a notification box that appears, try putting this line before the Save command:
ExcelApp.DisplayAlerts = False
That should disable the alert from popping up....
Related
I have an app that processes Word, PowerPoint and Excel documents. After processing each document, I call the SaveAs method (or SaveAs2). For word, I set the DisplayAlerts to wdAlertsAll. I never see the dialog asking if I want to overwrite the document. I added code to get the alsert level right before calling SaveAs2 and it is wdAlertsAll. But, I see no message box. If I run Word and open the same file and do SaveAs to the same location as my app, the dialog appears.
I have the same issue with PowerPoint where I set the level to ppAlertsAll.
I do the same thing for Excel and ... it works just fine. I am prompted before doing the SaveAs.
In all three cases my app starts the Office apps and make sure they are visible on the desktop. I was thinking that perhaps running in the background was an issue but apparently not.
There's some MS documentation about DisplayAlerts in PowerPoint here:
https://learn.microsoft.com/en-us/office/vba/api/powerpoint.application.displayalerts?f1url=%3FappId%3DDev11IDEF1%26l%3Den-US%26k%3Dk(vbapp10.chm502050)%3Bk(TargetFrameworkMoniker-Office.Version%3Dv16)%26rd%3Dtrue
The writer should be complimented for his/her vivid imagination. It's all a fantasy, probably copy/pasted from the Excel docs. DisplayAlerts is part of the PPT object model but it's never worked.
For example, try this in VBA:
Sub BeAlert()
Application.DisplayAlerts = ppAlertsNone
Debug.Print MsgBox("Testing", vbAbortRetryIgnore, "ArfArf")
Application.DisplayAlerts = ppAlertsAll
Debug.Print MsgBox("Testing", vbAbortRetryIgnore, "ArfArf")
End Sub
Both MsgBoxes appear, though the documentation suggests that only the second one will.
I'm not sure there'd be any difference between behavior in C# vs VBA, but in the latter, overwriting a file doesn't produce a message. It simply overwrites, no questions asked.
If you close a file that hasn't been saved since it was last changed, you may get a message; if you want to avoid that, set the presentation's .Saved property to True.
If you deal with open XML documents it makes sense to process documents without MS Office involved, see Welcome to the Open XML SDK 2.5 for Office for more information.
Otherwise, you can use the Application.DisplayAlerts in PowerPoint. The value of the DisplayAlerts property is not reset once a macro stops running; it is maintained throughout a session. It's not stored across sessions, so when PowerPoint begins, it is reset to ppAlertsNone.
Sub SetAlert
Application.DisplayAlerts = ppAlertsNone
End Sub
I have an application that uses Excel 2013. I need a way to disable all macros. I can not do it on workbook open because I do not have access to the open methods, the workbook is opened by another COM application then passed to me. It needs to happen prior to opening the document. What I am ultimately trying to do is set the setting found in the image below.
The best solution I found was to edit the registry. Shout out to Tim Williams for pointing me in the right direction
The key that needs to be edited is
HKEY_CURRENT_USER\Software\Microsoft\Office\15.0\Excel\Security\VBAWarnings
In my case I was to disable all macros by setting the value to 4
More info can be found Here
We have developed a VSTO addin for Excel, which pulls excel sheets from a web server, and allows users to manipulate the data on the sheet. It works with a local copy of the file but we don't really care about that copy. But some of our clients have "iManage Integration for Office" installed as well, and these clients experience odd behaviour. In this environment we are not able to cancel the Close event.
More specifically, if a user opens one of our files and makes changes, then closes the file, our event handler fires and prompts them to save changes (to the data on the server). If they choose Cancel, or if they choose Save and the save fails for some reason, we set Cancel = true in an attempt to keep the file open. Ordinarily this works perfectly.
For those clients with iManage, the file closes anyway. If our code has saved the local copy of the file, then the file just closes. If the local copy has not been saved, the user gets another prompt after our prompt, from iManage, asking if they want to save the file. From here, the user could click Cancel and the file remains open. But the users are reporting that it's confusing to see the second prompt after clicking Cancel on the first. And they are not willing to disable the iManage addin. We would like to be able to keep the file open in this case, preferably without seeing the iManage prompt.
Working in a test environment a client set up for me (Excel 2010), I have tried a few things:
I tried setting Cancel on the workbook level BeforeClose and the applicationlevel WorkbookBeforeClose; neither one worked (file still closes whenever iManage is enabled)
I tried to make sure my handler for WorkbookBeforeClose is registered last, by registering it in the workbook level event handler; no change
I can use the iManage ribbon to manually switch to Local Mode, which makes everything work, but I don't know whether/how I can make that change through code.
I can find the iManage addin in Globals.ThisAddIn.Application.COMAddIns; I tried setting its Connect = false, but this gives an error to the effect that only an administrator can connect/disconnect the addin.
I can save the local file during the Closing event, then do SaveAs to create a second copy; the second copy is now active and iManage closes it; then I reopen the original local file. It looks pretty good to the user, but then I have a bunch of COM references to cells on the old file, and these are all garbage. I can probably loop through and serialize them and recreate them with the new file, but it will be time consuming to code and to run, so I'm looking for other ideas first.
Is there any way I can keep the file open, without making the users do anything extra?
UPDATE
Using iManage 9.3.0.0 and Excel 2010, I created a VBA macro with a reference to Worksite Integration Interfaces Library(Ex). The event fires, but the file still closes. If I don't set the Saved property, and I type on the grid, I always get a prompt from iManage asking if I want to save.
Private WithEvents oWS As iManageExtensibility
Private Sub oWS_DocumentBeforeClose2(ByVal Doc As Variant, IgnoreIManageClose As Boolean, Cancel As Boolean)
IgnoreIManageClose = True
Cancel = True
End Sub
Private Sub Workbook_BeforeClose(Cancel As Boolean)
Set oWS = Application.COMAddIns("WorkSiteOffice2007Addins.Connect").Object
Cancel = True
ActiveWorkbook.Saved = True
End Sub
You do not need to disable the iManage integration add-in for Office. Your application should detect the presence of the iManage integration add-in and then handle that add-in's own equivalent Close event
To do that, first get an instance of the iManage add-in by examining the Excel Application.COMAddins collection and fetching back the COM add-in instance with a ProgID of either WorkSiteOffice2003Addins.Connect (Excel 2003 or earlier) or WorkSiteOffice2007Addins.Connect (Excel 2007 or later).
Actually there should also be a so-called "backwards compatibility" add-in installed also registered with a ProgID of oUR02k.Connect which you may reference instead. Again, whether that is installed or not depends somewhat on the version of FileSite/DeskSite that is installed on the machine.
That all may seem confusing to you however it's because the add-ins have changed over the years, so it rather depends on how old the iManage client is (i.e. FileSite, DeskSite) as well as the version of Office you're targeting. You may need to compensate for different Excel/iManage client versions in your code
Once you have the right COM add-in reference, examine the COMAddin.Object property. This value represents an instance of the iManage Office integration add-in
From there you can cast that object to the strongly typed COM interface of iManageExtensibility
You're then able to hook into all the Office application events that iManage have hijacked (much like you have done in your application) and respond to those events rather than the native Excel ones.
In your case you will need to monitor the DocumentBeforeClose2 event. Note the character '2' at the end. There is also a legacy event named DocumentBeforeClose but the newer DocumentBeforeClose2 has the following method signature:
DocumentBeforeClose2(object doc, ref bool ignoreimanageclose, ref bool cancel)
Finally, in your DocumentBeforeClose2 event handler add your business logic for cancelling the close event and/or the iManage close event. You do that by setting the ignoreimanageclose and/or cancel Booleans to true/false as appropriate. The doc parameter in this case will be the Excel workbook instance, so you may safely cast it to the Excel.Workbook interface if you wish
PS: if you are developing against the iManage APIs and require support you should consider purchasing the iManage SDK. That SDK contains help on various APIs, code samples, and crucially I believe it gives you access to some dev support.
Lets say I have an Excel file named "DataSheet.xls" open. How can I kill that Excel file using c#?
using Excel = Microsoft.Office.Interop.Excel;
(...)
var app = (Excel.Application)System.Runtime.InteropServices.Marshal.GetActiveObject("Excel.Application");
// I have english excel, but another culture and need to use english culture to use excel calls...
Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo("en-US");
app.Workbooks["DataSheet"].Close(false, false, false);
It's very likely that a single process will contain multiple open workbooks. Especially because Excel prefers to re-use an existing instance when opening files from Explorer, Outlook, etc. instead of creating a new process for each workbook.
Not to mention killing the process will require you to either 1) close the main window which will prompt if there's unsaved changes or 2) forcefully kill the process which will likely cause Excel to show its crash recovery options the next time you launch it.
The best course of action is to use the Excel COM API to close the workbooks. You can use the Marshal.GetActiveObject method to get a running instance of Excel and then refer to the Office developer reference for more information about how to close specific named workbooks without prompting.
The Process class would allow you to kill a process. You could inspect all running excel.exe processes, get the main window handle for the process, check whether the caption of that window contains the name of the XLS file and then kill the process for that window.
Otherwise you could use the Office COM classes to talk to Excel. This may also allow you to shut down open workbooks.
off hand don't have the code as such. but generally, in the past i'd have used a couple of api calls to do this. first, you'd get the window handle (hWnd) and then you'd use the sendmessage api call with the wm_close parameter.
that's about all i can remember -it's been about 10 yrs since i had to do that kinda stuff, so the field may have changed since then :)
I have developed a simple C# Winforms application that loads MS-Word 2007 documents via COM automation.
This is all very simple and straight forward, however depending on the document I need to programamtically Enable or Disable Macros as well as ActiveX controls.
There is probably a way to store this in the registry, but I want to control these settings on an instance by instance basis as multiple concurrent requests may be running at a time.
So my question is 'how do I configure the trust center settings using COM automation'.
I have Googled for hours, but all I have been able to find is the Application.AutomationSecurity property, but this only accepts the following values:
MsoAutomationSecurity.msoAutomationSecurityLow
MsoAutomationSecurity.msoAutomationSecurityForceDisable
MsoAutomationSecurity.msoAutomationSecurityByUI
The Word 2007 Trust Center however exposes the following settings:
Macro Settings:
Disable all macros without notification (matches msoAutomationSecurityForceDisable)
Disable all macros with notifications (I don't need this one)
Disable all macros except digitally signed macros (No equivalent)
Enable all macros (matches msoAutomationSecurityLow)
(source: visguy.com)
ActiveX controls (configured separately, I have not found any way to control these, note that according to the screenshot these settings are shared between all applications)
Disable all controls without notification
Prompt me before enabling UFI controls....
Prompt me before enabling all controls with minimal erstrictions
Enable all controls without restrictions
I have tried the old trick of recording an MS-Word macro while changing these settings, but none of these steps are recorded.
Update:
I have found the following entries for the ActiveX controls settings in the registry. Looks like ActiveX settings are indeed global and cannot be specified for a single MS-Word instance unless someone proves me wrong.
ActiveX Disabled
[HKEY_CURRENT_USER\Software\Microsoft\Office\Common\Security]
"DisableAllActiveX"=dword:00000001
"UFIControls"=dword:00000002
ActiveX Enabled with safe mode
[HKEY_CURRENT_USER\Software\Microsoft\Office\Common\Security]
"DisableAllActiveX"=dword:00000000
"UFIControls"=dword:00000002
ActiveX Enabled without safe mode
[HKEY_CURRENT_USER\Software\Microsoft\Office\Common\Security]
"DisableAllActiveX"=dword:00000000
"UFIControls"=dword:00000001
Still keen to resolve the macro settings problem
Looks like I am going to answer my own question.
I have tested it and can confirm the mappings are as follows:
Macro Settings:
msoAutomationSecurityForceDisable = Disable all macros without
notification
msoAutomationSecurityByUI = Disable all macros except digitally
signed macros
msoAutomationSecurityLow = Enable all macros
To the best of my knowledge the global ActiveX settings can only be configured by directly editing the registry
ActiveX Disabled
[HKEY_CURRENT_USER\Software\Microsoft\Office\Common\Security] "DisableAllActiveX"=dword:00000001 "UFIControls"=dword:00000002
ActiveX Enabled with safe mode
[HKEY_CURRENT_USER\Software\Microsoft\Office\Common\Security] "DisableAllActiveX"=dword:00000000 "UFIControls"=dword:00000002
ActiveX Enabled without safe mode
[HKEY_CURRENT_USER\Software\Microsoft\Office\Common\Security] "DisableAllActiveX"=dword:00000000 "UFIControls"=dword:00000001
I have left a comment in the relevant section of the MSDN website
I know this thread is quite old, but I had to figure it out today so after a quick research I found this registry for the Trust Center Settings:
This applies to Word version 2010 (and probably 2007, but with 12.0 instead of 14.0)
Or in text:
Registry location:
HKEY_CURRENT_USER\Software\Microsoft\Office\14.0\Word\Security
Macro Settings:
Name: VBAWarnings
Data:
Disable all macros without notification - 4
Disable all macros with notification - 2
Disable all macros except digitally signed macros - 3
Enable all macros (...) - 1
Developer Macro Settings:
Name: AccessVBOM
Data:
Unchecked - 0
Checked - 1
For the setting for ActiveX controls in office 2010
to DisbaleActiveX without safe mode you only need ...
"HKEY_CURRENT_USER\Software\Microsoft\Office\Common\Security" /v UFIControls /t REG_DWORD /D 1 /F
I've spent a couple of days trying the same thing and finally discovered a very simple way of opening an .xls file containing macros, without messing with the registry or Excel's trust settings. In C#:
Application aXL = new Application();
aXL.FileValidation =
Microsoft.Office.Core.MsoFileValidationMode.msoFileValidationSkip;
try {
Workbook aBook = aXL.Workbooks.Open("K:\\Work\\ExcelTest\\BrokenMacro.xls"
, 0
, true
, Type.Missing
, Type.Missing
, Type.Missing
, true
, Type.Missing
, Type.Missing
, false
, false
, Type.Missing
, false
, false
, Type.Missing
/*,false*/);
}
catch (Exception e) {
Console.WriteLine(e);
}
See MSDN for details.
My Excel trust center setting were all set to default values - "Disable All Macros with Warnings", and "Do Not trust access to the VBA object model. Without the msoFileValidationSkip option an exception was thrown. With the msoFileValidationSkip option the file opened fine.
It seems to me that this is the way to go, since it allows a program to open files with macros, but doesn't open up the Excel application virus ridden spreadsheets.
Note that I'm running Office 2010. I don't know on which version of Office this option was introduced.