0
votes

I've written/compiled a macro that opens an Excel file, creates a PowerPoint chart and populates the chart worksheet with data from a worksheet in the Excel file.

I'm trying to alter the macro to loop through the Excel file's worksheets and:

  1. for each worksheet create a PowerPoint slide and chart
  2. populate the PowerPoint chart with data from the worksheet in the Excel file

Presently when I run the macro, the first PowerPoint chart and slide is created correctly. The second slide is created for the Excel file's second worksheet but the PowerPoint chart is not created correctly. The workbook that I'm testing the macro on has two worksheets.

What is the correct way to dynamically reference each new PowerPoint slide? As of now I've been using:

Set pptWorkSheet = pptWorkBook.Worksheets(ActivePresentation.Slides.Count) 'sorta works-changed 8/19

When I go to the debugger it says ActivePresentation.Slides.Count = 2 so I am not sure as to why its not transferring the data to the second PowerPoint chart.

I also may not be referring to the Excel file worksheets correctly here:

pptWorkSheet.Range("a2:b5").Value = xlWB.ActiveSheet.Range("a2:b5").Value

Below is the full macro:

Sub CreateChartAllWKs()

'Create variables
    Dim myChart As Chart
    Dim pptChartData As ChartData
    Dim pptWorkBook As Excel.Workbook
    Dim pptWorkSheet As Excel.Worksheet
    Dim xlApp As Excel.Application
    Dim xlWB As Workbook
    Dim xlWS As Worksheet  

' Create new excel instance and open relevant workbook
    Set xlApp = New Excel.Application
    xlApp.Visible = True 'Make Excel visable
    Set xlWB = xlApp.Workbooks.Open("C:\filepath\ExcelData.xlsm", True, False)  'Open relevant workbook

'Loop through each worksheet in xlWB and transfer data to new pptWorkBook and
'create new PowerPoint chart
    For Each xlWS In ActiveWorkbook.Worksheets

        'Add a new slide where we will create the PowerPoint worksheet and chart
            ActivePresentation.Slides.Add ActivePresentation.Slides.Count + 1, ppLayoutText
            ActiveWindow.View.GotoSlide ActivePresentation.Slides.Count
            Set activeSlide = ActivePresentation.Slides(ActivePresentation.Slides.Count)

        ' Create the chart and set a reference to the chart data.
            Set myChart = activeSlide.Shapes.AddChart.Chart 'changed 8/19
            Set pptChartData = myChart.ChartData

        ' Set the PowerPoint Workbook and Worksheet references.
            Set pptWorkBook = pptChartData.Workbook
            Set pptWorkSheet = pptWorkBook.Worksheets(ActivePresentation.Slides.Count) 'sorta works-changed 8/19

        ' Add the data to the PowerPoint workbook.
            pptWorkSheet.ListObjects("Table1").Resize pptWorkSheet.Range("A1:B5")
            pptWorkSheet.Range("Table1[[#Headers],[Series 1]]").Value = "Items"
            pptWorkSheet.Range("a2:b5").Value = xlWB.ActiveSheet.Range("a2:b5").Value 'transfer data from ExcelWB to pptWorkSheet (i.e. the PowerPoint workbook)

        ' Apply styles to the chart.
            With myChart
                .ChartStyle = 4
                .ApplyLayout 4
                .ClearToMatchStyle
            End With

        ' Add the axis title.
            With myChart.Axes(xlValue)
                .HasTitle = True
                .AxisTitle.Text = "Units" 
            End With

        'Apply data labels
            myChart.ApplyDataLabels
   Next xlWS

' Clean up the references.
    Set pptWorkSheet = Nothing
' pptWorkBook.Application.Quit
    Set pptWorkBook = Nothing
    Set pptChartData = Nothing
    Set myChart = Nothing
'Clean up Excel references.
    Set xlApp = Nothing
'Option to close excel workbook
    'ExcelWB.Close
End Sub
1
are running this code from PowerPoint ?Shai Rado
Yes @ShaiRado, I am running it through PowerPoint.RTrain3k

1 Answers

2
votes

I think the problem you are running into is how PowerPoint and Excel store slide numbers and worksheet numbers. PowerPoint at least 3 different attributes with Slides, including "Slide IDs", "Slide Indexes" and "Slide Numbers". They are all different and make things a pain when you are trying to reference them. What I like to do is actually set the reference of the slide right when I am creating the slide:

