Этот код был написан (мной) для конкретного случая, когда есть только кнопка Next .
Казалось бы, изменение первого + 1
на - 1
способ изменить код для создания кнопки Previous .Это работает, но есть пара вопросов, которые будут объяснены в ближайшее время.Прежде чем перейти к этому, однако, обратите внимание, что второй + 1
должен остаться без изменений.Он просто преобразует хранимый индекс с нулевым основанием в одноосновный индекс, как того требует свойство Cell
.(И да, для случая только с кнопкой Next было бы проще хранить вместо этого одноосновный индекс. К счастью, сохранение индекса с нуля оказывается самым простым методом для случаяи Далее и Предыдущие кнопки.)
Итак, каковы проблемы с - 1
?
Ну во-первых, хотя это будет правильнообновите индекс, чтобы он указывал на предыдущую строку исходного диапазона, он не может переноситься с первой строки диапазона на последнюю строку.Вместо этого это приводит к ошибке 1004
(поскольку .Cells(sidxCurrentCell + 1).Copy
оценивается как .Cells(0).Copy
).Это связано с тем, что оператор присваивания, содержащий оператор Mod
, был написан самым простым способом для переноса из последней строки в первую строку, без учета обратного регистра.
Во-вторых, поскольку текущий индекс сохраняетсяв качестве статической переменной в подпрограмме, вызываемой при нажатии кнопки, наличие двух таких подпрограмм означает, что есть два сохраненных индекса, работающих независимо друг от друга.Таким образом, предполагая, что оба индекса установлены во второй строке, последовательность нажатий кнопок Next + Next + Previous не приведет к отображению третьейзначение строки, но вместо этого будет отображаться значение первой строки.
Чтобы решить первую проблему, необходимо добавить число строк исходного диапазона в первый операнд оператора Mod
.(Обратите внимание, что с этой модификацией подпрограмма Next также будет продолжать работать правильно.)
Вторая проблема решается с помощью обобщенной подпрограммы Previous / Next, которая принимает параметр для определения направленияи присвоение двух других отдельных подпрограмм каждой кнопке соответственно.Эти вспомогательные подпрограммы просто вызывают основную подпрограмму с соответствующим значением аргумента (1
для кнопки Next и -1
для кнопки Previous ).Таким образом, есть только один сохраненный индекс, который используется обеими кнопками.
Ниже приведен полностью измененный код, где Button1
- кнопка Next , а Button2
- Предыдущая * Кнопка 1054 *:
'============================================================================================
' Module : <any non-class module>
' Version : 0.1.0
' Part : 1 of 1
' References : N/A
' Source : https://stackoverflow.com/a/53690885/1961728
'============================================================================================
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
приводит к ячейке назначения, содержащей значение первой строки исходного диапазона, когда либо Далее или Предыдущий первый раз нажимается после открытия книги.