如何使用 VBA 在 PowerPoint 中取消形状组合后按类型重新组合形状

2024-05-04

继我的出色回答之后上一个问题 https://stackoverflow.com/questions/74339247/how-to-rename-shapes-within-grouped-groups-in-powerpoint-with-vba,我试图从一组原始的分组对中创建两组,一组由形状和一组文本框组成,每组由一个形状和一个文本框组成。 我尝试创建两个数组,每个类别一个,通过调整上一个问题的答案中的代码并查看我发现的类似问题,例如here https://stackoverflow.com/questions/65400944/grouping-an-array-of-shapes,但是我想出的方法不起作用:宏调用的函数在最后一步停止(当我尝试对数组进行分组时,即Set GroupedShapes = oSlide.shapes.Range(ShapeArray).Group)有错误-2147024809 (80070057)': Shapes(uknown member): Illegal value. Bad type: expected ID array of Variants, Integers, Longs, or Strings.我尝试留下空白括号 -->Set GroupedShapes = oSlide.shapes.Range(ShapeArray()).Group据我了解,那里缺少一些东西,但我得到了同样的错误,也没有...Range(ShapeArray(1 to .shpRng))...当我收到提示时,我应该用逗号分隔值。然而,我什至不确定如果这个问题得到解决,剩下的部分是否真的有效。有人可以建议吗?

Sub GiveNamesToShapes()
    Dim oSlide As slide
    Set oSlide = ActivePresentation.Slides(ActiveWindow.View.slide.SlideIndex)
    
    Dim shp As Shape
    For Each shp In oSlide.shapes
        If shp.Type = msoGroup Then
            NameGroup shp
        End If
    Next shp
End Sub

Function NameGroup(ByVal oShpGroup As Object) As Long
    Dim groupName As String, shp As Shape, shpRng As ShapeRange, txt As String

    Dim TextArray() As Variant 'these are the variables I created
    Dim ShapeArray() As Variant
    Dim GroupedShapes As Shape
    Dim GroupedText As Shape
    
    Dim i As Integer 'these are the variables I created
    Dim y As Integer
    
    Dim Shp_Cntr As Double
    Dim Shp_Mid As Double
    
    Dim ShapeLeft As Double
    Dim ShapeRight As Double
    Dim ShapeWidth As Double
    Dim ShapHeight As Double
    
    groupName = oShpGroup.name
    
    Dim oSlide As slide: Set oSlide = oShpGroup.Parent

    Set shpRng = oShpGroup.Ungroup
    For Each shp In shpRng
        If Not shp.Type = msoGroup Then
            If shp.TextFrame.HasText = msoTrue Then _
                txt = shp.TextFrame.TextRange.text
        End If
    Next shp
    For Each shp In shpRng
        If Not shp.Type = msoGroup Then
            If shp.TextFrame.HasText = msoFalse Then
                        
                With shp
'here is the first array i created (shapes)
                    Dim indicesShapes() As Long, z As Long: ReDim indicesShapes(LBound(ShapeArray) To UBound(ShapeArray))
                        For i = LBound(ShapeArray) To UBound(ShapeArray)
                            For z = 1 To oSlide.shapes.Count
                                Set oSlide.shapes(z) = ShapeArray(i) 'Then indices(i) = j: Exit For
                            Next z
                        Next i

'up to here
                End With
                
                ShapeLeft = shp.Left
                ShapeTop = shp.Top
                ShapeWidth = shp.Width
                ShapeHeight = shp.Height
                
                Shp_Cntr = ShapeLeft + ShapeWidth / 2
                Shp_Mid = ShapeTop + ShapeHeight / 2
                
                shp.name = txt
                
            Else
                With shp
'this is the second Array (for textboxes)
                    Dim indicesText() As Long, p As Long: ReDim indicesText(LBound(TextArray) To UBound(TextArray))
                        For y = LBound(TextArray) To UBound(TextArray)
                            For p = 1 To oSlide.shapes.Count
                                Set oSlide.shapes(p) = TextArray(y) 'Then indices(i) = j: Exit For
                            Next p
                        Next y

