vba - PowerPoint VBA - 按值传递形状似乎是通过引用发生的
问题描述
对于我正在整理的 VBA 脚本的一部分,我想遍历当前幻灯片上的所有形状,并在每个形状的顶部插入另一个形状。
我有第一个子例程 GetShapes(),它获取当前幻灯片上的所有形状,然后将它们按值传递给第二个子例程 LabelShapes(),它将新形状添加到顶部。
但是,新形状似乎出现在传递的 Shapes 对象中。似乎不应该是这种情况,因为它是通过引用传递的。
警告,以下将快速锁定 PowerPoint
Sub GetShapes()
Dim ss As Shapes
Set ss = Application.ActiveWindow.View.Slide.Shapes
Call LabelShapes(ss)
End Sub
Sub LabelShapes(ByVal ss As Shapes)
Dim s As Shape
For Each s In ss
Debug.Print s.Name
Application.ActiveWindow.View.Slide.Shapes.AddShape _
Type:=msoShapeRectangle, Left:=50, Top:=50, Width:=15, Height:=15
Next
End Sub
我想我可以通过为我的新形状使用特殊的命名约定然后将它们过滤掉来解决这个问题。也许有更好的方法?但是,实际上我只是想了解为什么这不符合我的预期。
解决方案
不确定您到底要做什么,但一个常见的误解是传递对象引用ByVal
会神奇地创建对象的副本。
传递对象引用ByVal
意味着您传递对象指针的副本,而不是对同一对象指针的引用。
在这两种情况下,您都传递了一个指向完全相同的对象的对象指针,因此当您更改时.AddShape
,您正在更改您正在迭代的同一个形状集合。
传递对象引用ByVal
不会传递对象的副本。如果要通过副本,则需要制作副本。
这可能有助于澄清:
Public Sub DoSomething()
Dim obj As Object
Set obj = New Collection
TestByVal obj 'pass a copy of the object reference
Debug.Assert Not obj Is Nothing
TestByRef (obj) 'force a copy of the object reference (despite ByRef)
Debug.Assert Not obj Is Nothing
TestByRef obj 'pass a reference to the object pointer
Debug.Assert Not obj Is Nothing ' << assert will fail here
End Sub
Private Sub TestByVal(ByVal obj As Object)
Set obj = Nothing ' only affects the local copy
End Sub
Private Sub TestByRef(ByRef obj As Object)
Set obj = Nothing ' DANGER! call site will see this
End Sub
推荐阅读
- jquery - 使用jquery隐藏和显示html中的字段
- android - 如何在地图内找到附近的码头、码头和船只发射点?
- java - 如何在魅力报告中附加自定义/现有屏幕截图?
- typescript - 如何在单元测试中模拟 TS 类
- php - PHPSpreadhseet:从我的数据库导出数据时没有得到输出,甚至没有一个错误?
- spring-security - 使用 Google OAuth 实现 Spring 安全性并生成自定义令牌
- javascript - 视差冻结浏览器
- ios - 用于快速发送和接收 json 数据的相同结构
- android - 如何以编程方式创建带有子项的操作项?
- php - 我无法将变量从我的 PHP 文件传递到我的 Smarty 文件