PPT VBA如何选择所有特定形状类型?

huangapple go评论79阅读模式
英文:

PPT VBA how to select all certain shape type?

问题

我想将PPT中所有具有特定类型(黑色边缘并填充为红色)的矩形改为(粉色边缘填充为蓝色)。

我认为有两个步骤:(1)使用VBA选择所有特定类型的形状
(2)回到PPT然后更改所有边缘和填充颜色,就像更改一个矩形一样。如果你想改变所有特定的矩形,你只需要先选择所有然后操作它们。这是我的建议。

我使用以下代码但它不起作用。

Sub my()
Dim currentSlide As Slide
Dim shp As Shape
Dim sld As Slide

For Each currentSlide In ActivePresentation.Slides
Set sld = Application.ActiveWindow.View.Slide
For Each shp In currentSlide.Shapes
If shp.Type = 1 Then 
shp.Select 
End If
Next shp
Next currentSlide
End Sub
英文:

I want change all rectangles in PPT with certain type(black edge and filled with red) into (pink edge filled with blue).

I suppose there two steps: (1) Use VBA to select all of certain types
(2) back in PPT then change all edge and filling color, just the same as change one rectangle. If you want to change all certain rectangle you just need to choose all first and then manipulate them. that's my opinion.

I use the following code but it doesn't work.

Sub my()
Dim currentSlide As Slide
Dim shp As Shape
Dim sld As Slide

For Each currentSlide In ActivePresentation.Slides
Set sld = Application.ActiveWindow.View.Slide
For Each shp In currentSlide.Shapes
If shp.Type = 1 Then 
shp.Select 
End If
Next shp
Next currentSlide
End Sub

答案1

得分: 1

没有理由将所有形状收集到一个数组中或选择它们。

只需循环遍历所有形状,检查是否要修改它(检查类型和可能的填充和线条颜色),如果是,则修改它:

Sub my()
    Dim sld As Slide
    Dim shp As Shape
    
    For Each sld In ActivePresentation.Slides
        For Each shp In sld.Shapes
            With shp
                If .Type = msoShapeRectangle Then
                    ' 如果需要,您可以检查当前的颜色,
                    ' 只需启用以下 IF 并调整颜色
                    ' If .Fill.ForeColor = vbRed And .Line.ForeColor = vbBlack Then
                        .Fill.ForeColor.RGB = RGB(0, 0, 255)     
                        .Line.ForeColor.RGB = RGB(255, 128, 255)
                    ' End If
                End If
            End With
        Next shp
    Next sld
End Sub
英文:

No reason to collect all shapes in an array or select them.

Simply loop over all shapes, check if you want to modify it (check type and maybe fill and line color) and if yes, modify it:

Sub my()
    Dim sld As Slide
    Dim shp As Shape
    
    For Each sld In ActivePresentation.Slides
        For Each shp In sld.Shapes
            With shp
                If .Type = msoShapeRectangle Then
                    ' You can check the current colors if needed, 
                    ' just enable the following IF and adapt the colors
                    ' If .Fill.ForeColor = vbRed And .Line.ForeColor = vbBlack Then
                        .Fill.ForeColor.RGB = RGB(0, 0, 255)     
                        .Line.ForeColor.RGB = RGB(255, 128, 255)
                    ' End If
                End If
            End With
        Next shp
    Next sld
End Sub

答案2

得分: 0

以下是您要翻译的代码部分:

Sub processShapes(sL As PowerPoint.Slide)
    
    ' 在形状上循环并进行选择(我尚未测试,但这是预期的行为),但没有任何操作。以下代码:
    
    ' - 创建幻灯片数组并调用一个函数,该函数
    ' - 创建两个数组,一个是形状数组,一个是长整型数组,第一个仅是中间数组
    ' 将这些形状的填充颜色更改为匹配范围内的蓝色
    
    ' 您可能想要:
    
    ' - 编辑If的内容并添加line.forecolor值
    ' - 进一步处理标记为无法集体完成的操作的形状

    Dim shArr() As Shape
    Dim sH As Shape
    Dim aLLsHArr() As Long
    Dim indexArr() As Long
    Dim sHIndex As Long

    Dim z As Long

    ReDim shArr(1 To sL.Shapes.Count)

    For z = LBound(shArr) To UBound(shArr)
        Set shArr(z) = sL.Shapes(z)
        Set sH = shArr(z) ' 在此处对形状进行单独处理
        
        If sH.AutoShapeType = msoShapeRectangle Then
            ' 在这里您当然也可以执行 sH.Fill.ForeColor.RGB = 12874308
            sHIndex = sHIndex + 1
            ReDim Preserve indexArr(1 To sHIndex)
            indexArr(sHIndex) = z
        End If
    Next z

    sL.Shapes.Range(indexArr).Fill.ForeColor.RGB = 12874308

    ' 但是通过使用这种方法,您还可以执行以下操作

    ' sL.Shapes.Range(indexArr).Group

    ' 作为整体来执行,而不仅仅是单独的矩形/任何形状
End Sub

Sub processSlides()

    Dim sldArr() As Slide
    Dim j As Long

    ReDim sldArr(1 To ActivePresentation.Slides.Count)

    For j = LBound(sldArr) To UBound(sldArr)
        ' 我检查了并没有错误
        Call processShapes(ActivePresentation.Slides(j))
    Next j