'up to here

                .TextFrame.WordWrap = False
                .TextFrame.AutoSize = ppAutoSizeShapeToFitText
                .TextFrame.TextRange.ParagraphFormat.Alignment = ppAlignCenter
                .TextFrame.VerticalAnchor = msoAnchorMiddle
                
                .Left = Shp_Cntr - .Width / 2
                .Top = Shp_Mid - Height / 2
                    
                End With
            End If
        End If
    Next shp
    
'here is where I try to group the items in the arrays and I get the error
    Set GroupedShapes = oSlide.shapes.Range(ShapeArray).Group
    Set GroupedText = oSlide.shapes.Range(TextArray).Group
    
End Function

编辑:我刚刚尝试过以下内容,但我得到了Type mismatch

    Set GroupedShapes = oSlide.shapes.Range(indicesShapes(ShapeArray)).Group
    Set GroupedText = oSlide.shapes.Range(indicesText(TextArray)).Group

EDIT2:

我回到我所指的答案,意识到我没有添加循环来取消分组到“核心”,直到没有剩余的组为止。然后,我更改了数组的顺序并将它们放置在此之后,天真地认为通过将形状和文本框的变量加倍,我会得到预期的结果,但第一对形状只会取消分组。我的想法是获取形状和文本框的 id,这样它们就会相应地分组,但是尽管我添加了循环,但下面的内容在第一对处停止,直到有组为止,所以最后一行Set GroupedText = oSlide.shapes.Range(indicesText).Group给出错误,表示在形状范围内必须至少有两个对象。

Sub GiveNamesToShapes()
    Dim oSlide As slide
    Set oSlide = ActivePresentation.Slides(ActiveWindow.View.slide.SlideIndex)
    
    Dim shp As Shape
    For Each shp In oSlide.shapes
        If shp.Type = msoGroup Then
            NameGroup shp
        End If
    Next shp
End Sub

Function NameGroup(ByVal oShpGroup As Object) As Long
    Dim groupName As String, shp As Shape, shpRng As ShapeRange, txt As String
    Dim TextArray() As Variant
    Dim ShapeArray() As Variant
    Dim GroupedShapes As Shape
    Dim GroupedText As Shape
   
    groupName = oShpGroup.name
    
    Dim oSlide As slide: Set oSlide = oShpGroup.Parent

    Set shpRng = oShpGroup.Ungroup
    For Each shp In shpRng
        If Not shp.Type = msoGroup Then
            If shp.TextFrame.HasText = msoTrue Then _
                txt = shp.TextFrame.TextRange.text
        End If
    Next shp
    For Each shp In shpRng
        If Not shp.Type = msoGroup Then
            If shp.TextFrame.HasText = msoFalse Then

                
                shp.name = txt
                

            End If
        End If
    Next shp
    
    
    Dim Shapeids() As Long, i As Long: ReDim Shapeids(1 To shpRng.Count): i = 1
    Dim Textids() As Long, y As Long: ReDim Textids(1 To shpRng.Count): y = 1
    For Each shp In shpRng
            Do While shp.Type = msoGroup  'I added this loop to ungroup recursively, but it does not go through all groups, it works only on the first one               
                            Call NameGroup(shp)
            Loop
            
            If shp.TextFrame.HasText = msoTrue Then
        
                    Textids(y) = shp.id: y = y + 1
            
            ElseIf shp.TextFrame.HasText = msoFalse Then
            
                    Shapeids(i) = shp.id: i = i + 1
            End If
    Next shp
    
    
    Dim Textindices() As Long, p As Long: ReDim Textindices(LBound(Textids) To UBound(Textids))
        For y = LBound(Textids) To UBound(Textids)
            For p = 1 To oSlide.shapes.Count
                If oSlide.shapes(p).id = Textids(y) Then Textindices(y) = p: Exit For
            Next p
        Next y
        
    Dim Shapeindices() As Long, z As Long: ReDim Shapeindices(LBound(Shapeids) To UBound(Shapeids))
        For i = LBound(Shapeids) To UBound(Shapeids)
            For z = 1 To oSlide.shapes.Count
                If oSlide.shapes(z).id = Shapeids(i) Then Shapeindices(i) = z: Exit For
            Next z
        Next i
    
    
    Set GroupedShapes = oSlide.shapes.Range(Shapeindices).Group 'here it stops and it says there must be two objects to make a group, only the first pair is ungroupd (the primary, big group containing all is gone) while all oteher pairs are still grouped

    Set GroupedText = oSlide.shapes.Range(Textindices).Group 
    
