You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Excel VBA复制msoShapeCube后AutoShapeType变为msoShapeMixed的问题求助

复制立方体形状后ShapeType变为msoShapeMixed的问题解决

问题描述

在项目中需多次将msoShapeCube类型的立方体形状从一个工作表复制到另一个,为了正确排列需要获取其比例(通过Adjustments.Item(1))。但粘贴后,原形状的AutoShapeType变为msoShapeMixed(该类型无Adjustments属性)。目前已用原形状的Adjustments.Item(1)作为临时解决方法,但想了解形状样式被修改的原因,以及如何保留原ShapeType或可靠获取比例。

用户提供的代码片段:

Dim thisBox As Shape
Dim refBox As Shape
 
boxLength = Feuil23.Range("E33").Value
boxWidth = Feuil23.Range("E34").Value
boxHeight = Feuil23.Range("E35").Value
nbBoxInLength = Feuil23.Range("I33").Value
nbBoxInWidth = Feuil23.Range("I34").Value
nbLayers = Feuil23.Range("I35").Value

nomCarton = boxLength & "x" & boxWidth & "x" & boxHeight
Count = 1

'FindCarton is a sub returning the Shape index of my box, if found, or -1 if not found.
If (FindCarton(nomCarton) <> -1) Then
    Set refBox = Feuil13.Shapes(nomCarton)
    ' I checked the AutoShapeStyle of refBox ; it is =14 (msoShapeCube)
    ' a spy on refBox clearly states "msoShapeCube" for this variable.
    ' Loop to stack layers
    For iInLayers = 1 To nbLayers
        ' Loop to add boxes in horizontal direction
        For iInLength = 1 To nbBoxInLength
            ' Loop to add boxes in opposite direction
            For iInWidth = 1 To nbBoxInWidth
                refBox.Copy
                Feuil23.Range("E11").Select
                Feuil23.Paste
                Feuil23.Shapes(nomCarton).Name = nomCarton & "_" & Count
                Set thisBox = Feuil23.Shapes(nomCarton & "_" & Count)
                ' a spy on thisBox says "msoShapeMixed" for this variable.
                ' I do not understand why...

原因分析

使用Copy/Paste复制形状时,Excel剪贴板可能会将形状及其关联格式、元数据打包为复合对象,而非单一的自动形状。这种情况下,系统无法识别为纯msoShapeCube类型,因此AutoShapeType返回msoShapeMixed。

解决方案

1. 直接创建新形状(推荐)

放弃剪贴板复制,改用Shapes.AddShape方法直接创建msoShapeCube类型的形状,同时继承原形状的调整值、格式等参数,完全避免类型转换问题。

优化后的代码示例:

Dim thisBox As Shape
Dim refBox As Shape
 
boxLength = Feuil23.Range("E33").Value
boxWidth = Feuil23.Range("E34").Value
boxHeight = Feuil23.Range("E35").Value
nbBoxInLength = Feuil23.Range("I33").Value
nbBoxInWidth = Feuil23.Range("I34").Value
nbLayers = Feuil23.Range("I35").Value

nomCarton = boxLength & "x" & boxWidth & "x" & boxHeight
Count = 1

If (FindCarton(nomCarton) <> -1) Then
    Set refBox = Feuil13.Shapes(nomCarton)
    ' 提取原形状的关键参数
    Dim cubeAdjustment As Single
    cubeAdjustment = refBox.Adjustments.Item(1)
    Dim baseLeft As Single, baseTop As Single, baseWidth As Single, baseHeight As Single
    baseLeft = refBox.Left
    baseTop = refBox.Top
    baseWidth = refBox.Width
    baseHeight = refBox.Height
    
    ' 循环创建形状并排列
    For iInLayers = 1 To nbLayers
        For iInLength = 1 To nbBoxInLength
            For iInWidth = 1 To nbBoxInWidth
                ' 直接创建立方体形状
                Set thisBox = Feuil23.Shapes.AddShape( _
                    Type:=msoShapeCube, _
                    Left:=baseLeft + (iInLength - 1) * baseWidth, _
                    Top:=baseTop + (iInLayers - 1) * baseHeight + (iInWidth - 1) * (baseWidth * 0.5), ' 根据需求调整位置逻辑
                    Width:=baseWidth, _
                    Height:=baseHeight _
                )
                ' 设置调整值和名称
                thisBox.Adjustments.Item(1) = cubeAdjustment
                thisBox.Name = nomCarton & "_" & Count
                ' 复制原形状的格式(保持视觉一致)
                refBox.Copy
                thisBox.PasteFormat
                
                Count = Count + 1
            Next iInWidth
        Next iInLength
    Next iInLayers
End If

2. 保留剪贴板复制的兼容处理

若必须使用Copy/Paste,可直接从原形状复制Adjustments值到新形状,无需依赖新形状的属性:

' 粘贴后直接应用原形状的调整值
Set thisBox = Feuil23.Shapes(nomCarton & "_" & Count)
thisBox.Adjustments.Item(1) = refBox.Adjustments.Item(1)

这种方法虽然新形状的AutoShapeType仍可能是msoShapeMixed,但可以正常设置和使用比例调整值。

内容的提问来源于stack exchange,提问作者TomTomZJ

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 02:27:40