使用VBA将带有数据的Excel图表粘贴到PowerPoint中

时间:2016-05-05 21:46:32

标签: excel vba charts powerpoint

答案:TL; DR:使用嵌入数据粘贴图表需要很长时间,因此必须安装延迟以防止vba在粘贴操作完成之前继续运行。

问题:我正在尝试将带有嵌入数据的Excel图表粘贴到powerpoint演示文稿中。我唯一能挂掉的就是在粘贴图表后将图表引用到ppt中。

    Dim newPowerPoint As PowerPoint.Application

    ActiveSheet.ChartObjects("Chart 1").Activate
    ActiveChart.ChartArea.Copy
    newPowerPoint.CommandBars.ExecuteMso ("PasteExcelChartDestinationTheme")

由于我需要将多个图表粘贴到单个幻灯片中,因此需要重新定位它们。我试着用这段代码做到这一点:

        newPowerPoint.ActiveWindow.Selection.ShapeRange.Left = 0

但总是遇到错误:“对象'选择'的方法'ShapeRange'失败”。

特别奇怪的是,从头到尾运行代码会导致此错误,但使用F8键单步执行代码则不会。

我已经尝试了各种方法来移动这张图表,但我完全陷入困境。有谁知道我怎么做到这一点?此外,请记住,图表中有数据是必要的(我不能将图表粘贴为图片,我更希望数据不被链接)。

谢谢,

史蒂夫

使用多个图表对象编辑新修改的代码。我需要添加一个if条件:

If activeSlide.Shapes.Count = 1 Then
GoTo NextiLoop
End If

对于其他图表对象,因为图表2的延迟使得循环名称图表1“pptcht2”,因为chart2尚不存在。

Sub CreatePPT()

 Dim newPowerPoint As PowerPoint.Application
  Dim activeSlide As PowerPoint.Slide
  Dim cht1 As Excel.ChartObject
  Dim Data As Excel.Worksheet
  Dim pptcht1 As PowerPoint.Shape
  Dim iLoopLimit As Long

  Application.ScreenUpdating = False

  'Look for existing instance
  On Error Resume Next
  Set newPowerPoint = GetObject(, "PowerPoint.Application")
  On Error GoTo 0

  'Let's create a new PowerPoint
  If newPowerPoint Is Nothing Then
    Set newPowerPoint = New PowerPoint.Application
  End If

  'Make a presentation in PowerPoint
  If newPowerPoint.Presentations.Count = 0 Then
  newPowerPoint.Presentations.Add
  End If

  'Show the PowerPoint
  newPowerPoint.Visible = True
  Application.ScreenUpdating = False

  'Add a new slide where we will paste the chart
  newPowerPoint.ActivePresentation.Slides.Add _
      newPowerPoint.ActivePresentation.Slides.Count + 1, ppLayoutText
  newPowerPoint.ActiveWindow.View.GotoSlide _
      newPowerPoint.ActivePresentation.Slides.Count
  Set activeSlide = newPowerPoint.ActivePresentation.Slides _
      (newPowerPoint.ActivePresentation.Slides.Count)
  activeSlide.Shapes(1).Delete
  activeSlide.Shapes(1).Delete

  'ActiveSheet.ChartObjects("Chart 1").Activate
  Set Data = ActiveSheet

  Set cht1 = Data.ChartObjects("Share0110")
  Set cht2 = Data.ChartObjects("SOW0110")
  Set cht3 = Data.ChartObjects("PROP0110")

  cht1.Copy

  newPowerPoint.CommandBars.ExecuteMso "PasteExcelChartDestinationTheme"

  DoEvents

  On Error Resume Next
  Do
    DoEvents
    Set pptcht1 = activeSlide.Shapes(activeSlide.Shapes.Count)
    If Not pptcht1 Is Nothing Then Exit Do
    iLoopLimit = iLoopLimit + 1
    If iLoopLimit > 100 Then Exit Do
  Loop
  On Error GoTo 0

  Debug.Print "iLoopLimit = " & iLoopLimit

  With pptcht1
    .Left = 25
    .Top = 150
  End With

  iLoopLimit = 0

   'ActiveSheet.ChartObjects("Chart 2").Activate
  'Set Data = ActiveSheet

  cht2.Copy

  newPowerPoint.CommandBars.ExecuteMso "PasteExcelChartDestinationTheme"

  DoEvents
  On Error Resume Next
  Do
    DoEvents

    If activeSlide.Shapes.Count = 1 Then
    GoTo NextiLoop
    End If
    Set pptcht2 = activeSlide.Shapes(activeSlide.Shapes.Count)
    If Not pptcht2 Is Nothing Then Exit Do
NextiLoop:
    iLoopLimit = iLoopLimit + 1
    If iLoopLimit > 100 Then Exit Do
  Loop
  On Error GoTo 0

  Debug.Print "iLoopLimit = " & iLoopLimit

  With pptcht2
    .Left = 275
    .Top = 150
  End With

  iLoopLimit = 0

    AppActivate ("Microsoft PowerPoint")
    Set activeSlide = Nothing
    Set newPowerPoint = Nothing

End Sub

