gpt4 book ai didi

vba - 使用 vba 在 Excel 中对形状进行分组和命名

转载 作者:行者123 更新时间:2023-12-02 07:46:07 24 4
gpt4 key购买 nike

在 Excel vba 中,我使用 vba 在 Excel 中创建两个形状。一个箭头,我将其命名为“aro”+ i,以及一个文本框,我将其命名为“text”+ i,其中 i 是一个数字,表示照片的编号。

因此,对于照片 3,我将创建箭头“aro3”和文本框“text3”。

然后我想将它们分组并重命名该组“arotext”+ i,因此在本例中为“arotext3”。

到目前为止,我一直在进行如下分组和重命名:

targetSheet.shapes.Range(Array(Arrow.Name, textBox.Name)).Select
Selection.group
Selection.Name = "AroTxt" & Number

它在子程序中工作得非常好,但现在我想将其更改为一个函数并返回命名组,所以我尝试了这样的方法:

Dim arrowBoxGroup as Object
set arrowBoxGroup = targetSheet.shapes.Range(Array(Arrow.Name, textBox.Name))
arrowBoxGroup.group
arrowBoxGroup.Name = "AroTxt" & Number

当我创建一个与已创建的组同名的新组时,我遇到了问题。因此,如果我创建第二个“aro3”和“text3”,然后尝试对它们进行分组并将该组重命名为“arotext3”,则会收到错误,因为已存在同名的组。

我不明白的是,当我使用引用选择的方法执行此操作时,如果我愿意,我可以使用相同的名称重命名每个组,并且不会出现错误。为什么它在引用 Selection 对象时有效,但在尝试使用分配的对象时失败?

更新:

既然有人问了,我到目前为止的代码如下。 arrow 和 textbox 是指向用户使用表单任意定义的方向的箭头和文本框。

然后,这会在目标工作表上以正确的角度创建一个箭头,并在箭头末尾放置一个具有指定数字(也通过表单)的文本框,以便它有效地形成标注。我知道有标注,但它们不符合我的要求,所以我必须自己制作。

我必须对文本框和箭头进行分组,因为 1) 它们属于一起,2) 我使用组的名称作为引用来跟踪已​​经放置的标注,3) 用户必须将标注放在右侧工作表中嵌入的 map 上的位置。

到目前为止,我已经通过将返回值设置为 GroupObject 来将其变成一个函数。但这仍然依赖于 Sheet.Shapes.range().Select,在我看来这是一个非常糟糕的方法。我正在寻找一种不依赖于选择对象的方法。

我想了解为什么这在使用选择时有效,但在使用强类型变量来保存对象时失败。

    Public Function MakeArrow(ByVal No As Integer, ByVal angle As Double, ByVal size As ArrowSize, ByVal ArrowX As Double, ByVal ArrowY As Double, ByVal TargetInternalAngle As Double, ByRef targetSheet As Worksheet) As GroupObject

Dim Number As String
Dim fontSize As Integer
Dim textboxwidth As Integer
Dim textboxheight As Integer
Dim arrowScale As Double
Dim X1 As Double
Dim Y1 As Double
Dim X2 As Double
Dim Y2 As Double
Dim xBox As Double
Dim yBox As Double
Dim testRange As Range
Dim arrow As Shape
Dim textBox As Shape
' Dim arrowTextbox As ShapeRange
' Dim arrowTextboxGroup As Variant

Select Case size
Case ArrowSize.normal
fontSize = fontSizeNormal
arrowScale = arrowScaleNormal
Case ArrowSize.small
fontSize = fontSizeSmall
arrowScale = arrowScaleSmall
Case ArrowSize.smaller
fontSize = fontSizeSmaller
arrowScale = arrowScaleSmaller
End Select
arrowScale = baseArrowLength * arrowScale

'Estimate required text box width
Number = Trim(CStr(No))
Set testRange = shtTextWidth.Range("A1")
testRange.value = Number
testRange.Font.Name = "MS P明朝"
testRange.Font.size = fontSize
shtTextWidth.Columns(testRange.Column).EntireColumn.AutoFit
shtTextWidth.Columns(testRange.row).EntireRow.AutoFit
textboxwidth = testRange.Width * 0.8
textboxheight = testRange.Height * 0.9
testRange.Clear

'Make arrow
X1 = ArrowX
Y1 = ArrowY
X2 = X1 + arrowScale * Cos(angle)
Y2 = Y1 - arrowScale * Sin(angle)
Set arrow = AddArrow(X1, Y1, X2, Y2, Number, targetSheet)

'Make text box
Set textBox = Addtextbox(angle, Number, fontSize, X2, Y2, textboxwidth, textboxheight, TargetInternalAngle, targetSheet)

'Group arrow and test box
targetSheet.shapes.Range(Array(arrow.Name, textBox.Name)).group.Select
Selection.Name = "AroTxt" & Number

Set MakeArrow = Selection

' Set arrowTextbox = targetSheet.shapes.Range(Array(arrow.Name, textBox.Name))
' Set arrowTextboxGroup = arrowTextbox.group
' arrowTextboxGroup.Name = "AroTxt" & Number
'
' Set MakeArrow = arrowTextboxGroup

