英文:
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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论