我有一个包装Excel.Shape
的类。
在我的一个功能(允许将形状从一张纸移动到另一张纸上,我有以下代码:
Private Property ThisShape As Excel.Shape
Public Property Sheet As Excel.Worksheet Implements IShapeWrapper.Sheet
Get
If Not Me.HasShape Then Return Nothing
Return Me._Sheet
End Get
Set(value As Excel.Worksheet)
If value Is Nothing Then Throw New ArgumentNullException(NameOf(value))
If Not Me.HasShape Then Exit Property 'Throw New InvalidOperationException("Unable to assign sheet: This wrapper does not contain any shapes.")
If value Is Me._Sheet Then Exit Property
Try
Dim TestShapeName As Excel.Shape = value.Shapes.Item(Me.ThisShape.Name)
Throw New InvalidOperationException("The destination worksheet already contains a shape with the same name.")
Catch ex As Exception
End Try
Me._Sheet = value
VBMath.Randomize()
Dim ShapeNamePrefix As String = $"AppName_{CInt(VBMath.Rnd() * 1000000)}_{Date.Now.Millisecond}_"
Dim TempName As String = ShapeNamePrefix & Me.ThisShape.Name
Me.ThisShape.Name = TempName
Me.ThisShape.Cut()
value.Paste()
Me.ThisShape = Nothing
For Each MyShape As Excel.Shape In value.Shapes
If MyShape.Name = TempName Then
Me.ThisShape = MyShape
MyShape.Name = String.Concat(MyShape.Name.Skip(ShapeNamePrefix.Length))
Exit For
End If
Next
If Me.ThisShape Is Nothing Then Throw New ApplicationException("Unable to re-bind with shape after copy/pasting.")
End Set
End Property
Private _Sheet As Excel.Worksheet
对于某些形状(实际上,总是相同的,这是我正在处理的50个形状中的一种),
[MyShape.Name = String.Concat(MyShape.Name.Skip(ShapeNamePrefix.Length))
引发MyShape
System.ArgumentException:指定的值超出范围。
这很混乱,因为该行基本上是MyObject.Property = MyObject.Property & Something
。调试时,我可以回显?MyShape.Name
(无论如何,上面的代码仅在上面两行中读取了它)
我对这个异常所指的含义感到困惑(无法通过索引找到形状吗?为什么分配该属性失败。
这是VB.Net代码,但是我添加了VBA标记,因为我怀疑这是Office.Interop API问题。
如果保护了形状,则可以通过编程方式移动它,但是不能重命名。就像可以以编程方式更改受保护工作表的单元格内容一样,而合并/合并单元格需要取消保护工作表。
解决方法是取消选中形状属性中的protected
框(或通过Interop API),或解锁工作表本身。