Динамический диапазон для скрытия строк

#excel #vba

#excel #vba

Вопрос:

У меня есть рабочая книга, где у меня есть кнопки для скрытия и отображения строк. Поэтому, когда строки скрыты, одна кнопка также скрыта, а затем наоборот. Тогда у меня есть диапазон, который должен быть скрыт и не отображаться при нажатии кнопок. Есть ли какой-нибудь способ сделать это как-то динамичным?

Проблема в том, что у меня около 40 кнопок, и как только я вношу некоторые изменения в калькулятор и добавляю новую строку в свой рабочий лист, мне приходится переписывать все диапазоны. Диапазоны расположены последовательно, поэтому они выглядят следующим образом:

 Range("1254:1275").EntireRow.Hidden = True
Range("1254:1275").EntireRow.Hidden = False
next one
Range("1276:1298").EntireRow.Hidden = True
Range("1276:1298").EntireRow.Hidden = False
next one
Range("1299:1350").EntireRow.Hidden = True
Range("1299:1350").EntireRow.Hidden = False
etc.
 

Возможно ли каким-то образом иметь что-то вроде 22 вместо 1254:1275 ? Тогда 23 вместо 1276:1298 etc.?

Для 40 кнопок у меня есть 80 вспомогательных элементов (1 для скрытия и 1 для отображения). Каждая операция в собственном подразделе выглядит так:

КНОПКА СКРЫТЬ:

 Sub WorkshopWork_HideMe()

Application.ScreenUpdating = False
ThisWorkbook.Sheets("Price calculation").Unprotect Password:="123"
Range("1254:1275").EntireRow.Hidden = True
ActiveSheet.Shapes("Rectangle: Rounded Corners 111").Visible = True
ActiveSheet.Shapes("Rectangle: Rounded Corners 233").Visible = False
ThisWorkbook.Sheets("Price calculation").Protect Password:="123"
Application.ScreenUpdating = True

End Sub
 

КНОПКА ПОКАЗАТЬ:

 Sub WorkshopwnWork_UnhideMe()

Application.ScreenUpdating = False
ThisWorkbook.Sheets("Price calculation").Unprotect Password:="123"
Range("1254:1275").EntireRow.Hidden = False
ActiveSheet.Shapes("Rectangle: Rounded Corners 111").Visible = False
ActiveSheet.Shapes("Rectangle: Rounded Corners 233").Visible = True

ActiveWindow.ScrollRow = 1254
ThisWorkbook.Sheets("Price calculation").Protect Password:="123"
Application.ScreenUpdating = True

End Sub
 

Комментарии:

1. Проверьте Resize и Offset .

2. Что определяет диапазоны? Вы всегда можете использовать именованные диапазоны, поэтому нет необходимости вносить изменения в код, просто обновляйте именованные диапазоны

3. Вы могли бы создать класс, чтобы при каждом нажатии кнопки он запускал класс. Это означает, что вам не нужно добавлять код для каждой кнопки

Ответ №1:

Да, вы могли бы сделать что-то подобное, чтобы сделать rows index динамический:

 Dim startRow As Integer

startRow = 1200
Range(startRow   54 amp; ":" amp; startRow   75).EntireRow.Hidden = True
Range(startRow   54 amp; ":" amp; startRow   75).EntireRow.Hidden = False
 

Вы можете объявить свою переменную как a Public Constant , и они будут использовать ее во всех ваших functions :

 'This goes at the start of a Module, outside any Sub or Function
Public Const startRow As Integer = 1200

'Example Button1
Sub mySubButton1()
    Range(startRow   54 amp; ":" amp; startRow   75).EntireRow.Hidden = True
    Range(startRow   54 amp; ":" amp; startRow   75).EntireRow.Hidden = False
End Sub

'Example Button2
Sub mySubButton2()
    Range(startRow   100 amp; ":" amp; startRow   125).EntireRow.Hidden = True
    Range(startRow   100 amp; ":" amp; startRow   125).EntireRow.Hidden = False
End Sub
 

Надеюсь, это поможет.

Комментарии:

1. Спасибо! Это выглядит хорошо, но как заставить его работать, если у меня есть собственный подраздел для каждой кнопки?

2.@user7202022 Вы можете объявить startRow как Public Constant ( Public Const startRow As Integer = 1200 ), а затем использовать его во всех своих Functions . Я соответствующим образом отредактирую код своего ответа. 🙂

Ответ №2:

Попробуйте использовать Application.Caller .

 Sub btnS()

Set wsAuth = ThisWorkbook.Worksheets("Data")
    ColumnNr = wsAuth.Buttons(Application.Caller).TopLeftCell.Column
    RowNr = wsAuth.Buttons(Application.Caller).TopLeftCell.Row
    Range(RowNr   54 amp; ":" amp; RowNr   75).EntireRow.Hidden = True


End Sub
 

Ответ №3:

Вы могли бы попробовать:

 Option Explicit


Sub test()

    Dim arr As Variant, i As Long

    arr = Array(1254, 1276, 1299) '<- Create an array with all row you want to change

    For i = LBound(arr) To UBound(arr) '<- loop array

        Call Module1.Hide(arr(i)) '<- Call Hide sub

    Next i

End Sub

Sub Hide(ByVal Value As Long)

    Dim y As Long

    With ThisWorkbook.Worksheets("Sheet1")

         If Value = 1254 Then '<- Check value

            y = 22

        ElseIf Value = 1276 Then
            y = 23

        End If

        .Range(Value amp; ":" amp; Value   y).EntireRow.Hidden = True

    End With

End Sub
 

Ответ №4:

Я бы создал и поддерживал именованный диапазон, который перемещается и изменяется в соответствии с вашими требованиями. Вам нужно включить ячейки только в первый столбец, если вы переключаете отображение всей строки.

введите описание изображения здесь

Оттуда вы можете включить этот диапазон в свой код, вы можете увидеть его в вызове диапазона в приведенной ниже процедуре. Если вы затем вставляете или удаляете строки, форма именованного диапазона автоматически изменяется.

Вы также можете улучшить свою процедуру, чтобы принимать логическое значение для отображения, а затем обрабатывать его с помощью прокси-процедуры для скрытия и отображения.

 Sub WorkshopWork_HideMe()
    ToggleHideShow False
End Sub

Sub WorkshopWork_ShowMe()
    ToggleHideShow True
End Sub

Private Sub ToggleHideShow(ByVal bShow As Boolean)
    Application.ScreenUpdating = False

    ThisWorkbook.Sheets("Price calculation").Unprotect Password:="123"

    Range("ShowHideRange").EntireRow.Hidden = Not bShow

    ActiveSheet.Shapes("Rectangle: Rounded Corners 111").Visible = bShow
    ActiveSheet.Shapes("Rectangle: Rounded Corners 233").Visible = Not bShow

    ThisWorkbook.Sheets("Price calculation").Protect Password:="123"

    Application.ScreenUpdating = True
End Sub
 

В любом случае есть о чем подумать.