Context:
Vb.net program
Visual studio 2010 ultimate
MS Word 2010 automation
Microsoft.Office.Interop.Word library
I'm using the saveAs2 method to save a new document I'm creating but the application is still prompting me when I call the method. Why?
The application is not visible.
The application.displayAlerts is false
Any ideas guys?
Also, when I do complete the SaveUI prompt by hand, the saveAs2 method throws an exception.
Here's my code for people who asked for it :
Public Sub generateModel() Implements ModelGenerator.generateModel
wordApp.Visible = True
wordApp.DisplayAlerts = Word.WdAlertLevel.wdAlertsNone
wordDoc = wordApp.Documents.Add
wordDoc.PageSetup.TopMargin = wordApp.InchesToPoints(0.25)
wordDoc.PageSetup.BottomMargin = wordApp.InchesToPoints(0.25)
wordDoc.PageSetup.LeftMargin = wordApp.InchesToPoints(0.25)
wordDoc.PageSetup.RightMargin = wordApp.InchesToPoints(0.25)
With wordDoc.Content.Paragraphs.Add(wordDoc.Bookmarks.Item("\endofdoc").Range)
.Range.Text = _text
.Format.Alignment = Word.WdParagraphAlignment.wdAlignParagraphCenter
.Format.LineUnitBefore = 1
.Range.Font.SmallCaps = True
.Range.Font.Size = 12
End With
Dim logo = wordDoc.Shapes.AddPicture(logoLoc)
logo.Height = wordApp.InchesToPoints(0.5)
logo.Width = wordApp.InchesToPoints(1.18)
Me.mainTable = wordDoc.Tables.Add(wordDoc.Bookmarks.Item("\endofdoc").Range, 3, 2)
mainTable.Rows.HeightRule = Word.WdRowHeightRule.wdRowHeightExactly
mainTable.Columns.Width = wordApp.InchesToPoints(4)
mainTable.Rows.Height = wordApp.InchesToPoints(3.25)
mainTable.Select()
wordApp.Selection.ParagraphFormat.Alignment = Word.WdParagraphAlignment.wdAlignParagraphLeft
With wordDoc.Content.Paragraphs.Add(wordDoc.Bookmarks.Item("\endofdoc").Range)
.Range.Text = "Rapport journalier de production - page 2"
.Range.Font.Size = 10
.Format.Alignment = Word.WdParagraphAlignment.wdAlignParagraphCenter
.Format.LineUnitBefore = 0
.Format.SpaceBeforeAuto = False
.Format.SpaceBefore = 0
End With
wordDoc.SaveAs2("C:\Doc1.docx")
wordDoc.Close(False)
wordApp.Application.Quit()
End Sub
**Update:
I tested the code on an other machine and it works. So I tried this code on mine:
Dim app As New Microsoft.Office.Interop.Word.Application
Dim doc = app.Documents.Add
doc.SaveAs2("C:\Users\simon\Documents\Doc3.docx")
And it still makes the saveUI pop up. I'm so confused...
Finally found the problem's source.
My Acer computer was installing an Add-in everytime I installed Word. Once I removed the Add-in from Word everything went back to normal.
The Add-in was the AcerCloud Add-in.
I just tried to create a sample implementation in C#, Word Interop API v.15 (Office 2013):
var wordApplication = new Application() { Visible = true };
var doc = wordApplication.Documents.Add();
doc.SaveAs2(#"C:\my.docx");
... and when you save to a location that requires admin permission (like on the root of the C:\ drive), Word Interop throws a System.Runtime.InteropServices.COMException saying that: "Word cannot save or create this file. Make sure that the disk you want to save the file on is not full, write-protected, or damaged."
Instead, you should save at a location where your application has the necessary write permissions, e.g., to your own user directory - then it should work as expected.
Related
Using DocumentFormat.OpenXML, I am trying to add a custom property to a Word document and then later read the property. The following code "appears" to do just that:
Dim os As OpenSettings = New OpenSettings() With {
.AutoSave = False
}
Dim propVal As String = "Test Value"
Using doc As WordprocessingDocument = WordprocessingDocument.Open(filename, True, os)
Dim cPart As CustomFilePropertiesPart = doc.CustomFilePropertiesPart
If cPart Is Nothing Then
cPart = doc.AddCustomFilePropertiesPart
cPart.Properties = New DocumentFormat.OpenXml.CustomProperties.Properties()
End If
Dim cPart As CustomFilePropertiesPart = doc.CustomFilePropertiesPart
Dim cProps As Properties = cPart.Properties
For Each prop As CustomDocumentProperty In cProps
If prop.Name = "TranscriptID" Then
prop.Remove()
Exit For
End If
Next
Dim newProp As CustomDocumentProperty = New CustomDocumentProperty() With {
.Name = "TranscriptID"
}
newProp.VTBString = New VTBString(propVal)
newProp.FormatId = "{D5CDD505-2E9C-101B-9397-08002B2CF9AE}"
cProps.AppendChild(newProp)
Dim pid As Integer = 2
For Each item As CustomDocumentProperty In cProps
item.PropertyId = pid
pid += 1
Next
cProps.Save()
End Using
This code is modeled after code found here:
https://learn.microsoft.com/en-us/office/open-xml/how-to-set-a-custom-property-in-a-word-processing-document
It appears to work in this scenario:
Execute code from above.
Execute code from above again.
At #2 I expect to find the CustomFilePropertiesPart and the property value and my expectation is met.
The problem appears in this scenario:
Execute code from above.
Open document using Microsoft Word, save and close.
Execute code from above again.
What happens in this scenario is that the CustomFilePropertiesPart is missing, whereas it should be found. It is as if Microsoft Word does not successfully read this object, so when the document is save, the object is lost. This suggests to me that there is something that there is something wrong with my code. If you can see what it is, or if you have a comparable working example that I could compare it with, I would appreciate hearing from you. I feel like I correctly followed the Microsoft example, but obviously I did not and I am having trouble seeing where I departed. Thanks.
OK, I found this wonderful tool called the Office Productivity Tool. It has a code generation feature, so I was able to compare what I was doing with what Word does. Basically the problem was with setting the property value. This snippet does the trick:
Dim cProps As Properties = cPart.Properties
Dim val As DocumentFormat.OpenXml.VariantTypes.VTLPWSTR = New DocumentFormat.OpenXml.VariantTypes.VTLPWSTR
val.Text = tr.ID.ToString
Dim newProp As CustomDocumentProperty = New CustomDocumentProperty() With {
.Name = "TranscriptID",
.FormatId = "{D5CDD505-2E9C-101B-9397-08002B2CF9AE}"
}
newProp.Append(val)
cProps.AppendChild(newProp)
What I'm trying to do here would seem to be pretty simple. At the start of my SSIS package I want to set a variable to a directory that the user is prompted for. Here's my VB code:
Public Sub Main()
Dim fldDialog As FolderBrowserDialog = New FolderBrowserDialog
fldDialog.Description = "Select the folder..."
fldDialog.ShowNewFolderButton = False
fldDialog.RootFolder = Environment.SpecialFolder.MyDocuments
If fldDialog.ShowDialog() = DialogResult.OK Then
Dts.Variables("variable").Value = fldDialog.SelectedPath
Dts.TaskResult = ScriptResults.Success
Else
MsgBox("You need to select a folder!", MsgBoxStyle.Exclamation, "Error!")
Dts.TaskResult = ScriptResults.Failure
End If
End Sub
Of course, I've got "variable" set as a "ReadWriteVariables" in the Script Task Editor, and the "Imports System.Windows.Forms" at the top of my VB file.
When I run the task it just sits there yellow (as if it's running), but never shows the dialog. There's never even an error, it just sits there. I can run the same code within a standard windows application project no problem.
Not sure what's going on here. On know one quirk of showing an OpenFileDialog is you have to set the ShowHelp property to True, so I'm wondering if there's another quirk to getting this to run. Google only mostly shows me an old problem where the folder tree is blank, but I'm not even getting the prompt. Any help would be much appreciated.
I know it's a little bit late but I came across this Problem and found a fix for this. (Using C#)
You need to use the "OpenFileDialog" instead of the "FolderBrowserDialog" and you need to set a few adjustments. Here is a sample code which opens the explorer and lets you pick a folder:
public void Main()
{
string myPath="";
OpenFileDialog folderBrowser = new OpenFileDialog();
folderBrowser.ValidateNames = false;
folderBrowser.CheckFileExists = false;
folderBrowser.CheckPathExists = true;
folderBrowser.FileName = "Folder Selection.";
folderBrowser.ShowHelp = true;
if (folderBrowser.ShowDialog() == DialogResult.OK)
{
myPath = Path.GetDirectoryName(folderBrowser.FileName);
}
else
{
MessageBox.Show("Error selecting path");
}
Dts.Variables["User::varFolderPath"].Value = myPath;
Dts.TaskResult = (int)ScriptResults.Success;
}
The most important statement is the "folderBrowser.ShowHelp = true" statement. If this assignment isn't made you'll get the same problem as in your question.
You also need the statements above to "trick" the Dialog so you can select a Folder instead of a File.
I hope I can help you or people with the same problem but you should pass in the folder as a variable into the package as "N West" said.
Consider following:
I have an Admin sub site which have all lists and Document Libraries, I provision most of Document Libraries in the Root web programmatically using XlstViewWebPart, when I try to select an item and delete it using delete button on the ribbon I get:
The server has encountered the following error(s):
List does not exist. The page you selected contains a list that does not exist. It may have been deleted by another user.
But if delete the item from item popup menu, it is working fine and deleted !!!!
Platform: SharePoint Server 2010 SP1, VS 2010, CU June 2012
Thanks in advance
========================================
Update (My Code to provision web parts)
Dim _web As SPWeb = SPContext.Current.Site.RootWeb
Try
'Get refrence to publishing web
Dim _pubWeb As PublishingWeb = PublishingWeb.GetPublishingWeb(_web)
Dim WPM As Microsoft.SharePoint.WebPartPages.SPLimitedWebPartManager
If _pubWeb IsNot Nothing Then
'Loop each publishing page in the web
'Check out the file
'If the current page have CustomWebPart (It is an Custom System Page), Then
'If XsltListViewWebPart is not provisiond (double check in case of click the button more than one time), then
'Create an XsltListViewWebPart
'Assign properties of the new XsltListViewWebPart with Document Lib. Name and Admin web
'Add the new XsltListViewWebPart to the current page in the loop
For Each curPage As PublishingPage In _pubWeb.GetPublishingPages()
If curPage.ListItem.File.RequiresCheckout AndAlso curPage.ListItem.File.CheckOutType = SPFile.SPCheckOutType.None Then curPage.CheckOut()
WPM = curPage.ListItem.File.GetLimitedWebPartManager(System.Web.UI.WebControls.WebParts.PersonalizationScope.Shared)
Dim CustomWebPart As CustomWebPart = WPM.WebParts.OfType(Of CustomWebPart)().FirstOrDefault()
If CustomWebPart IsNot Nothing Then
If CustomWebPart.DocLibName.ToLower = Constants.List.MeetingSchedular.ListName.ToLower Then Continue For
Dim web As SPWeb = _web.Site.RootWeb.Webs(Constants.WebNames.AdminWeb) 'Get Admin Web
Dim LVWP As WebPartPages.XsltListViewWebPart = WPM.WebParts.OfType(Of WebPartPages.XsltListViewWebPart)().FirstOrDefault()
If LVWP Is Nothing Then
LVWP = New WebPartPages.XsltListViewWebPart
Dim lst As SPList = web.Lists(CustomWebPart.DocLibName)
With LVWP
.WebId = web.ID
.ViewGuid = lst.DefaultView.ID.ToString("B").ToUpper()
.ListName = lst.ID.ToString("B").ToUpper()
.ListId = lst.ID
.ListUrl = "/Admin/" + CustomWebPart.DocLibName
.TitleUrl = "/Admin/" + CustomWebPart.DocLibName
.ChromeType = System.Web.UI.WebControls.WebParts.PartChromeType.None
.AllowClose = False
.AllowEdit = True
.AllowMinimize = True
.AllowConnect = True
End With
_web.AllowUnsafeUpdates = True
WPM.AddWebPart(LVWP, "MainZone", 0)
curPage.Update()
_web.AllowUnsafeUpdates = False
End If
curPage.CheckIn("By cmdProvisionWebParts_Click")
curPage.ListItem.File.Publish("By cmdProvisionWebParts_Click")
End If
Next
End If
RegisterNotification("Provision Web Parts Completed successfully")
Catch ex As Exception
SiteHelper.WriteErrors("Custom_Settings.ProvisioningRootWebParts", ex)
RegisterNotification("Error: " + ex.Message)
End Try
Maybe, the error happens because your list belongs to another site (or subsite) and SP says you, that it doesn't have the list.
Try to create the list in your site and delete again.
And if it wouldn't work, please show us your XlstViewWebPart code.
Im working with vb.net and microsoft word using Microsoft.Office.Interop.Word and everything is fine. My only problem is I cant find a way to change the default page size printing setting from "letter" to "A4".
This code was doing the job for Crystal reports but isnt doing it for Word
Dim pp As New System.Drawing.Printing.PrintDocument
For i = 0 To pp.DefaultPageSettings.PrinterSettings.PaperSizes.Count - 1
If pp.DefaultPageSettings.PrinterSettings.PaperSizes.Item(i).Kind = System.Drawing.Printing.PaperKind.A4 Then
pp.DefaultPageSettings.PaperSize = pp.DefaultPageSettings.PrinterSettings.PaperSizes.Item(i)
Exit For
End If
Next
You should change the PaperSize of the PageSetup interface on your Word Document instance.
Imports Microsoft.Office.Interop.Word
....
Dim myWordApp as Application = New Application();
Dim myWordDoc As Document = myWordApp.Documents.Open("your_file_name_here")
myWordDoc.PageSetup.PaperSize = WdPaperSize.wdPaperA4
Ref: http://social.msdn.microsoft.com/forums/en-US/vsto/thread/45152591-1f3e-4d1e-b767-ef030be9d9f2
Since page size can vary from section to section, the best thing is to set the PageSetup properties of the Document.Section object. For example, you can loop through all the sections of the document:
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
Application app = Globals.ThisAddIn.Application;
Word.Document doc = app.ActiveDocument;
foreach (Section section in doc.Sections)
{
section.PageSetup.PaperSize = WdPaperSize.wdPaperA4;
}
}
Adding locic to set paper size when a document is created or opened is up to you, I'm guessing you'll need to determine if the document being opened has purposely been saved in a non-A4 size.
EDIT: This does work, I dont know what you mean with the comment ThisAddIn isnt a member or Globals and ActiveDocument isnt a member of Application in VB.NET - you cant skip these top two lines, here is the VB.Net version:
Private Sub ThisAddIn_Startup(sender As Object, e As System.EventArgs)
Dim app As Application = Globals.ThisAddIn.Application
Dim doc As Word.Document = app.ActiveDocument
For Each section As Section In doc.Sections
section.PageSetup.PaperSize = WdPaperSize.wdPaperA4
Next
End Sub
All you need to do is > Visual Studio > Create a New Prorject > Office > Word 2010 (or 2007) Add-In and paste in the above code. Here is a screenshot showing it works with A4 and Letter:
The only issue you may face is when the Printer doesn't have the size paper you get this error: Requested PaperSize is not available on the currently selected printer.
I'm posting another answer to this question because the accepted answer doesn't refresh the document or handle page orientation. So just in case someone needs this I find this to be a much better solution...
Microsoft.Office.Interop.Word.Application app = Globals.ThisAddIn.Application;
Microsoft.Office.Interop.Word.Document doc = app.ActiveDocument;
foreach (Section section in doc.Sections)
{
if(section.PageSetup.Orientation == WdOrientation.wdOrientLandscape)
{
section.PageSetup.PageWidth = 841.88976378F;
section.PageSetup.PageHeight = 595.275590551F;
}
else
{
section.PageSetup.PageWidth = 595.275590551F;
section.PageSetup.PageHeight = 841.88976378F;
}
}
I need to be able to save Presentations (programatically) in PowerPoint 2003 as OpenXML (".pptx").
I installed the Microsoft Office Compatibility Pack. This indeed allows me to perform "Save as PowerPoint 2007 Presentation" from PowerPoint 2003.
How can I do this programmatically? (e.g. VBA)
I tried Presentation.SaveAs:
While there is no inherent PpSaveAsFileType enum value in PowerPoint 2003 for ppSaveAsOpenXMLPresentation, I made a program which prints the PpSaveAsFileType values and found out that during run-time, ppSaveAsOpenXMLPresentation = 24.
However, I tried:
SaveAs(#"c:\temp\saveas\pupik.pptx", (PpSaveAsFileType) ((int) 24), MsoTriState.msoTrue);
And got an "Invalid Enumeration Value" Exception
Any ideas how to make this work?
(PS - I am aware that this question was already asked by several people on the web, but no solutions were offered.)
Thanks,
Arie
Edit > Some grammar
AFAIK the pptx format does not support macro-enabled presentations, so if your code is in the presentation you are trying to save, it will not work.
I don't have Excel 2003 at hand now, but if the Compatibility Pack enabled the option "pptx" in the Configuration Dialog, Default Save Format, and you are trying to save ANOTHER presentation I guess you can if you use something like:
MyOtherPresentation.SaveAs "C:\Mypres", ppSaveAsDefault
Please note that this may work only if the presentation had not been saved before in ppt format
EDIT
If the above doesn't work, you could try a different approach. Save the file in the old format and the call a conversion program:
ppcnvcom.exe
See here for an example (using wordconv.exe, but essentially the same)
Be sure to have all the office upgrades installed, because if not the program ends
reporting no error and doing nothing.
ofc
See here for instructions
And here for a good discussion
HTH!
A trick is to modify the default save format of the application in the Registry, then save and finally to restore the original save format again.
The relevant key is
Software\Microsoft\Office\11.0\PowerPoint\Options
Create a DWORD value with name DefaultFormat and set it to 0x21 to save as PPTX.
public void SomeMethod()
{
...
using (PptxSaver pptxSaver = new PptxSaver())
{
presentation.SaveAs("sample.pptx")
}
...
}
class PptxSaver : IDisposable
{
private const string OptionKey = #"Software\Microsoft\Office\11.0\PowerPoint\Options";
private const string OptionValue = "DefaultFormat";
private const int SaveFormatPptx = 0x21;
private int oldFormat;
public PptxSaver()
{
using (RegistryKey key = Registry.CurrentUser.OpenSubKey(OptionKey, true))
{
oldFormat = (int)key.GetValue(OptionValue, -1);
key.SetValue(OptionValue, SaveFormatPptx, RegistryValueKind.DWord);
}
}
public void Dispose()
{
// Delete the value
using (RegistryKey key = Registry.CurrentUser.OpenSubKey(OptionKey, true))
{
if (oldFormat == -1)
{
key.DeleteValue(OptionValue);
}
else
{
key.SetValue(OptionValue, oldFormat);
}
}
}
}
I used ppcnvcom.exe but note that unlike a considerable amount of posts I used only the -oice switch without the -nme switch
For VBA this works:
Sub TestSaveas()
SaveAs "c:\somefilepath\"
End sub
Private Sub SaveAs(fp As String)
Dim dlgSaveAs As FileDialog
Dim strMyFile As String
Set dlgSaveAs = Application.FileDialog(msoFileDialogSaveAs)
With dlgSaveAs
.InitialFileName = fp
If .Show = -1 Then
strMyFile = .SelectedItems(1)
Application.ActivePresentation.SaveAs strMyFile
'MsgBox strMyFile
''-- save your file to strMyFile here
Else
MsgBox "File not saved"
End If
End With
dlgSaveAs.Execute
Set dlgSaveAs = Nothing
End Sub
I know this is an old question, but I got around the problem recently using:
Presentation.SaveCopyAs "c:\temp\saveas\pupik.pptx"
instead of SaveAs. Works well, regardless wether the original is in ppt- or pptx-format.
(I could not get the registry-change method mentioned to work for me without reopening the presentation.)