End Sub
' 更新

' 可以使用集合而不是每次调整大小的数组(使用数组的非有效方法),我已经使用上面给出的代码处理了成百上千个形状而没有问题,但是链接的文章让我重新考虑了答案。下面的代码经过测试可以工作。问题在于将集合作为范围传递以进行集体操作会导致错误,因此仍然必须创建长整型数组...

Sub coLLectShapes()
    Dim sL As Slide: Set sL = ActivePresentation.Slides(2)
    Dim shArr() As Shape
    Dim sH As Shape
    Dim aLLsHArr() As Long
    Dim indexArr() As Long
    Dim sHIndex As Long

    Dim sHpsToGrab As Collection: Set sHpsToGrab = New Collection

    Dim z As Long

    ReDim shArr(1 To sL.Shapes.Count)

    For z = LBound(shArr) To UBound(shArr)
        Set shArr(z) = sL.Shapes(z)
        Set sH = shArr(z) ' 在此处对形状进行单独处理

        If sH.AutoShapeType = msoShapeRectangle Then
            sHpsToGrab.Add z
        End If
    Next z

    Erase shArr ' 并释放内存

    Dim coLLToArr() As Long: ReDim coLLToArr(1 To sHpsToGrab.Count)
    Dim k As Long
    For k = 1 To sHpsToGrab.Count
        coLLToArr(k) = sHpsToGrab.Item(k)
    Next k

    ' sL.Shapes.Range(coLLToArr).Group
    sL.Shapes.Range(coLLToArr).Fill.ForeColor.RGB = 12874308

End Sub
英文:

Your code is looping through the shapes and selecting them (I have not tested it, but that's what it's supposed to do anyway) without any action. The below code:

  • creates an array of slides and call a function that
  • creates two arrays, one of shapes and of long, the first being only an intermediate one
    color the fill of those shapes in the range of the matching ones in blue

you may want to:

  • edit the content of the If and add the line.forecolor value
  • process further the shapes individually where marked for those actions that cannot be done collectively
Sub processShapes(sL As PowerPoint.Slide)

Dim shArr() As Shape
Dim sH As Shape
Dim aLLsHArr() As Long
Dim indexArr() As Long
Dim sHIndex As Long

Dim z As Long

ReDim shArr(1 To sL.Shapes.Count)

    For z = LBound(shArr) To UBound(shArr)
        Set shArr(z) = sL.Shapes(z)
        Set sH = shArr(z) ' do things indivually here to the shape
    
            If sH.AutoShapeType = msoShapeRectangle Then
'           If sH.Type =msoPicture then 'or something else
             'You can of course do sH.Fill.Forecolor.RGB = 12874308 here as well 
            sHIndex = sHIndex + 1
            ReDim Preserve indexArr(1 To sHIndex)
            indexArr(sHIndex) = z
            
            
            End If
    Next z
    
sL.Shapes.Range(indexArr).Fill.ForeColor.RGB = 12874308

'but by using this method you can also do things like this 


'sL.Shapes.Range(indexArr).Group


'to the "match" as it is being intended here as a whole, 
'not just as individual rectangles/whatever_shape


End Sub




Sub processSlides()

Dim sldArr() As Slide
Dim j As Long
    
  

    ReDim sldArr(1 to ActivePresentation.Slides.Count)
    
        For j = LBound(sldArr) To UBound(sldArr) 'I checked and there were no errors 
                Call processShapes(ActivePresentation.Slides(j))
        Next j

End Sub

Update

A collection can be used instead of the array to be resized each time (a non-efficient way to use arrays), I have been using the code I gave above for many hundreds of shapes without issues, however the linked article made me rethink the answer. The below is tested and works. The thing is that passing the Collection as range to do things collectively gives error, so the array of long has to be created anyway...


Sub coLLectShapes()
Dim sL As Slide: Set sL = ActivePresentation.Slides(2)
Dim shArr() As Shape
Dim sH As Shape
Dim aLLsHArr() As Long
Dim indexArr() As Long
Dim sHIndex As Long

Dim sHpsToGrab As Collection: Set sHpsToGrab = New Collection

Dim z As Long

ReDim shArr(1 To sL.Shapes.Count)

    For z = LBound(shArr) To UBound(shArr)
        Set shArr(z) = sL.Shapes(z)
         Set sH = shArr(z) ' do things indivually here to the shape

            If sH.AutoShapeType = msoShapeRectangle Then           
             sHpsToGrab.Add z
            
            End If
    Next z

    Erase shArr 'and free the memory

    Dim coLLToArr() As Long: ReDim coLLToArr(1 To sHpsToGrab.Count)
    Dim k As Long
    For k = 1 To sHpsToGrab.Count
     coLLToArr(k) = sHpsToGrab.Item(k)
    Next k
    
'sL.Shapes.Range(coLLToArr).Group
sL.Shapes.Range(coLLToArr).Fill.ForeColor.RGB = 12874308

End Sub


huangapple
  • 本文由 发表于 2023年7月24日 15:19:30
  • 转载请务必保留本文链接:https://go.coder-hub.com/76752184.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定