Set CurSlide = ActivePresentation.Slides.Add(ActivePresentation.Slides.Count + 1, ppLayoutText)

This way right when you create the slide you now have a reference to it.

Additionally I find that using a number as a worksheet reference can also cause issues since if you reference the 5th worksheet it may not be the 5th worksheet at all. You have to look in the VBA editor of Excel to see what sheet gets what reference. However if you are able to refer to the worksheet name such as "Sheet1", "Sheet2", "OtherWorksheet" etc. You can make things a lot easier. To put this a little more in perspective if you make a sheet named "5" and then call the worksheet with.

Set ws = ActiveWorkBook.WorkSheets(5)

It will not work. You would need to use

Set ws = ActiveWorkBook.Worksheets("5")

Hopefully that makes sense. This part is not necessary but it makes debugging a lot easier if you do run into issues. The way I would recommend to do this is not in my code below because I don't have your workbook.

Set PPtWorkSheet = pptWorkBook.Worksheets("Sheet" & CurSlide.SlideIndex) 

I re-wrote a few lines of your code and I was able to get it to work. However I do not have a copy of your workbook so I am not 100% sure this would work. Consider changing the worksheet names on your workbook if you still have trouble referencing the worksheet from the slide Index.

The revised code is below let me know if you have any questions.

Sub CreateChartAllWKs()

'Create variables
        Dim myChart As Chart
        Dim pptChartData As ChartData
        Dim pptWorkBook As Excel.Workbook
        Dim pptWorkSheet As Excel.Worksheet
        Dim xlApp As Excel.Application
        Dim xlWB As Excel.Workbook
        Dim xlWS As Excel.Worksheet
        Dim CurSlide As Slide 'new from update

' Create new excel instance and open relevant workbook
        Set xlApp = New Excel.Application
        xlApp.Visible = True 'Make Excel visable
        Set xlWB = xlApp.Workbooks.Open("C:\filepath\ExcelData.xlsm", True, False)  'Open relevant workbook

'Loop through each worksheet in xlWB and transfer data to new pptWorkBook and
'create new PowerPoint chart
        For Each xlWS In ActiveWorkbook.Worksheets

                'Add a new slide where we will create the PowerPoint worksheet and chart
                        'Set CurSlide = ActivePresentation.Slides.Add ActivePresentation.Slides.Count + 1, ppLayoutText
                        ActiveWindow.View.GotoSlide ActivePresentation.Slides.Count
'This is my recommendation
                        Set CurSlide = ActivePresentation.Slides.Add(ActivePresentation.Slides.Count + 1, ppLayoutText)

                ' Create the chart and set a reference to the chart data.
                        Set myChart = CurSlide.Shapes.AddChart.Chart 'changed 8/19
                        Set pptChartData = myChart.ChartData

                ' Set the PowerPoint Workbook and Worksheet references.
                        Set pptWorkBook = pptChartData.Workbook
                        Set pptWorkSheet = pptWorkBook.Worksheets(CurSlide.SlideIndex) 'From Update

                ' Add the data to the PowerPoint workbook.
                        pptWorkSheet.ListObjects("Table1").Resize pptWorkSheet.Range("A1:B5")
                        pptWorkSheet.Range("Table1[[#Headers],[Series 1]]").Value = "Items"
                        pptWorkSheet.Range("a2:b5").Value = xlWB.ActiveSheet.Range("a2:b5").Value 'transfer data from ExcelWB to pptWorkSheet (i.e. the PowerPoint workbook)

                ' Apply styles to the chart.
                        With myChart
                                .ChartStyle = 4
                                .ApplyLayout 4
                                .ClearToMatchStyle
                        End With

                ' Add the axis title.
                        With myChart.Axes(xlValue)
                                .HasTitle = True
                                .AxisTitle.Text = "Units"
                        End With

                'Apply data labels
                        myChart.ApplyDataLabels
     Next xlWS

' Clean up the references.
        Set pptWorkSheet = Nothing
' pptWorkBook.Application.Quit
        Set pptWorkBook = Nothing
        Set pptChartData = Nothing
        Set myChart = Nothing
'Clean up Excel references.
        Set xlApp = Nothing
'Option to close excel workbook
        'ExcelWB.Close
End Sub