End Function

As is

预期结果


我的一位同事总是告诉我使用 F8 来查看宏的作用,而以上所有内容都清楚地表明我没有这样做。不够。 我意识到我试图在函数中对项目进行分组,而实际上这应该在取消分组之后发生在宏本身中。我的灵感来自于这个答案 https://stackoverflow.com/a/46851159/18247317(记住它下面的评论:形状必须有不同的名称)现在一切都按预期工作。

我不明白一件事:在线Debug.Print Parent.name立即窗口说Microsoft Excel,但我在 PowerPoint 中运行它,并且 Excel 已关闭。

Sub GiveNamesToShapes_Center_AndThenRegroup()
    Dim oSlide As slide
    Set oSlide = ActivePresentation.Slides(ActiveWindow.View.slide.SlideIndex)
    
    Dim x As Long
    Dim sTemp As String
    
    Dim ShapeList() As String
    Dim ShapeCount As Long
    
    Dim TextList() As String
    Dim TextCount As Long
    
    Dim shp As Shape
    For Each shp In oSlide.shapes
        If shp.Type = msoGroup Then
            NameGroup shp
            
        Else
        
        For x = 1 To oSlide.shapes.Count

            If oSlide.shapes(x).TextFrame.HasText = msoFalse Then
                ShapeCount = ShapeCount + 1
                
                
            Else
                TextCount = TextCount + 1
            End If
        Next x 'EDIT 2022/11/24 --> I added 'x' as with crowded groups coming from SVG files the part above ''If shp.Type = msoGroup Then'' was being skipped


        ReDim ShapeList(1 To ShapeCount)
        ReDim TextList(1 To TextCount)

        ShapeCount = 0
        TextCount = 0

        For x = 1 To oSlide.shapes.Count

            If oSlide.shapes(x).TextFrame.HasText = msoFalse Then
                ShapeCount = ShapeCount + 1
                ShapeList(ShapeCount) = oSlide.shapes(x).name
                
            Else
                TextCount = TextCount + 1
                TextList(TextCount) = oSlide.shapes(x).name
            End If
        Next x 'EDIT 2022/11/24 --> I added 'x' as with crowded groups coming from SVG files the part above ''If shp.Type = msoGroup Then'' was being skipped


        If UBound(ShapeList) > 0 Then
            oSlide.shapes.Range(ShapeList).Group
        End If
        If UBound(TextList) > 0 Then
            oSlide.shapes.Range(TextList).Group
        End If
            

        End If
    Next shp
End Sub

Function NameGroup(ByVal oShpGroup As Object) As Long
    Dim groupName As String, shp As Shape, shpRng As ShapeRange, txt As String
    

    
    Dim Shp_Cntr As Double
    Dim Shp_Mid As Double
    
    Dim ShapeLeft As Double
    Dim ShapeTop As Double
    Dim ShapeWidth As Double
    Dim ShapeHeight As Double
    
    
    groupName = oShpGroup.name
    Debug.Print oShpGroup.name
    Dim oSlide As slide: Set oSlide = oShpGroup.Parent
    Debug.Print Parent.name

    Set shpRng = oShpGroup.Ungroup
    For Each shp In shpRng
        If Not shp.Type = msoGroup Then
            If shp.TextFrame.HasText = msoTrue Then _
                txt = shp.TextFrame.TextRange.text
        End If
    Next shp
    For Each shp In shpRng
        If Not shp.Type = msoGroup Then
            If shp.TextFrame.HasText = msoFalse Then
            
                shp.name = txt
            
                ShapeLeft = shp.Left

                ShapeTop = shp.Top

                ShapeWidth = shp.Width

                ShapeHeight = shp.Height

                
                Shp_Cntr = ShapeLeft + ShapeWidth / 2
                Shp_Mid = ShapeTop + ShapeHeight / 2

            Else

                With shp
                                shp.name = "Textbox " & txt
                    .TextFrame.WordWrap = False
                    .TextFrame.AutoSize = ppAutoSizeShapeToFitText
                    .TextFrame.TextRange.ParagraphFormat.Alignment = ppAlignCenter
                    .TextFrame.VerticalAnchor = msoAnchorMiddle
                    
                    .Left = Shp_Cntr - (.Width / 2)
                    .Top = Shp_Mid - (.Height / 2)
                End With


            End If
        End If
    Next shp
    

    Dim ids() As Long, i As Long: ReDim ids(1 To shpRng.Count): i = 1
    For Each shp In shpRng
        If shp.Type = msoGroup Then

             NameGroup shp

        End If
    Next shp

