I am building automated reporting using excel and PowerPoint templates that I am editing in c# before saving to a new file path. My PowerPoint template has objects imbedded that are linked to the excel template (think cell ranges and charts). I would like to programmatically update the excel file that these objects are linked to. This would be equivalent to going into the PowerPoint document, clicking File -> Info -> Edit Links to Files -> Change Source.
I am currently attempting this with the NetOfficeFw.PowerPoint library, but I have so far been unsuccessful. Here is an example of my latest attempt:
public void UpdateLinks(string templatePath, string excelWorkbookPath)
{
var application = new PowerPoint.Application();
var presentation = application.Presentations.Open(templatePath, MsoTriState.msoFalse);
foreach (PowerPoint.Slide slide in presentation.Slides)
{
foreach (var shape in slide.Shapes)
{
if (ShapeIsLinked(shape))
{
shape.LinkFormat.SourceFullName = excelWorkbookPath;
}
}
}
}
private bool ShapeIsLinked(PowerPoint.Shape shape)
{
return shape.Type == MsoShapeType.msoLinkedPicture
|| shape.Type == MsoShapeType.msoLinked3DModel
|| shape.Type == MsoShapeType.msoLinkedGraphic
|| shape.Type == MsoShapeType.msoLinkedOLEObject;
}
This throws the error:
NetOffice.Exceptions.PropertySetCOMException (0x80004005): Failed to proceed PropertySet on PowerPoint.LinkFormat=>SourceFullName. ---> System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.Runtime.InteropServices.COMException: LinkFormat.SourceFullName : Failed.
I am open to other libraries if needed, but preferably open source or cheaper options that could accomplish this. Thanks!
So I figured out that the excel path you pass to SourceFullName must be to an existing file. I was passing a dummy path for testing just to see if it would actually update the path, and I assumed that it wouldn't check to see if the file existed until I actually attempted to open the powerpoint file and update links. That is not the case, it requires a path to an existing file.