从UserForm获取ListBox值时遇运行时错误13:类型不匹配,求解决
解决VBA中AddShape的类型不匹配错误
错误原因
你遇到的运行时错误13:类型不匹配,根源在于ListBox中存储的是字符串(比如"msoShapeRectangle"),但Shapes.AddShape的Type参数需要的是MsoAutoShapeType枚举类型的数值,而非字符串本身。直接把字符串传给Type参数,自然会触发类型不匹配。
解决方案
方案1:让ListBox存储枚举数值,显示友好名称
这种方法最可靠,避免字符串转数值的麻烦:
- 修改UserForm的初始化代码:
Public Sub UserForm_Initialize() ' 添加名称和对应的枚举值,ListBox用多列存储 With UserForm1.ListBox1 .ColumnCount = 2 ' 设置为2列 .ColumnWidths = "120;0" ' 隐藏第二列(数值列) ' 添加第一项:五边形 .AddItem "五边形" .List(.ListCount - 1, 1) = msoShapePentagon ' 添加第二项:矩形 .AddItem "矩形" .List(.ListCount - 1, 1) = msoShapeRectangle ' 添加第三项:笑脸 .AddItem "笑脸" .List(.ListCount - 1, 1) = msoShapeSmileyFace End With End Sub
- 修改Macro2中获取类型的代码:
Public Sub Macro2() ActivePresentation.Slides.Add 1, ppLayoutBlank ' 直接取ListBox中存储的枚举数值 Dim shapeType As MsoAutoShapeType shapeType = UserForm1.ListBox1.List(UserForm1.ListBox1.ListIndex, 1) MsgBox shapeType ' 现在可以正常调用AddShape ActivePresentation.Slides(1).Shapes.AddShape Type:=shapeType, Left:=0, Top:=0, Width:=480, Height:=100 UserForm1.Unload ' 用完记得卸载窗体 End Sub
方案2:将字符串转换为枚举数值(Select Case方式)
如果不想修改ListBox的显示方式,可以用Select Case把选中的字符串映射为对应的枚举值:
修改Macro2代码:
Public Sub Macro2() ActivePresentation.Slides.Add 1, ppLayoutBlank Dim myVariant As String myVariant = UserForm1.ListBox1.Value MsgBox myVariant Dim shapeType As MsoAutoShapeType ' 字符串转枚举值 Select Case myVariant Case "msoShapePentagon" shapeType = msoShapePentagon Case "msoShapeRectangle" shapeType = msoShapeRectangle Case "msoShapeSmileyFace" shapeType = msoShapeSmileyFace Case Else MsgBox "未知形状类型" Exit Sub End Select ' 调用AddShape ActivePresentation.Slides(1).Shapes.AddShape Type:=shapeType, Left:=0, Top:=0, Width:=480, Height:=100 UserForm1.Unload End Sub
方案3:用Eval函数直接解析字符串(简易但需注意安全)
如果代码是完全可控的,可以用Eval函数直接把字符串解析为枚举值:
修改Macro2中相关代码:
Public Sub Macro2() ActivePresentation.Slides.Add 1, ppLayoutBlank Dim myVariant As String myVariant = UserForm1.ListBox1.Value MsgBox myVariant ' 用Eval解析字符串为枚举值 Dim shapeType As MsoAutoShapeType shapeType = Eval(myVariant) ActivePresentation.Slides(1).Shapes.AddShape Type:=shapeType, Left:=0, Top:=0, Width:=480, Height:=100 UserForm1.Unload End Sub
注意:Eval会执行传入的字符串代码,若字符串来源不可控(比如用户输入),可能存在安全风险,仅在自己编写的固定列表中使用。
额外建议
调用完窗体后记得用Unload UserForm1释放资源,避免窗体在后台残留。
内容的提问来源于stack exchange,提问作者Danny Coleiro
相关产品推荐
相关产品推荐

