Question

I am attempting to store xml metadata within chart shapes in a PowerPoint presentation.

I need to ensure that the shape only contains the current xml data, so I have a function to delete existing data (if any) and add the current data.

Sub Test()
Dim cht as Chart
Dim xml as String
Set cht = ActivePresentation.Slides(1).Shapes(1)
xml = "<Chart property1='true' property2='false'>blah blah blah</Chart>"

    EmbedChartXML xml, cht

End Sub

Sub EmbedChartXML(xml As String, cht As Shape)
Dim x As Variant

    'Get rid of any previous data
    For Each x In cht.CustomerData
        x.Delete
    Next

    Set xmlPart = cht.CustomerData.Add

    xmlPart.LoadXML xml
End Sub

The For Each loop is failing with the indicated error message. I can see that the cht.CustomerData.Count = 2 (for example), but if I try to view this in the Locals window, I get the same error.

enter image description here

UPDATE

Here is another test routine that is failing, even though there is nothing inside the For/Next loop.

Sub TestIteration()
Dim sld As Slide
Dim pres As Presentation
Dim shp As Shape
Dim x As CustomXMLPart

Set pres = ActivePresentation
Set sld = pres.Slides(2)

For Each shp In sld.Shapes

    Set pptCustomerData = shp.CustomerData

    For Each x In shp.CustomerData

'    For Each pptCustomXMLPart In pptCustomerData
'        Debug.Print pptCustomXMLPart.Id
'    Next
    Next
Next


End Sub
Was it helpful?

Solution

Others here cannot replicate this error in Excel 2013 (I am using Excel 2010) where the collection object itself becomes inaccessible. Perhaps there is a bug or something, but I could not find much on Google about similar errors...

I ultimately arrive at this solution. I am not sure why the CustomXMLPart's .Delete method doesn't actually delete the item from the collection (instead it makes it to Nothing, and then failure on successive iteration attempts).

Instead, I use the CustomerData.Delete method. This seems to be working as expected.

Sub EmbedChartXML(xml As String, cht As Shape)
Dim x As Variant
Dim cData As CustomerData

Dim xID As String

    Set cData = cht.CustomerData
    Debug.Print cht.CustomerData.Count

    'Get rid of any previous data
    For Each x In cData
        xID = x.Id
        cData.Delete xID
    Next

    With cData.Add
        .LoadXML xml
    End With

    Debug.Print cht.CustomerData.Count
End Sub
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top