End Function



本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用 VBA 在 PowerPoint 中取消形状组合后按类型重新组合形状 的相关文章

  • 即使 Excel 中存在多条记录,CopyFromRecordset 也仅复制并粘贴第一行

    我有一个包含表格数据的 Excel 工作表 strSQL SELECT S FIELD NAME1 S FIELD NAME2 S FIELD NAME3 from SourceData A1 IV6 S Dim cn as ADODB C
  • 如何处理 Workbook.SaveAs 覆盖确认上的“否”或“取消”?

    我希望在 VBA 脚本开始修改内容之前提示用户保存工作簿 当 另存为 对话框出现时 如果用户单击 取消 我会引发自定义错误并停止脚本 如果他们单击 保存 并且文件名已存在 我希望询问他们是否覆盖 这是我的代码 Function SaveCu
  • 由于直接引用范围而不是通过中间变量而导致 Excel VBA 运行时错误 450

    当我尝试直接引用某个范围内的值时 出现运行时错误 450 但如果我使用中间变量 它就会起作用 我不明白为什么 所以我担心在将来的某个时候我会再次遇到错误而不知道为什么 我尝试过使用 With End With 块 但当我直接引用范围时它仍然
  • 查找并替换目录中所有 Excel 文件工作簿中的字符串

    我正在编写 VBA 代码来替换位于特定目录中的多个 Excel 文件 工作簿 中的特定字符串 我尝试在 Stack Overflow 上搜索 找到答案 但这与通过 Excel 中的宏替换文本文件中的字符串有关 相同的链接是查找并替换文件中的
  • 如何使用 VBA 将 mm/dd/yyyy 更改为 dd/mm/yyyy

    我在使用 VBA 将 mm dd yyyy 转换为 dd mm yyyy 日期格式时遇到问题 我有一个这样的表 仅供参考 该表是从报告工具自动生成的 字符串操作 或任何 Excel 函数可以提供帮助吗 希望知道如何解决这个问题的人可以给我一
  • 在 VBA 中循环合并单元格

    是否可以循环遍历合并的单元格vba questions tagged vba 我的范围内有 6 个合并单元格B4 B40 我只需要这 6 个单元格中的值 6 次迭代 上面的答案看起来已经让你排序了 如果您不知道合并的单元格在哪里 那么您可以
  • VBA XML V6.0 如何让它等待页面加载?

    我一直在努力寻找答案 但似乎找不到任何有用的东西 基本上 我是从一个网站上拉取的 当您在该页面上时 该网站会加载更多项目 我希望我的代码在加载完成后提取最终数据 但不知道如何让 XML httprequest 等待 Edited Sub p
  • VBA根据单元格的值是否为零显示/隐藏行

    我有一个 Excel 工作表 我想根据另一个单元格中的值隐藏或取消隐藏某些行 简而言之 整个事情应该取决于单元格中的值C2 D2 E2 If C2 is blank我想rows 31 to 40被隐藏 如果是的话不为空 他们需要是visib
  • 将匹配的行复制到另一张纸中

    我有两张表 sheet1 和sheet 2 我正在查看工作表 1 的 T 列 如果工作表 2 中 T 包含 1 则粘贴完整行 该代码运行良好 但它将sheet2 中的结果粘贴到sheet1 的同一行中 这会导致行之间出现空白 任何人都可以建
  • VBA在多个文件夹中搜索特定子文件夹并移动其中的所有文件

    你能帮助我吗 我想要一个宏vba来搜索SPECIFIC例如 所有存在并移动其文件的文件夹和子文件夹之间的子文件夹 Xfolder P Desktop Folder1 subfolder SUBFOLDER1 Xfolder 我正在使用 VB
  • 如何将参数从 Excel/VBA 传递到 Rstudio 中的脚本

    我正在尝试使用 Rstudio 从 VBA 打开 R 脚本 同时将参数传递给 R 脚本 然后我可以使用 commandArgs 访问该脚本 该问题与此处描述的问题非常相似 WScript Shell 用于运行路径中包含空格且来自 VBA 的
  • 如何修复日期过滤器 VBA,因为它没有拾取我范围内的所有日期

    我正在尝试创建一个过滤器来过滤掉我选择的日期内的所有日期 我选择的日期将始终反映整个月 例如 如果我需要 2019 年 5 月的数据 我将输入开始日期为 01 05 2019 结束日期为 31 05 2019 我的数据过滤器将需要选取经过我
  • Excel 的 VBA - 如何检查范围的交集不为空

    我有两个问题 1 如何检查交集或范围是否不为空 例如 如果我想检查它是否为空 我会写 if application intersect r1 r2 is nothing 但有什么东西是否定虚无的吗 例如 并非没有任何事情不起作用 2 如何比
  • 在用户窗体终止/关闭 VBA 时调用数组

    我有一个问题 我想在用户窗体关闭时将用户窗体的内容存储在数组中 我认为我的语法正确 但似乎不会在用户窗体初始化时重新填充 我尝试将数组放入其自己的模块中 但这也不起作用 有人愿意启发我吗 示例代码 Public Sub DPArrayStu
  • 插入行而不选择任何内容?

    我正在使用 VBA 希望在特定位置插入一行而不选择它 我遇到的问题是 选择该行后 当脚本运行完毕时 电子表格会向下滚动到该行 我希望能够在不将电子表格向下滚动到插入行的情况下执行此操作 Rows i i Select ActiveCell
  • 了解从 MsgBox 返回的响应代码

    我对编程很陌生 我刚刚开始学习 VBA 和 Excel 我在这个网站上遇到并做了这里的例子 但我对这段代码有疑问 我知道变量是使用 Dim 语句声明的 Message 这里是数据类型为整数的变量 我不太明白的是 这里的 6 和 7 是什么意
  • 使用 VBA 将 Excel 工作表导入 Access

    我正在尝试使用一些简单的 VBA 代码将 Excel 电子表格导入到 Access 中 我遇到的问题是 Excel 文件中有 2 个工作表 我需要导入第二个工作表 是否可以在VBA代码中指定所需的工作表 Private Sub Comman
  • 防止在单元格中更改行时重新格式化字符

    我有一个带有格式化文本的单元格 其中包含我想要用行更改替换的某个子字符串 子字符串是带有方括号的 enterkey 这是这个问题的一个变体在 Excel 中将 HTML 标记 替换为 Alt Enter https stackoverflo
  • VBA 中的 If 和 Or 多个语句

    我想将包含 14 列的 Excel 文件重新分配到正确的列 包含 12 000 行 为此 我必须使用一些 If And Or 语句将数字放入矩阵中 但显然我没有从中得到正确的东西 它使我的所有单元格为零 而具有值的单元格应保留该值 我哪里出
  • 从 CSV 中去除额外的文本限定符

    我有一个 CSV 其中某些字段由 符号分隔作为文本限定符 参见下面的例子 请注意 每个整数 例如 1 2 3 等 都应该是一个字符串 合格的字符串被 符号包围 1 2 3 qualifiedString1 4 5 6 7 8 9 10 11

