我编写的代码会自动将按钮放在需要的位置并为其指定一个宏:
sudo xcodebuild -license
整个宏如下进行,首先删除工作表上的所有按钮,而不是在需要的地方插入按钮并为其指定宏:
Sub CreateButton(a, b, c, d As Double, s As String)
ActiveSheet.Buttons.Add(a, b, c, d).Select
Selection.name = s
Selection.OnAction = "Button_ACTION"
Selection.Characters.Text = s
End Sub
宏确定按钮的位置并操纵数据。 问题是,无论我点击哪个按钮,数据只会在列中的第一个更改。请告知问题是什么,解决方案是什么?
答案 0 :(得分:1)
问题是您的按钮没有唯一的名称。
我更改了您的CreateButton()
sub,因此可以将名称和标题作为参数。名称是Application.Caller
使用的名称,标题是按钮上写的内容。名称必须是唯一的,所有按钮上的标题都可以相同。
我还添加了一个检查,以便在创建时只接受唯一的按钮名称。
Sub test()
CreateButton 200, 100, 100, 25, "test1", "Test"
CreateButton 50, 50, 100, 25, "test2", "Test"
CreateButton 500, 500, 100, 25, "test3", "Test"
End Sub
Sub CreateButton(left As Double, top As Double, width As Double, height As Double, name As String, caption As String)
On Error Resume Next
ActiveSheet.Buttons(name).name = name
If Err.Number = 0 Then
MsgBox "Name has to be unique"
Exit Sub
End If
On Error GoTo 0
'this part above assures that the name for the button is unique.
With ActiveSheet.Buttons.Add(left, top, width, height)
.name = name
.caption = caption
.OnAction = "Button_ACTION"
End With
End Sub
我强烈建议使用可读变量名而不是a,b,c和o!
请注意
Dim r, i, c As Integer 'r and i are of type variant here only c is integer
CreateButton(a, b, c, d As Double, s As String)
'a, b and c are of type variant. Only d is double and s is string.
与
不同Dim r As Integer, i As Integer, c As Integer
CreateButton(a As Double, b As Double, c As Double, d As Double, s As String)
答案 1 :(得分:0)
首先 - 尽量不要使用selection
!
第二 - 为什么你需要使用integers
? Use Longs!
你的问题(我假设)是因为你一遍又一遍地给出相同的名字,所以用Set o = ActiveSheet.Buttons(Application.Caller)
行你选择给定名字的第一个按钮!
由于你没有提到你的和 来自哪里(和),因此从那里调用类似的子CreateButton
只有一个为我重现问题的方法 - 使用相同的s
参数多次调用sub。
注意:Application.Caller是一个string
,在你的案例中有一个按钮的名称。
尝试给出独特的东西!
Sub CreateButton(a, b, c, d As Double, s As String)
Dim NewButton As Button
Static Counter As Long
Set NewButton = ActiveSheet.Buttons.Add(a, b, c, d)
NewButton.Name = s & Counter
NewButton.OnAction = "Button_ACTION"
NewButton.Characters.Text = s
Counter = Counter + 1
End Sub
但我建议你研究你的名字的独特性。
Static
计数器是好的,如果你不是一个完美主义者,你对Long
类型限制很好,并且在退出excel时删除了所有按钮。
我建议你不要希望它 - 当你需要一些独特的东西时 - 总是使用dictionary
。
使用dictionary
,您可以轻松回答问题"该字符串是否真的独一无二?":
Public Function IsUnique(ByVal str As String) As Boolean
Static UniqueDict As New Dictionary
If UniqueDict.Exists(str) Then _
Exit Function
Call UniqueDict.Add(Key:=str, Item:=str)
IsUnique = True
End Function
因此,只有在真正需要时才能编辑字符串或添加内容。 如果您在退出时不打算删除按钮 - 您可以在启动时用名字填写该字典!奇妙不是吗?
要使用
dictionary
对象,您需要参考Microsoft Scripting Runtime!
答案 2 :(得分:0)
为什么在代码中使用Application.Caller ...?它会返回调用者Shape对象..?尝试调试它....,我认为Application.Caller将无法返回调用者Shape(您指定宏的Shape对象)。您可以为您创建的每个Shapes对象指定一个唯一的名称,并通过其名称访问它,这里的示例希望它有用。
Option Explicit
Public Sub AddButtonWithLoop()
Dim btn As Shape
'Use for each loop to Create 3 Shapes, assign name and macro to each Shape
Dim i As Integer
For i = 1 To 3
Set btn = Worksheets(1).Shapes.AddShape(msoShapeBevel, 10, 70 * i, 70, 50)
'set some properties
With btn
.Name = "MyButton" & i
.TextFrame2.TextRange.Characters.Text = "Button " & i
.OnAction = "'SayHello""" & btn.Name & """'"
End With
Next i
End Sub
Public Sub SayHello(shapeName As String)
'Create Shape object using ShapeName
Dim s As Shape: Set s = ActiveSheet.Shapes(shapeName)
With s.TopLeftCell
MsgBox .Row
MsgBox .Column
End With
End Sub