修改 "Next" 按钮代码,使其与 "Previous" 按钮一起使用
Modifying the "Next" button code so it works with a "Previous" button
我有一个 "Next" 按钮,运行 是以下代码。它复制源范围的下(下)行的内容并将其粘贴到目标 sheet.
中的单元格
我也想要类似的代码,即 运行 通过 "Previous" 按钮 copy/pastes 上一行(上方)的内容代替。
我尝试了 - 1
而不是 + 1
,但是没有用。
这里有人可以帮我修改代码以正确创建 "Previous" 按钮吗?
Option Explicit
Sub Button1_Click()
Const s_DestSheet As String = "MIRCALCULATION"
Const s_DestRange As String = "F5"
Const s_SrcSheet As String = "MIRDATA"
Const s_SrcCell As String = "A1:A100"
Static sidxCurrentCell As Variant: If IsEmpty(sidxCurrentCell) Then sidxCurrentCell = 1
With Worksheets(s_SrcSheet).Range(s_SrcCell)
sidxCurrentCell = (sidxCurrentCell + 1) Mod .Cells.Count
.Cells(sidxCurrentCell + 1).Copy Destination:=Worksheets(s_DestSheet).Range(s_DestRange)
End With
End sub
该代码是(由我)针对只有 Next 按钮的特定情况编写的。
似乎将第一个 + 1
更改为 - 1
将是修改代码以创建 Previous 按钮的方法。这种方法有效,但有几个问题将在稍后解释。然而,在开始之前,请注意第二个 + 1
必须保持不变。它只是根据 Cell
属性 的要求将零基存储索引转换为单基索引。 (是的,对于只有 Next 按钮的情况,存储从一开始的索引会更简单。幸运的是,存储从零开始的索引被证明是最简单的方法对于 Next 和 Previous 按钮的情况。)
那么,- 1
有什么问题?
首先,虽然它会正确更新索引以指向源范围的前一行,但它无法从范围的第一行换行到最后一行。相反,它会导致 1004
错误(因为 .Cells(sidxCurrentCell + 1).Copy
的计算结果为 .Cells(0).Copy
)。这是因为包含 Mod
运算符的赋值语句是以最简单的方式编写的,即从最后一行换行到第一行,不允许相反的情况。
其次,由于当前索引作为静态变量存储在按下按钮时调用的子例程中,因此具有两个这样的子例程意味着有两个存储的索引彼此独立运行。因此,假设索引都设置为第二行,则按钮按下的顺序为 Next+Next+Previous,不会显示第三行的值,而是显示第一行的值。
要解决第一个问题,您需要将源区域的行数添加到 Mod
运算符的第一个操作数。 (请注意,通过此修改,Next 子例程也将继续正常工作。)
第二个问题通过使用一个通用的 Previous/Next 子例程来解决,该子例程采用参数来确定方向,并将另外两个单独的子例程分别分配给每个按钮。这些辅助子例程仅使用适当的参数值调用主例程(Next 按钮的 1
和 Previous[=60 的 -1
=] 按钮)。因此,只有一个存储的索引被两个按钮使用。
以下是完整的修改代码,其中 Button1
是 Next 按钮,Button2
是 Previous 按钮:
'============================================================================================
' Module : <any non-class module>
' Version : 0.1.0
' Part : 1 of 1
' References : N/A
' Source :
'============================================================================================
Option Explicit
Private Sub Next_or_Previous( _
ByRef direction As Long _
)
Dim plngDirection As Long: plngDirection = direction
Const s_DestSheet As String = "MIRCALCULATION"
Const s_DestRange As String = "F5"
Const s_SrcSheet As String = "MIRDATA"
Const s_SrcCell As String = "A1:A100"
Static sidxCurrentCell As Variant: If IsEmpty(sidxCurrentCell) Then sidxCurrentCell = -plngDirection
With Worksheets(s_SrcSheet).Range(s_SrcCell)
sidxCurrentCell = (sidxCurrentCell + plngDirection + .Cells.Count) Mod .Cells.Count
.Cells(sidxCurrentCell + 1).Copy Destination:=Worksheets(s_DestSheet).Range(s_DestRange)
End With
End Sub
Public Sub Button1_Click()
Next_or_Previous 1
End Sub
Public Sub Button2_Click()
Next_or_Previous -1
End Sub
请注意,将 sidxCurrentCell
初始化为 -plngDirection
会在 Next 或 Previous打开工作簿后先按
我有一个 "Next" 按钮,运行 是以下代码。它复制源范围的下(下)行的内容并将其粘贴到目标 sheet.
中的单元格我也想要类似的代码,即 运行 通过 "Previous" 按钮 copy/pastes 上一行(上方)的内容代替。
我尝试了 - 1
而不是 + 1
,但是没有用。
这里有人可以帮我修改代码以正确创建 "Previous" 按钮吗?
Option Explicit
Sub Button1_Click()
Const s_DestSheet As String = "MIRCALCULATION"
Const s_DestRange As String = "F5"
Const s_SrcSheet As String = "MIRDATA"
Const s_SrcCell As String = "A1:A100"
Static sidxCurrentCell As Variant: If IsEmpty(sidxCurrentCell) Then sidxCurrentCell = 1
With Worksheets(s_SrcSheet).Range(s_SrcCell)
sidxCurrentCell = (sidxCurrentCell + 1) Mod .Cells.Count
.Cells(sidxCurrentCell + 1).Copy Destination:=Worksheets(s_DestSheet).Range(s_DestRange)
End With
End sub
该代码是(由我)针对只有 Next 按钮的特定情况编写的。
似乎将第一个 + 1
更改为 - 1
将是修改代码以创建 Previous 按钮的方法。这种方法有效,但有几个问题将在稍后解释。然而,在开始之前,请注意第二个 + 1
必须保持不变。它只是根据 Cell
属性 的要求将零基存储索引转换为单基索引。 (是的,对于只有 Next 按钮的情况,存储从一开始的索引会更简单。幸运的是,存储从零开始的索引被证明是最简单的方法对于 Next 和 Previous 按钮的情况。)
那么,- 1
有什么问题?
首先,虽然它会正确更新索引以指向源范围的前一行,但它无法从范围的第一行换行到最后一行。相反,它会导致 1004
错误(因为 .Cells(sidxCurrentCell + 1).Copy
的计算结果为 .Cells(0).Copy
)。这是因为包含 Mod
运算符的赋值语句是以最简单的方式编写的,即从最后一行换行到第一行,不允许相反的情况。
其次,由于当前索引作为静态变量存储在按下按钮时调用的子例程中,因此具有两个这样的子例程意味着有两个存储的索引彼此独立运行。因此,假设索引都设置为第二行,则按钮按下的顺序为 Next+Next+Previous,不会显示第三行的值,而是显示第一行的值。
要解决第一个问题,您需要将源区域的行数添加到 Mod
运算符的第一个操作数。 (请注意,通过此修改,Next 子例程也将继续正常工作。)
第二个问题通过使用一个通用的 Previous/Next 子例程来解决,该子例程采用参数来确定方向,并将另外两个单独的子例程分别分配给每个按钮。这些辅助子例程仅使用适当的参数值调用主例程(Next 按钮的 1
和 Previous[=60 的 -1
=] 按钮)。因此,只有一个存储的索引被两个按钮使用。
以下是完整的修改代码,其中 Button1
是 Next 按钮,Button2
是 Previous 按钮:
'============================================================================================
' Module : <any non-class module>
' Version : 0.1.0
' Part : 1 of 1
' References : N/A
' Source :
'============================================================================================
Option Explicit
Private Sub Next_or_Previous( _
ByRef direction As Long _
)
Dim plngDirection As Long: plngDirection = direction
Const s_DestSheet As String = "MIRCALCULATION"
Const s_DestRange As String = "F5"
Const s_SrcSheet As String = "MIRDATA"
Const s_SrcCell As String = "A1:A100"
Static sidxCurrentCell As Variant: If IsEmpty(sidxCurrentCell) Then sidxCurrentCell = -plngDirection
With Worksheets(s_SrcSheet).Range(s_SrcCell)
sidxCurrentCell = (sidxCurrentCell + plngDirection + .Cells.Count) Mod .Cells.Count
.Cells(sidxCurrentCell + 1).Copy Destination:=Worksheets(s_DestSheet).Range(s_DestRange)
End With
End Sub
Public Sub Button1_Click()
Next_or_Previous 1
End Sub
Public Sub Button2_Click()
Next_or_Previous -1
End Sub
请注意,将 sidxCurrentCell
初始化为 -plngDirection
会在 Next 或 Previous打开工作簿后先按