随机推荐

  • 如何从 firebase 导出无崩溃的用户?

    我想将有关崩溃和无崩溃用户指标的数据保留在数据库中以供进一步分析 我已经将该项目链接到 BigQuery 但找不到计算方法无崩溃用户BigQuery 中包含的数据价值 是否可以以某种方式导出无崩溃的用户指标 这里是 Fabric Fireb
  • 将 system.web 应用程序池添加到 web.config 会导致 500 内部服务器错误

    我正在尝试将以下内容添加到我的网络配置中
  • 如何从构建管道内的项目存储库中的azure存储blob下载文件(Azure DevOps)

    需要一种在构建过程中将一组文件从 Azure Blob 存储下载到项目存储库的方法 该流程的目的是对移动应用程序进行 CI CD 但是移动应用程序的图标 背景图像和一些其他图像是由其他应用程序提供的 因此在构建过程中图像应该从 blob 存
  • 访问 Spring-MVC 中的应用程序属性

    Spring MVC 的新手 我想在 properties 文件中存储两个属性 uploadFolder downloadFolder 在 HomeController 类 由 MVC 模板自动创建 中访问它 你能指导我如何 1 用上面的内
  • 自定义类上的 List.sum

    我有以下代表 GF2 字段的代码 trait GF2 def unary this def that GF2 GF2 def that GF2 GF2 def that GF2 that match case Zero gt throw n
  • 运行 istio-proxy 后启动容器/pod

    我正在尝试使用 Istio 和 Envoy 通过 Kubernetes 实现服务网格 我能够设置服务和 istio proxy 但无法控制容器和 istio proxy 的启动顺序 我的容器是第一个启动的 并尝试通过 TCP 访问外部资源
  • MSBuild 多个输出路径

    I saw this https stackoverflow com questions 14107302 msbuild copy multiple files to multiple directories repeatedlyS O
  • Java:使用反射正确检查类实例化

    我正在尝试使用最简单的反射形式之一来创建类的实例 package some common prefix public interface My void configure void process public class MyExamp
  • jQuery select2 与 WordPress

    我正在使用 jQueryselect2 https select2 org在 WordPress 内 我有一个像这样的 HTML 表格 如果用户点击我需要这里Bob SMith and admin它将转换为select2具有多项选择的下拉菜
  • 制作域中立程序集的步骤是什么?

    这些步骤也可以应用于第三方议会 可能已经是强名称的 吗 我的问题的上下文应该不重要 但无论如何我都会分享 我正在考虑制作一个记录器 或日志包装器 它始终知道要定位的 日志源 无论使用它的程序集是否是在一个应用程序域中 或分布在多个应用程序域
  • 想要显示图像

    我有一个小问题 我想要一个可以上传和显示图像的 Django 应用程序 目前 它可以上传图像 但无法显示该图像 例如 comment photo 将打印出路径C Users AQUIL Desktop myproject images P1
  • 使用ant检测操作系统并设置属性

    我想根据操作系统类型在 ant 任务中设置不同的属性 该属性是一个目录 在 Windows 中我希望它是 c flag 在 unix linux 中是 opt flag 我当前的脚本仅在使用默认目标运行时才有效 但为什么呢
  • 如何禁止一个用户访问某个文件?

    我正在尝试禁止用户打开文件 目的是当用户尝试打开特定文件时 他将无法打开 另外 我希望能够返回权限并让用户打开文件 我只找到了启用权限的方法 os chmod path 0444 但我不明白如何禁用权限 Unix 权限入门 Every fi
  • MySQL:插入被外键引用行的更新阻止

    让我用一个 SQL 示例来开始我的问题 这是表设置 创建表x and y With y x指的是x id 插入一行到x id 1 START TRANSACTION CREATE TABLE x id INT 11 NOT NULL AUT
  • Python虚拟环境包安装问题

    我正在构建一个需要 Django 的 Python 项目 我使用 virtualenv 创建了项目目录和虚拟环境 但我无法使用 PIP 安装 django 我必须使用 easy install 才能将其安装到虚拟环境中 注意 我只在 Dja
  • AWS Cloudfront 行为函数不重定向

    尝试找到一种方法将流量从我的 AWS CloudFront 页面重定向到另一个 URL 我目前正在使用 Cloudfront Functions 设置 函数 函数代码 函数名称 exampleFunction function handle
  • MD5 是否保证可与 Android 中的 MessageDigest 一起使用?

    我想知道 MD5 摘要算法是否保证在所有 Android 设备中可用 然后再直率地忽略已检查的异常MessageDigest getInstance MD5 可以扔 我越来越java security NoSuchAlgorithmExce
  • Ubuntu 上的 Docker 无法连接到本地主机,但可以连接到其 IP

    我运行的是 Ubuntu 18 04 uname r 5 3 0 46 generic 我已经安装了docker docker version Docker version 19 03 8 build afacb8b7f0 我有一个简单的
  • 从数据层中删除所有特征

    我用过类似的东西 var map function initialize map new google maps Map document getElementById map canvas zoom 4 center lat 28 lng
  • 如何使用 VBA 在 PowerPoint 中取消形状组合后按类型重新组合形状

    继我的出色回答之后上一个问题 https stackoverflow com questions 74339247 how to rename shapes within grouped groups in powerpoint with