End Function

Private Function AddArrow(ByVal StartX As Double, ByVal StartY As Double, ByVal EndX As Double, ByVal EndY As Double, ByVal Number As String, ByRef targetSheet As Worksheet) As Shape

Set AddArrow = targetSheet.shapes.AddLine(StartX, StartY, EndX, EndY)
With AddArrow
.Name = "Aro" & Number
With .Line
.BeginArrowheadStyle = msoArrowheadTriangle
.BeginArrowheadLength = msoArrowheadLengthMedium
.BeginArrowheadWidth = msoArrowheadWidthMedium
.ForeColor.RGB = RGB(0, 0, 255)
End With
End With

End Function

Private Function Addtextbox(ByVal angle As Double, ByVal Number As String, ByVal fontSize As Integer, ByVal arrowEndX As Double, ByVal arrowEndY As Double, ByVal Width As Integer, ByVal Height As Integer, ByVal LimitAngle As Double, ByRef targetSheet As Worksheet) As Shape

Dim xBox, yBox As Integer
Dim PI As Double
Dim horizontalAlignment As eTextBoxHorizontalAlignment
Dim verticalAlignment As eTextBoxVerticalAlignment

PI = 4 * Atn(1)

If LimitAngle = 0 Then
LimitAngle = PI / 4
End If

Select Case angle
'Right
Case 0 To LimitAngle, 2 * PI - LimitAngle To 2 * PI
xBox = arrowEndX
yBox = arrowEndY - Height / 2
horizontalAlignment = eTextBoxHorizontalAlignment.left
verticalAlignment = eTextBoxVerticalAlignment.Center
'Top
Case LimitAngle To PI - LimitAngle
xBox = arrowEndX - Width / 2
yBox = arrowEndY - Height
horizontalAlignment = eTextBoxHorizontalAlignment.Middle
verticalAlignment = eTextBoxVerticalAlignment.Bottom
'Left
Case PI - LimitAngle To PI + LimitAngle
xBox = arrowEndX - Width
yBox = arrowEndY - Height / 2
horizontalAlignment = eTextBoxHorizontalAlignment.Right
verticalAlignment = eTextBoxVerticalAlignment.Center
'Bottom
Case PI + LimitAngle To 2 * PI - LimitAngle
xBox = arrowEndX - Width / 2
yBox = arrowEndY
horizontalAlignment = eTextBoxHorizontalAlignment.Middle
verticalAlignment = eTextBoxVerticalAlignment.top
End Select

Set Addtextbox = targetSheet.shapes.Addtextbox(msoTextOrientationHorizontal, xBox, yBox, Width, Height)
With Addtextbox
.Name = "Txt" & Number
With .TextFrame
.AutoMargins = False
.AutoSize = False
.MarginLeft = 0#
.MarginRight = 0#
.MarginTop = 0#
.MarginBottom = 0#
Select Case verticalAlignment
Case eTextBoxVerticalAlignment.Bottom
.verticalAlignment = xlVAlignBottom
Case eTextBoxVerticalAlignment.Center
.verticalAlignment = xlVAlignCenter
Case eTextBoxVerticalAlignment.top
.verticalAlignment = xlVAlignTop
End Select
Select Case horizontalAlignment
Case eTextBoxHorizontalAlignment.left
.horizontalAlignment = xlHAlignLeft
Case eTextBoxHorizontalAlignment.Middle
.horizontalAlignment = xlHAlignCenter
Case eTextBoxHorizontalAlignment.Right
.horizontalAlignment = xlHAlignRight
End Select
With .Characters
.Text = Number
With .Font
.Name = "MS P明朝"
.FontStyle = "標準"
.size = fontSize
.Strikethrough = False
.Superscript = False
.Subscript = False
.OutlineFont = False
.Shadow = False
.Underline = xlUnderlineStyleNone
.ColorIndex = xlAutomatic
End With
End With
End With
.Fill.Visible = msoFalse
.Fill.Solid
.Fill.Transparency = 1#
With .Line
.Weight = 0.75
.DashStyle = msoLineSolid
.style = msoLineSingle
.Transparency = 0#
.Visible = msoFalse
End With
End With


End Function

最佳答案

Range.Group 返回一个值。您可以尝试:

Set arrowBoxRange = targetSheet.shapes.Range(Array(Arrow.Name, textBox.Name))
Set arrowBoxGroup = arrowBoxRange.Group
arrowBoxGroup.Name = "AroTxt" & Number

我怀疑当前的选择已更新,就像您早期工作中的以下内容一样:

Set Selection = Selection.Group  'it's as if this is done for you when you create the group.

这就是造成差异的原因。

仅供引用,我使用的是 Excel 2010,无法根据选择复制原始代码片段(执行“Selection.Name =”时出现错误,这导致对象不支持属性。)

好的,我可以让它工作:

Selection.Group.Select
Selection.Name = "AroTxt"

当然,就像我建议的其他代码片段一样,这会重新分配组的返回值,以便 Selection.Group 和 Selection.Name 中的 Selection 引用不同的对象,我认为这就是您想要的。

关于vba - 使用 vba 在 Excel 中对形状进行分组和命名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12003100/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com