Изменение кода кнопки «Далее», чтобы он работал с кнопкой «Назад» - PullRequest
0 голосов
/ 06 декабря 2018

У меня есть кнопка «Далее», которая запускает следующий код.Он копирует содержимое следующей (ниже) строки исходного диапазона и вставляет его в ячейку на листе назначения.

Я также хотел бы иметь аналогичный код, который запускается кнопкой «Предыдущий», котораявместо этого скопируйте / вставьте содержимое предыдущей строки (выше).

Я попытался - 1 вместо + 1, но это не сработало.

Может кто-нибудь здесь помочь мнеизменить код, чтобы правильно создать кнопку «Предыдущий»?

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

1 Ответ

0 голосов
/ 09 декабря 2018

Этот код был написан (мной) для конкретного случая, когда есть только кнопка 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 приводит к ячейке назначения, содержащей значение первой строки исходного диапазона, когда либо Далее или Предыдущий первый раз нажимается после открытия книги.

...