我在Word中尝试了以下代码:
Sub MyMacro()
Dim sh1 As Shape
For Each sh1 In ActiveDocument.Shapes
If sh1.GroupItems.Count > 0 Then
Debug.Print sh1.Name + " is a group!"
Else: Debug.Print sh1.Name + " is not a group!"
End If
Next
End Sub
对于实际的分组形状,它可以工作,但是当形状不是一个组时,我得到一个错误:
运行时错误“-2147024891(80070005)”:只能为组访问此成员
除了使用On Error
之外,如何检查对象是否是一个组?
5条答案
按热度按时间7kjnsjlb1#
到目前为止,我在这里得到了两个非常全面的答案,我感谢他们的作者。但是我想避免
On Error
捕获,不想依赖形状的名称,也不想做复杂的事情,比如构建自己的dll。Cindy使用InStr(rng.WordOpenXML, "<wpg:wgp>")
的解决方案看起来是最接近的,但由于某种原因,这段代码在我的文档中不起作用:<wpg:wgp>
被发现用于任何形状,分组与否。因此,我决定发布我自己的解决方案,这是非常简单的,似乎对所有情况下正确的工作。我们只需要使用.AutoShapeType
属性(@SMeaden在评论中指出的):eqqqjvef2#
在Word中有多种方法可以实现这一点。前两个可能也适用于Excel,但第三个只能在Word中使用。
1.使用
On Error Resume Next
的代码并检查Err.Number
。如果它是0,你有一个组,如果不是,那么你没有。可能还有其他错误,尽管目前我没有想到。
1.另一种可能性是检查
Name
属性,假设它没有被任何代码更改。默认情况下,它将类似于“组3”,因此1.检查WordOpenXML是否包含元素标记
<wpg:wgp>
(代表wordProcessingGroup
,参见Open XML SDK documentation)。您无法获取Shape的WordOpenXML,您需要查询Shape.Anchor.Paragraphs(1).Range
-与Shape关联的Word文档中的Range。请注意,只有当已分组的Shape是唯一锚定到段落的Shape时,这种简单的方法才有效。如果有多个Shape,您仍然可以使用WordOpenXML,但需要使用XML工具对其进行分析,以确保有问题的Shape是属于Group的Shape。
hfyxw5xn3#
我遇到了同样的挑战,发现以前的解决方案要么过于复杂(错误处理),要么不起作用(AutoShapeType)。但是,它显示,通过检查Shape.Type属性,组本身将使用值6(或作为msoGroup)进行标识。
因此,前面的代码可能会调整为以下内容:
q43xntqr4#
IMHO,它看起来像一个界面设计错误。设计者还应该导出一个
GroupItemsCount
方法,客户端代码可以在尝试调用GroupItems
之前检查该方法。我也不喜欢使用
On Error Resume Next
(herefeter OERN),每个开发团队都试图说服同事发布一个用.NET(C#或VB.NET)编写的DLL
,它掩盖了这些方法引发的所有错误。因此,在Excel中,我们为每个工作簿都有一个Worksheets集合,但设计人员忘记了导出Exists方法。必须调用
[Worksheets]Item
,但如果工作表不存在,则Item抛出错误。在.NET DLL中编写自己的[Worksheet]Exists方法意味着可以隐藏错误并避免VBA OERN。在您的情况下,我建议您创建自己的
SupportsGroupItems
函数,它本身有一个错误处理程序,但它会隐藏在VBA视图中(这样错误就被隐藏了)。它将被存放在.NET DLL中。我意识到许多经理更喜欢纯VBA解决方案,管理层可能害怕DLL地狱,但如果你告诉他们这是一次性的,他们应该是可以说服的。这将是一个非常少的代码行。
DLL解决方案的下一个问题是部署,并不是所有的部署都是在一个完整的推出中完成的,因此如果安装了DLL,您需要编写代码来利用DLL,如果没有安装,则回退到VBA。您可以在注册表中查找代码来检测DLL的安装。
如果你已经读到这里,并确信你想自己的dll来埋葬任何错误,那么你需要一些示例代码。这个blog post有一些示例代码。使.NET DLL可从VBA调用的关键是在Assembly.cs中标记ComVisible(true),并在项目属性的构建选项卡上确保选中以下复选框“注册COM互操作”。
然后确保接口和类的分离。你知道吗?让我在这里写代码。因此,这是通过使用
dynamic
关键字避免Word主互操作程序集的示例C#。下面是一些调用. NETDll的示例VBA代码
所有这些都使VBA中的OERN看起来很可口。
cuxqih215#
虽然它们看起来是矛盾的,但两个答案都是正确的,所以这里要澄清的是
Shape
的属性GroupItems
被示例化并可以查询的所有情况:Type
=msoGroup
(6)来识别。这些形状是通过组合2个或更多其他形状而创建的。AutoShapeType
=msoShapeMixed
(-2)来识别。这些是对应于SmartArt Graphics的形状。请注意,问题是关于Excel和Word的,但答案也适用于PowerPoint。
这个答案是社区维基,以便在需要时修复它,或者在存在其他可能性时完成它。