0

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!

Jason247
  • 974
  • 4
  • 16
  • 38
  • You might want to modify your ShapeIsLinked function to return True *only* if the shape is an msoLinkedOLEObject. Also, what are you passing as excelWorkbookPath? Just the file path or are you including add'l bits like the chart name/range name etc? It'd be worth displaying SourceFullName for an existing linked chart/range so you can see what the full source path should look like, if you're not familiar with it already. – Steve Rindsberg Aug 17 '23 at 13:24
  • Good call on the add'l bits part. I was missing those originally. But it turns out my problem was that my excelWorkbookPath didn't point to an actual excel docuement. I was using a dummy path for testing, assuming that it wouldn't actual check to see that it existed before writing it and that it would only be a problem once I actually tried to open the powerpoint file. But no, the file must exist when saving it. Also, why do you suggest only looking at msoLinkedOLEObjects? I am linking to things like charts and images in the excel file. – Jason247 Aug 17 '23 at 15:14
  • 1
    Bingo. Yes, PPT checks to see if the file exists before it will create the link in the first place, and fails silently if not; that is, it won't throw any errors, so it's up to your code to check for existence of the file before trying to link to it. As to charts and anything else in the XL file ... those will all be OLE objects. And if you're setting links to the other stuff to point to an excel file, it'll fail. Maybe rewrite your ShapeIsLinked to let you pass a shape type as a parameter so it only returns true if the shape is linked AND is of the type you want to work with. – Steve Rindsberg Aug 19 '23 at 15:21

1 Answers1

0

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.

Jason247
  • 974
  • 4
  • 16
  • 38