Excel VBA在命令按钮上显示/隐藏图像或形状单击事件对数据进行排序
我正在开发一个程序,它有多个数据列,可以按多个列进行排序。对于美学,我使用命令按钮单击事件以升序或降序切换排序。我的代码非常简单。我使用“向上”箭头和“向下”箭头的图像作为上升/下降指示器。所有图像都在工作表上,根据排序方法,“单击”事件会显示或隐藏相应的图像。编码工作正常,但有一个问题我没有考虑。当用户单击按钮进行排序时,该箭头会正确显示和隐藏该列,但其他列仍会显示箭头,这可能会混淆用户。我想隐藏除正在排序的列中的图像/箭头之外的其他图像/箭头 请参见所附图片以了解说明 在上图中,如果再次按下播放器ID命令按钮,向上箭头将隐藏,向下箭头将可见,但其他箭头将保持不变。我只希望列被排序以显示箭头 下面的代码在工作表模块中使用命令按钮单击事件Excel VBA在命令按钮上显示/隐藏图像或形状单击事件对数据进行排序,excel,vba,click,show-hide,shapes,Excel,Vba,Click,Show Hide,Shapes,我正在开发一个程序,它有多个数据列,可以按多个列进行排序。对于美学,我使用命令按钮单击事件以升序或降序切换排序。我的代码非常简单。我使用“向上”箭头和“向下”箭头的图像作为上升/下降指示器。所有图像都在工作表上,根据排序方法,“单击”事件会显示或隐藏相应的图像。编码工作正常,但有一个问题我没有考虑。当用户单击按钮进行排序时,该箭头会正确显示和隐藏该列,但其他列仍会显示箭头,这可能会混淆用户。我想隐藏除正在排序的列中的图像/箭头之外的其他图像/箭头 请参见所附图片以了解说明 在上图中,如果再次按
Private Sub cmbAgentID_Click()
If ActiveSheet.Shapes.Range(Array("picAgentIDUp")).Visible = False Then
Call SortByAgentAsc 'sort ascending
ActiveSheet.Shapes.Range(Array("picAgentIDUp")).Visible = True
ActiveSheet.Shapes.Range(Array("picAgentIDDown")).Visible = False
Else
Call SortByAgentDes 'sort descending
ActiveSheet.Shapes.Range(Array("picAgentIDDown")).Visible = True
ActiveSheet.Shapes.Range(Array("picAgentIDUp")).Visible = False
End If
End Sub
Private Sub cmbAllHands_Click()
If ActiveSheet.Shapes.Range(Array("picAllHandsUp")).Visible = False Then
Call SortByHandsAsc 'sort ascending
ActiveSheet.Shapes.Range(Array("picAllHandsUp")).Visible = True
ActiveSheet.Shapes.Range(Array("picAllHandsDown")).Visible = False
Else
Call SortByHandsDes 'sort descending
ActiveSheet.Shapes.Range(Array("picAllHandsDown")).Visible = True
ActiveSheet.Shapes.Range(Array("picAllHandsUp")).Visible = False
End If
End Sub
Private Sub cmbCashHands_Click()
If ActiveSheet.Shapes.Range(Array("picCashUp")).Visible = False Then
Call SortByCashAsc 'sort ascending
ActiveSheet.Shapes.Range(Array("picCashUp")).Visible = True
ActiveSheet.Shapes.Range(Array("picCashDown")).Visible = False
Else
Call SortByCashDes 'sort descending
ActiveSheet.Shapes.Range(Array("picCashDown")).Visible = True
ActiveSheet.Shapes.Range(Array("picCashUp")).Visible = False
End If
End Sub
Private Sub cmbEmbers_Click()
If ActiveSheet.Shapes.Range(Array("picEmbersUp")).Visible = False Then
Call SortByEmbersAsc 'sort ascending
ActiveSheet.Shapes.Range(Array("picEmbersUp")).Visible = True
ActiveSheet.Shapes.Range(Array("picEmbersDown")).Visible = False
Else
Call SortByEmbersDes 'sort descending
ActiveSheet.Shapes.Range(Array("picEmbersDown")).Visible = True
ActiveSheet.Shapes.Range(Array("picEmbersUp")).Visible = False
End If
End Sub
Private Sub cmbFees_Click()
If ActiveSheet.Shapes.Range(Array("picFeeUp")).Visible = False Then
Call SortByFeeAsc 'sort ascending
ActiveSheet.Shapes.Range(Array("picFeeUp")).Visible = True
ActiveSheet.Shapes.Range(Array("picFeeDown")).Visible = False
Else
Call SortByFeeDes 'sort descending
ActiveSheet.Shapes.Range(Array("picFeeDown")).Visible = True
ActiveSheet.Shapes.Range(Array("picFeeUp")).Visible = False
End If
End Sub
有什么建议吗?我一直在寻找ShapeRange,这对我和ShapeArray来说是新的,但还没有找到我要找的东西
-------更新了下面的代码,但建议的改进不起作用-------
创建“旋转它”子对象,并将宏指定给单个箭头
Sub RotateIt()
Dim s As Shape: Set s = ActiveSheet.Shapes(Application.Caller)
If s.Rotation = 0 Then
s.Rotation = 180
Else
s.Rotation = 0
End If
End Sub
创建了1个子排序,我想我的问题在这里
Sub SortByEverything(sortKey As Range, Optional boolAsc As Boolean)
Dim sh As Worksheet: Set sh = ActiveSheet
Dim lastrow As Long: lastrow = Cells(Rows.Count, 2).End(xlUp).Row
Dim rng As Range: Set rng = sh.Range("B3:M" & lastrow)
If boolAsc Then
With rng 'your existing code for ACENDING sorting type, but using supplied sortKey...
.Sort Key1:=sortKey, Order1:=xlAscending, Header:=xlYes
End With
Debug.Print "Sort Ascending..."
Else
With rng 'your existing code for ACENDING sorting type, but using supplied sortKey...
.Sort Key1:=sortKey, Order1:=xlAscending, Header:=xlYes
End With
Debug.Print "Sort Descending..."
End If
End Sub
已创建类模块按钮名
Option Explicit
Public WithEvents cmdButton As MSForms.CommandButton
创建工作表激活子项
Option Explicit
Private arrEvents As Collection
请尝试下一种方法。创建要由所有按钮调用的
子,单击事件:
Sub HideArrows(sh As Worksheet)
Dim s As Shape
For Each s In sh.Shapes
If Right(s.Name, 2) = "Up" Or _
Right(s.Name, 4) = "Down" Then s.Visible = msoFalse
Next
End Sub
然后以以下方式使用现有代码:
Private Sub cmbAgentID_Click() 'proceed in a similar way to all the other click events
Dim sh As Worksheet: Set sh = ActiveSheet
HideArrows sh
If sh.Shapes.Range(Array("picAgentIDUp")).Visible = False Then
Call SortByAgentAsc 'sort ascending
sh.Shapes.Range(Array("picAgentIDUp")).Visible = True
Else
Call SortByAgentDes 'sort descending
sh.Shapes.Range(Array("picAgentIDDown")).Visible = True
End If
End Sub
编辑:请尝试下一种不同的方法。它非常紧凑标准模块中的下一个代码将是所有必要的代码:
创建单个(向上)箭头形状并将其命名为“箭头”
每个(表单类型)按钮将针对相同的子项
,因此为所有按钮分配下一个代码。对于ActiveX按钮,我将在结尾展示方法(稍微复杂一点,但不会太多):
使用下一步内置的排序Subs
。他们将根据每个按下的按钮位置接收分拣键:
要更改箭头方向/排序类型,请为“箭头”形状指定下一个代码:
下一个方法是:按下按钮时,“箭头”形状将移动到其右侧。根据其旋转
属性,排序将按升序或降序进行。然后将调整箭头旋转。如果它仍然是向下的,并且下次,对于不同的列,您需要按降序排序,只需单击箭头形状,它将根据相应的排序类型进行旋转。您只需要一个排序Sub
被告知有关排序键和排序类型的
对于ActiveX按钮,Application.Coller
不会返回调用子名称的形状,并且需要类事件包装器
a) 插入一个类模块,将其命名为ButtonName
,然后复制下一个代码:
Option Explicit
Public WithEvents cmdButton As MSForms.CommandButton
Public Sub cmdButton_Click()
Dim sArr As Shape: Set sArr = ActiveSheet.Shapes("Arrow")
sArr.top = cmdButton.top: sArr.left = cmdButton.left + cmdButton.width
If sArr.Rotation = 0 Then
SortByEverything cmdButton.TopLeftCell, True
sArr.Rotation = 180
Else
SortByEverything cmdButton.TopLeftCell
sArr.Rotation = 0
End If
End Sub
注意:所有ActiveX按钮都不需要单击事件(对于此特定任务)
b) 在图纸级别模块中创建一个私有变量。除此之外,在声明区域:
Public arrEvents As Collection
c) 使用工作表\u Activate
事件(当然在保留按钮的工作表中),为所有ActiveX类型按钮初始化类:
Private Sub Worksheet_Activate()
Dim ActXButEvents As ButtonName, shp As Shape
Set arrEvents = New Collection
For Each shp In Me.Shapes
If shp.Type = msoOLEControlObject Then
If TypeOf shp.OLEFormat.Object.Object Is MSForms.CommandButton Then
Set ActXButEvents = New ButtonName
Set ActXButEvents.cmdButton = shp.OLEFormat.Object.Object
arrEvents.aDD ActXButEvents
End If
End If
Next
End Sub
注意:当您有代码时,如果不触发工作表激活事件,则无法按下工作表上的按钮。但是,在代码准备过程中,需要激活另一个工作表,然后重新激活它。只是为了触发前面提到的事件
如果感兴趣,请检查并发送一些反馈。请尝试下一种方法。创建要由所有按钮调用的子,单击事件:
Sub HideArrows(sh As Worksheet)
Dim s As Shape
For Each s In sh.Shapes
If Right(s.Name, 2) = "Up" Or _
Right(s.Name, 4) = "Down" Then s.Visible = msoFalse
Next
End Sub
然后以以下方式使用现有代码:
Private Sub cmbAgentID_Click() 'proceed in a similar way to all the other click events
Dim sh As Worksheet: Set sh = ActiveSheet
HideArrows sh
If sh.Shapes.Range(Array("picAgentIDUp")).Visible = False Then
Call SortByAgentAsc 'sort ascending
sh.Shapes.Range(Array("picAgentIDUp")).Visible = True
Else
Call SortByAgentDes 'sort descending
sh.Shapes.Range(Array("picAgentIDDown")).Visible = True
End If
End Sub
编辑:请尝试下一种不同的方法。它非常紧凑标准模块中的下一个代码将是所有必要的代码:
创建单个(向上)箭头形状并将其命名为“箭头”
每个(表单类型)按钮将针对相同的子项
,因此为所有按钮分配下一个代码。对于ActiveX按钮,我将在结尾展示方法(稍微复杂一点,但不会太多):
使用下一步内置的排序Subs
。他们将根据每个按下的按钮位置接收分拣键:
要更改箭头方向/排序类型,请为“箭头”形状指定下一个代码:
下一个方法是:按下按钮时,“箭头”形状将移动到其右侧。根据其旋转
属性,排序将按升序或降序进行。然后将调整箭头旋转。如果它仍然是向下的,并且下次,对于不同的列,您需要按降序排序,只需单击箭头形状,它将根据相应的排序类型进行旋转。您只需要一个排序Sub
被告知有关排序键和排序类型的
对于ActiveX按钮,Application.Coller
不会返回调用子名称的形状,并且需要类事件包装器
a) 插入一个类模块,将其命名为ButtonName
,然后复制下一个代码:
Option Explicit
Public WithEvents cmdButton As MSForms.CommandButton
Public Sub cmdButton_Click()
Dim sArr As Shape: Set sArr = ActiveSheet.Shapes("Arrow")
sArr.top = cmdButton.top: sArr.left = cmdButton.left + cmdButton.width
If sArr.Rotation = 0 Then
SortByEverything cmdButton.TopLeftCell, True
sArr.Rotation = 180
Else
SortByEverything cmdButton.TopLeftCell
sArr.Rotation = 0
End If
End Sub
注意:所有ActiveX按钮都不需要单击事件(对于此特定任务)
b) 创建Pri
Public arrEvents As Collection
Private Sub Worksheet_Activate()
Dim ActXButEvents As ButtonName, shp As Shape
Set arrEvents = New Collection
For Each shp In Me.Shapes
If shp.Type = msoOLEControlObject Then
If TypeOf shp.OLEFormat.Object.Object Is MSForms.CommandButton Then
Set ActXButEvents = New ButtonName
Set ActXButEvents.cmdButton = shp.OLEFormat.Object.Object
arrEvents.aDD ActXButEvents
End If
End If
Next
End Sub
Private Sub cmbAgentID_Click()
Dim sh As Worksheet: Set sh = ActiveSheet
If sh.Shapes.Range(Array("picAgentIDUp")).Visible = msoFalse Then
hidedownarrows sh
Call SortByAgentAsc 'sort ascending
With sh.Shapes
.Range(Array("picAgentIDUp")).Visible = msoTrue
.Range(Array("picCashUp", "picAllHandsUp", "picEmbersUp", "picRBAmtUp", "PicRBUp", "picFeeUp", "picIDUp")).Visible = msoFalse
End With
Else
HideupArrows sh
Call SortByAgentDes 'sort descending
With sh.Shapes
.Range(Array("picAgentIDDown")).Visible = msoTrue
.Range(Array("picCashdown", "picAllHandsdown", "picEmbersdown", "picRBAmtdown", "PicRBdown", "picFeedown", "picIDdown")).Visible = msoFalse
End With
End If
End Sub
Private Sub cmbAllHands_Click()
Dim sh As Worksheet: Set sh = ActiveSheet
If sh.Shapes.Range(Array("picAllHandsUp")).Visible = msoFalse Then
hidedownarrows sh
Call SortByHandsAsc 'sort ascending
With sh.Shapes
.Range(Array("picAllHandsUp")).Visible = msoTrue
.Range(Array("picCashUp", "picAgentIDUp", "picEmbersUp", "picRBAmtUp", "PicRBUp", "picFeeUp", "picIDUp")).Visible = msoFalse
End With
Else
HideupArrows sh
Call SortByHandsDes 'sort descending
With sh.Shapes
.Range(Array("picAllHandsDown")).Visible = msoTrue
.Range(Array("picCashdown", "picAgentIDdown", "picEmbersdown", "picRBAmtdown", "PicRBdown", "picFeedown", "picIDdown")).Visible = msoFalse
End With
End If
End Sub
Private Sub cmbCashHands_Click()
Dim sh As Worksheet: Set sh = ActiveSheet
If sh.Shapes.Range(Array("picCashUp")).Visible = msoFalse Then
hidedownarrows sh
Call SortByCashAsc 'sort ascending
With sh.Shapes
.Range(Array("picCashUp")).Visible = msoTrue
.Range(Array("picAllHandsUp", "picAgentIDUp", "picEmbersUp", "picRBAmtUp", "PicRBUp", "picFeeUp", "picIDUp")).Visible = msoFalse
End With
Else
HideupArrows sh
Call SortByCashDes 'sort descending
With sh.Shapes
.Range(Array("picCashDown")).Visible = msoTrue
.Range(Array("picAllHandsDown", "picAgentIDdown", "picEmbersdown", "picRBAmtdown", "PicRBdown", "picFeedown", "picIDdown")).Visible = msoFalse
End With
End If
End Sub
Private Sub cmbEmbers_Click()
Dim sh As Worksheet: Set sh = ActiveSheet
If sh.Shapes.Range(Array("picEmbersUp")).Visible = msoFalse Then
hidedownarrows sh
Call SortByEmbersAsc 'sort ascending
With sh.Shapes
.Range(Array("picEmbersUp")).Visible = msoTrue
.Range(Array("picAllHandsUp", "picAgentIDUp", "picCashUp", "picRBAmtUp", "PicRBUp", "picFeeUp", "picIDUp")).Visible = msoFalse
End With
Else
HideupArrows sh
Call SortByEmbersDes 'sort descending
With sh.Shapes
.Range(Array("picEmbersDown")).Visible = msoTrue
.Range(Array("picAllHandsDown", "picAgentIDdown", "picCashDown", "picRBAmtdown", "PicRBdown", "picFeedown", "picIDdown")).Visible = msoFalse
End With
End If
End Sub
Private Sub cmbFees_Click()
Dim sh As Worksheet: Set sh = ActiveSheet
If sh.Shapes.Range(Array("picFeeUp")).Visible = msoFalse Then
hidedownarrows sh
Call SortByFeeAsc 'sort ascending
With sh.Shapes
.Range(Array("picFeeUp")).Visible = msoTrue
.Range(Array("picAllHandsUp", "picAgentIDUp", "picCashUp", "picRBAmtUp", "PicRBUp", "picEmbersUp", "picIDUp")).Visible = msoFalse
End With
Else
HideupArrows sh
Call SortByFeeDes 'sort descending
With sh.Shapes
.Range(Array("picFeeDown")).Visible = msoTrue
.Range(Array("picAllHandsDown", "picAgentIDdown", "picCashDown", "picRBAmtdown", "PicRBdown", "picEmbersDown", "picIDdown")).Visible = msoFalse
End With
End If
End Sub
Sub HideupArrows(sh As Worksheet)
Dim s As Shape
For Each s In sh.Shapes
If Right(s.Name, 2) = "Up" Then
s.Visible = msoFalse
End If
Next
End Sub
Sub hidedownarrows(sh As Worksheet)
Dim s As Shape
For Each s In sh.Shapes
If Right(s.Name, 4) = "Down" Then
s.Visible = msoFalse
End If
Next
End Sub