【问题标题】:Copy Powerpoint Shapes to Excel - identically looking slides, different shape order将 Powerpoint 形状复制到 Excel - 外观相同的幻灯片,不同的形状顺序
【发布时间】:2018-06-20 18:14:03
【问题描述】:

我有一个包含 32 张外观相同的幻灯片的演示文稿(最初是宏生成的,后来有了人情味)。

简化外观:

标题(但未格式化为标题)
图片
内容1
内容2
内容3

我现在想将文本复制回 Excel。尽管所有幻灯片看起来都相同,但 slide.Shapes 中形状的顺序似乎不同。

对于每张幻灯片,我想要一行,列的顺序相同:
Title, Content1, Content2,Content3
但有些是
Content1,Content3,Title,Content2 (或任何其他顺序)

这是为什么?

我的代码:

    Sub CopyFromPowerpoint()

        'Prepare variables
        Dim PowerPoint As PowerPoint.Application
        Dim activeSlide As PowerPoint.Slide
        Dim curShape As PowerPoint.shape
        Dim RowCounter As Integer
        Dim ColumnCounter As Integer
        Dim tmp As String

        'Set powerPoint
        Set PowerPoint = GetObject(, "PowerPoint.Application")

        tmp = "XXX" 'this should never be pasted
        RowCounter = 1
        ColumnCounter = 1
        For Each Slide In PowerPoint.Presentations(1).Slides
        Set activeSlide = PowerPoint.Presentations(1).Slides(RowCounter)
            For Each shape In activeSlide.Shapes
                Set curShape = activeSlide.Shapes(ColumnCounter)
                If curShape.TextFrame.HasText Then tmp = curShape.TextFrame.TextRange
                If curShape.TextFrame.HasText Then Worksheets("nameofsheet").Cells(RowCounter, ColumnCounter).Value = tmp
                ColumnCounter = ColumnCounter + 1
            Next
            ColumnCounter = 1
            RowCounter = RowCounter + 1
         Next


End Sub

【问题讨论】:

  • 如果您问为什么顺序会发生变化,答案将是这是对象的创建或操作方式的结果。如果您要问如何处理它,那么答案是您需要其他方法来识别哪个对象是哪个对象。也许在幻灯片上的位置?
  • 谢谢。正是我的两个问题。那么形状数组是由“上次编辑”跟踪的吗?我在网上找不到那个。将尝试解决位置问题。
  • @SLLegendre 不,不是最后一次编辑,但某些类型的编辑(向前/向后/向后/向前发送)会改变顺序。正如克里斯建议的那样,一种唯一识别形状的方法会有所帮助。创建形状时,您可以添加一个 .Tag,其名称/值可以识别它,然后当您复制形状时,返回具有给定标签的形状的函数会将您返回的形状返回给您。在我维护的 PPT faq 中有更多的细节和示例代码:标签pptfaq.com/…

标签: vba excel powerpoint


【解决方案1】:

最终帮助我的是将每个文本框的左侧和顶部位置相乘。该值足够独特,相关内容最终会出现在每张幻灯片的同一列中。在 Excel 中对列本身进行排序,我仍然需要手动完成,但这是一项简单的任务。我从另一个stackoverflow question得到的快速排序算法

Sub CopyFromPowerpoint()

        'Prepare variables
        Dim PowerPoint As PowerPoint.Application
        Dim activeSlide As PowerPoint.Slide
        Dim curShape As PowerPoint.shape
        Dim RowCounter As Integer
        Dim ColumnCounter As Integer
        Dim shapeCounter As Long
        Dim tmp(20) As String
        Dim arr(20) As Long
        Dim tmpMult As Long

        'Set powerPoint
        Set PowerPoint = GetObject(, "PowerPoint.Application")

        RowCounter = 1
        ColumnCounter = 1
        For Each Slide In PowerPoint.Presentations(1).Slides
        Set activeSlide = PowerPoint.Presentations(1).Slides(RowCounter)

           'Loop through shapes, note their position from top and left, multiply them and sort it
            shapeCounter = LBound(arr)
            For Each shape In activeSlide.Shapes
                arr(CInt(shapeCounter)) = shape.Top * shape.Left
                shapeCounter = shapeCounter + 1
            Next
            Call QuickSort(arr, LBound(arr), UBound(arr))



            'Loop through shapes again and copy shape text into relevant position in text array
            For Each shape In activeSlide.Shapes
            If shape.TextFrame.HasText Then
                For i = LBound(arr) To UBound(arr)
                    tmpMult = shape.Top * shape.Left
                    If arr(i) = tmpMult Then tmp(i) = shape.TextFrame.TextRange
                    tmpMult = 0
                Next i
            End If

            Next

            'Loop through text array and paste into worksheet
            For i = LBound(tmp) To UBound(tmp)
                Worksheets("uebergabe").Cells(RowCounter, i + 1).Value = tmp(i)
            Next i

            'Reset for next slide
            RowCounter = RowCounter + 1
            shapeCounter = 0
            For i = LBound(arr) To UBound(arr)
                arr(i) = 0
                tmp(i) = ""
            Next i


         Next


End Sub

Public Sub QuickSort(vArray As Variant, inLow As Long, inHi As Long)

  Dim pivot   As Variant
  Dim tmpSwap As Variant
  Dim tmpLow  As Long
  Dim tmpHi   As Long

  tmpLow = inLow
  tmpHi = inHi

  pivot = vArray((inLow + inHi) \ 2)

  While (tmpLow <= tmpHi)

     While (vArray(tmpLow) < pivot And tmpLow < inHi)
        tmpLow = tmpLow + 1
     Wend

     While (pivot < vArray(tmpHi) And tmpHi > inLow)
        tmpHi = tmpHi - 1
     Wend

     If (tmpLow <= tmpHi) Then
        tmpSwap = vArray(tmpLow)
        vArray(tmpLow) = vArray(tmpHi)
        vArray(tmpHi) = tmpSwap
        tmpLow = tmpLow + 1
        tmpHi = tmpHi - 1
     End If

  Wend

  If (inLow < tmpHi) Then QuickSort vArray, inLow, tmpHi
  If (tmpLow < inHi) Then QuickSort vArray, tmpLow, inHi

End Sub

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-05-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-15
    • 1970-01-01
    • 1970-01-01
    • 2017-12-30
    相关资源
    最近更新 更多