编辑:OLD无法正常工作的代码:

    Sub CreatePPT()

        Dim newPowerPoint As PowerPoint.Application
        Dim activeSlide As PowerPoint.Slide
        Dim cht As Excel.ChartObject

        Application.ScreenUpdating = False


     'Look for existing instance
        On Error Resume Next
        Set newPowerPoint = GetObject(, "PowerPoint.Application")
        On Error GoTo 0

    'Let's create a new PowerPoint
        If newPowerPoint Is Nothing Then
            Set newPowerPoint = New PowerPoint.Application
        End If

    'Make a presentation in PowerPoint
        If newPowerPoint.Presentations.Count = 0 Then
            newPowerPoint.Presentations.Add
        End If

    'Show the PowerPoint
        newPowerPoint.Visible = True
        Application.ScreenUpdating = False

        'Add a new slide where we will paste the chart
            newPowerPoint.ActivePresentation.Slides.Add newPowerPoint.ActivePresentation.Slides.Count + 1, ppLayoutText
            newPowerPoint.ActiveWindow.View.GotoSlide newPowerPoint.ActivePresentation.Slides.Count
            Set activeSlide = newPowerPoint.ActivePresentation.Slides(newPowerPoint.ActivePresentation.Slides.Count)
                    activeSlide.Shapes(1).Delete
                    activeSlide.Shapes(1).Delete



            'ActiveSheet.ChartObjects("Chart 1").Activate
            Set Data = ActiveSheet
            Set cht1 = Data.ChartObjects("Chart 1")
            cht1.Copy

            newPowerPoint.CommandBars.ExecuteMso ("PasteExcelChartDestinationTheme")

            Set pptcht1 = newPowerPoint.ActiveWindow.Selection
                With pptcht1
                    .Left = 0
                    End With




    AppActivate ("Microsoft PowerPoint")
    Set activeSlide = Nothing
    Set newPowerPoint = Nothing

End Sub

1 个答案:

答案 0 :(得分:1)

  1. 帮自己一个忙,并将其作为代码模块的第一行输入:
  2. Option Explicit

    这将强制您声明所有变量。你有很多未声明的变量,包括几个与你声明的几个变量几乎相同的变量。然后转到VBA的工具菜单>选项,并在对话框的第一个选项卡上选中需要变量声明,这将Option Explicit放在每个新模块的顶部。

    1. 将形状声明为PowerPoint.Shape,然后使用此方法找到它,因为任何新添加的形状都是幻灯片中的最后一个:
    2. Set pptcht1 = activeSlide.Shapes(activeSlide.Shapes.Count)

      1. 以下第一行首先不需要括号,尽管Microsoft帮助文章写得不好。其次,运行需要很长时间。 Excel已经尝试在创建形状之前很久就移动形状。 DoEvents应该通过使Excel等到计算机上发生的其他事情完成来帮助解决这个问题,但是线路仍然太慢。
      2. newPowerPoint.CommandBars.ExecuteMso ("PasteExcelChartDestinationTheme")

        所以我拼凑了一个小循环,尝试将变量设置为形状,并保持循环直到形状完成创建。

        On Error Resume Next
        Do
          DoEvents
          Set pptcht1 = activeSlide.Shapes(activeSlide.Shapes.Count)
          If Not pptcht1 Is Nothing Then Exit Do
          iLoopLimit = iLoopLimit + 1
          If iLoopLimit > 100 Then Exit Do
        Loop
        On Error GoTo 0
        

        在少数测试中,我发现循环必须运行20到60次。我也曾几次崩溃过PowerPoint。怪异。

        我确定有更好的方法来粘贴复制的图表并保留幻灯片的颜色主题,但我不知道其中的一个。

        1. 这是不可靠的,因为应用程序标题随Office的不同版本而变化(并且不再需要括号):
        2. AppActivate ("Microsoft PowerPoint")

          请改用:

          AppActivate newPowerPoint.Caption

          1. 所以你的整个代码变成了:
          2. `Sub CreatePPT()

              Dim newPowerPoint As PowerPoint.Application
              Dim activeSlide As PowerPoint.Slide
              Dim cht1 As Excel.ChartObject
              Dim Data As Excel.Worksheet
              Dim pptcht1 As PowerPoint.Shape
              Dim iLoopLimit As Long
            
              Application.ScreenUpdating = False
            
              'Look for existing instance
              On Error Resume Next
              Set newPowerPoint = GetObject(, "PowerPoint.Application")
              On Error GoTo 0
            
              'Let's create a new PowerPoint
              If newPowerPoint Is Nothing Then
                Set newPowerPoint = New PowerPoint.Application
              End If
            
              'Make a presentation in PowerPoint
              If newPowerPoint.Presentations.Count = 0 Then
              newPowerPoint.Presentations.Add
              End If
            
              'Show the PowerPoint
              newPowerPoint.Visible = True
              Application.ScreenUpdating = False
            
              'Add a new slide where we will paste the chart
              newPowerPoint.ActivePresentation.Slides.Add _
                  newPowerPoint.ActivePresentation.Slides.Count + 1, ppLayoutText
              newPowerPoint.ActiveWindow.View.GotoSlide _
                  newPowerPoint.ActivePresentation.Slides.Count
              Set activeSlide = newPowerPoint.ActivePresentation.Slides _
                  (newPowerPoint.ActivePresentation.Slides.Count)
              activeSlide.Shapes(1).Delete
              activeSlide.Shapes(1).Delete
            
              'ActiveSheet.ChartObjects("Chart 1").Activate
              Set Data = ActiveSheet
              Set cht1 = Data.ChartObjects("Chart 1")
              cht1.Copy
            
              newPowerPoint.CommandBars.ExecuteMso "PasteExcelChartDestinationTheme"
            
              DoEvents
            
              On Error Resume Next
              Do
                DoEvents
                Set pptcht1 = activeSlide.Shapes(activeSlide.Shapes.Count)
                If Not pptcht1 Is Nothing Then Exit Do
                iLoopLimit = iLoopLimit + 1
                If iLoopLimit > 100 Then Exit Do
              Loop
              On Error GoTo 0
            
              Debug.Print "iLoopLimit = " & iLoopLimit
            
              With pptcht1
                .Left = 0
              End With
            
              AppActivate newPowerPoint.Caption
              Set activeSlide = Nothing
              Set newPowerPoint = Nothing
            
            End Sub`