Working on an Add-in that supports Microsoft Office’s Word, Excel and PowerPoint. One would think that being all three products being Office applications that programming against them would be nice and simple. How wrong I could be…

(Note: Using C# doesn’t help either :P)

Here’s an example of opening a document and marking it as saved in all three products:

Word

object filePath = "c:\temp\doc1.docx";
object missingValue = Type.Missing;
object falseValue = false;
object trueValue = true;

var doc = 
	_AddIn.Application.Documents.Open(ref filePath, ref missingValue, ref falseValue, 
	ref missingValue, ref missingValue, ref missingValue, ref missingValue, 
	ref missingValue, ref missingValue, ref missingValue, ref missingValue, 
	ref missingValue, ref missingValue, ref missingValue, ref missingValue, 
	ref missingValue);
doc.Saved = false;
 

Excel

object filePath = "c:\temp\book1.xlsx";
object missingValue = Type.Missing;
object falseValue = false;
object trueValue = true;

var doc = 
	_AddIn.Application.Workbooks.Open(filePath, missingValue, false, missingValue, 
		missingValue, missingValue, missingValue, missingValue, missingValue, 
		true, missingValue, missingValue, true, missingValue, missingValue);
doc.Saved = false;

PowerPoint

var filePath = "C:\temp\Presentation1.pptx";

var doc = _AddIn.Application.Presentations.Open(filePath, MsoTriState.msoFalse, MsoTriState.msoFalse, MsoTriState.msoTrue);
doc.Saved = MsoTriState.msoFalse;

Here’s sample code to try save in each product and if it’s new to popup the Save As dialog

Word

public void MySave()
{
	var doc = _AddIn.Application.ActiveDocument;
	doc.Saved = false;
	try
	{
		// Word automatically detects if a document has been saved to disk already
		// and popups up the SaveAs dialog if it is not
		doc.Save();
	}
	catch (COMException ex)
	{
		if (ex.ErrorCode == -2146824090)
		{
			// No problem, user just cancelled out of the save as dialog
			return;
		}
	}
}
 

Excel

public void MySave()
{
	// Try to save the document first
	var doc = _AddIn.Application.ActiveWorkbook;
	doc.Saved = false;
	
	var filePath = doc.FullName;
	var name = doc.Name;
	var path = doc.Path;

	// If it's already saved then save, otherwise popup the SaveAs
	if (File.Exists(filePath))
	{
		doc.Save();
		doc.Saved = true;
	}
	else
	{
		filePath = _AddIn.Application.GetSaveAsFilename(
					name,
					"Microsoft Excel File (*.xls), *.xls", 
					// Note there are heaps more file types in the default save as dialog
					missingValue,
					"Save As",
					missingValue).ToString();
		// Note: this doesn't actually save the file for you but tells you a path
		doc.SaveAs(filePath, XlFileFormat.xlOpenXMLWorkbook, Type.Missing, 
				Type.Missing, Type.Missing, Type.Missing, 
				XlSaveAsAccessMode.xlNoChange, Type.Missing, 
				Type.Missing, Type.Missing, Type.Missing, Type.Missing);
}

PowerPoint

 
public void MySave()
{
	var doc = _AddIn.Application.ActivePresentation;
	var filePath = doc.FullName;
	var name = doc.Name;
	var path = doc.Path;
	
	// Check if the file has bee saved already, if not then show the Save As dialog
	if (File.Exists(filePath))
	{
		doc.Save();
		doc.Saved = MsoTriState.msoTrue;
	}
	else
	{
		var dialog = _AddIn.Application.get_FileDialog(MsoFileDialogType.msoFileDialogSaveAs);
		int i = dialog.Show();
		dialog.Execute();
	
		// Note: this dialog actually does save the file for you
		if (((FileDialogSelectedItems)dialog.SelectedItems).Count == 0)
		{
			return;
		}

		filePath = ((FileDialogSelectedItems)dialog.SelectedItems).Item(1);
		name = filePath.Substring(filePath.LastIndexOf("\\") + 1);
		path = filePath.Substring(0, filePath.LastIndexOf("\\"));

		_AddIn.Application.ActivePresentation.SaveAs(filePath,
			PowerPoint.PpSaveAsFileType.ppSaveAsPresentation, 
			Office.MsoTriState.msoTrue); 
	}
 }

I can only hope things get better in Office 2010, but I’m dreaming aren’t I?

Comment