Уважаемые форумчане!! Помогите с решением вопроса. Имеется книга, на ней множество листов с информацией (фрукты, крупы и т.д.). Часть данных на листы вносятся с помощью "Выпадающего списока с добавлением новых элементов", которые находятся на листе "данные". Лист "итоги" служит для обобщения данных по годам и наименованию. Необходима Ваша помощь, в написании макроса для листа "итоги", который в свою очередь реагировал бы на пустые строки и соответсвенно скрывал их (в моем случае строки A6:A19 и B24:B37). Если, к примеру, добавляются новые сведения по продукции, то они автоматически добавляются в "итоги" и заполненная строка отображается. Спасибо.
Уважаемые форумчане!! Помогите с решением вопроса. Имеется книга, на ней множество листов с информацией (фрукты, крупы и т.д.). Часть данных на листы вносятся с помощью "Выпадающего списока с добавлением новых элементов", которые находятся на листе "данные". Лист "итоги" служит для обобщения данных по годам и наименованию. Необходима Ваша помощь, в написании макроса для листа "итоги", который в свою очередь реагировал бы на пустые строки и соответсвенно скрывал их (в моем случае строки A6:A19 и B24:B37). Если, к примеру, добавляются новые сведения по продукции, то они автоматически добавляются в "итоги" и заполненная строка отображается. Спасибо.graffserg
Добрый день! Вот такой вариант: При любом изменении ячеек на листе "данные", проверяем на нули 1 столбец листа "итоги", если 0 - скрыть строку, в противном случае показать. Добавьте обработчик в модуль листа "данные". [vba]
Код
Private Sub Worksheet_Change(ByVal Target As Range) Dim rCell As Range With Sheets("итоги") For Each rCell In .Cells(.UsedRange.Row, 1).Resize(.UsedRange.Rows.Count) If Not IsEmpty(rCell) Then rCell.EntireRow.Hidden = IIf(rCell.Value = 0, True, False) Next rCell End With End Sub
[/vba]
Добрый день! Вот такой вариант: При любом изменении ячеек на листе "данные", проверяем на нули 1 столбец листа "итоги", если 0 - скрыть строку, в противном случае показать. Добавьте обработчик в модуль листа "данные". [vba]
Код
Private Sub Worksheet_Change(ByVal Target As Range) Dim rCell As Range With Sheets("итоги") For Each rCell In .Cells(.UsedRange.Row, 1).Resize(.UsedRange.Rows.Count) If Not IsEmpty(rCell) Then rCell.EntireRow.Hidden = IIf(rCell.Value = 0, True, False) Next rCell End With End Sub
Спасибо Mikael огромное!!! Макрос работает, но есть одно но, или даже несколько. Дело в том, что в реальном примере, на листе «итоги» присутствует кнопка(и) (своего рода сопоставление данных по годам), которые отображают/скрывают суммарную информацию о работе сотрудника с других листов и к ним прикреплен макрос: [vba]
Код
Sub Click_2014() Worksheets("итоги").Unprotect Password:="123456" Columns("J:V").Hidden = IIf(Columns("J:V").Hidden, False, True) Worksheets("итоги").Protect Password:="123456" End Sub
[/vba] Соответственно, когда срабатывает макрос, то он автоматически делает видимыми все ранее скрытые строки, которые спрятал предыдущий макрос. Возможно, ли сделать так, чтобы макрос, который написали Вы: 1. реагировал на изменения и скрывал строки только в определенном диапазоне(ах), например A10:A40, A45:A60, A70:A90 и т.д.? 2. работал на нескольких листах, например «итоги» и «итоги_2»? И еще: - практически все листы в книге скрываются автоматически, т.к. используется оглавление; - практически все защищены паролем, от «кривых» рук и ввод данных разрешен в определенных ячейках. Спасибо!!
Спасибо Mikael огромное!!! Макрос работает, но есть одно но, или даже несколько. Дело в том, что в реальном примере, на листе «итоги» присутствует кнопка(и) (своего рода сопоставление данных по годам), которые отображают/скрывают суммарную информацию о работе сотрудника с других листов и к ним прикреплен макрос: [vba]
Код
Sub Click_2014() Worksheets("итоги").Unprotect Password:="123456" Columns("J:V").Hidden = IIf(Columns("J:V").Hidden, False, True) Worksheets("итоги").Protect Password:="123456" End Sub
[/vba] Соответственно, когда срабатывает макрос, то он автоматически делает видимыми все ранее скрытые строки, которые спрятал предыдущий макрос. Возможно, ли сделать так, чтобы макрос, который написали Вы: 1. реагировал на изменения и скрывал строки только в определенном диапазоне(ах), например A10:A40, A45:A60, A70:A90 и т.д.? 2. работал на нескольких листах, например «итоги» и «итоги_2»? И еще: - практически все листы в книге скрываются автоматически, т.к. используется оглавление; - практически все защищены паролем, от «кривых» рук и ввод данных разрешен в определенных ячейках. Спасибо!!graffserg
2. работал на нескольких листах, например «итоги» и «итоги_2»?
[vba]
Код
For Each Sh In Array("итоги", "итоги_2", ... , "итоги_n")
[/vba]
все вместе будет выглядеть так (диапазоны из Вашего файла в 1 посте): [vba]
Код
Private Sub Worksheet_Change(ByVal Target As Range) Dim rCell As Range, Sh As Variant For Each Sh In Array("итоги", "итоги_2") For Each rCell In Sheets(Sh).Range("A6:A19, A24:A37") If Not IsEmpty(rCell) Then rCell.EntireRow.Hidden = IIf(rCell.Value = 0, True, False) Next rCell Next Sh End Sub
[/vba] С файлом, который ближе к реальности, было бы проще Вам помочь.
2. работал на нескольких листах, например «итоги» и «итоги_2»?
[vba]
Код
For Each Sh In Array("итоги", "итоги_2", ... , "итоги_n")
[/vba]
все вместе будет выглядеть так (диапазоны из Вашего файла в 1 посте): [vba]
Код
Private Sub Worksheet_Change(ByVal Target As Range) Dim rCell As Range, Sh As Variant For Each Sh In Array("итоги", "итоги_2") For Each rCell In Sheets(Sh).Range("A6:A19, A24:A37") If Not IsEmpty(rCell) Then rCell.EntireRow.Hidden = IIf(rCell.Value = 0, True, False) Next rCell Next Sh End Sub
[/vba] С файлом, который ближе к реальности, было бы проще Вам помочь.Mikael
С файлом, который ближе к реальности, было бы проще Вам помочь.
это верно!
Посмотрите, может это Вам чем то поможет
[vba]
Код
Public vid As Boolean 'значение true или false (дополнительно передаем переменную на кнопку) Sub скрытие_отображение() Dim irows As Range Dim inabor As Range
name_ch = "итоги" 'здесь мы будем присваивать имя листа On Error Resume Next 'защита от ошибки, если условие не выполнится ни разу
Worksheets(name_ch).Unprotect Password:="123456"
For i = 5 To 100 'пребор строк с 5 по 100 If Worksheets(name_ch).Cells(i, 1) > 5 Then 'любое условие для скрытия/отображения из 1 столбца Set irows = Worksheets(name_ch).Rows(i & ":" & i) 'запоминаем строку, если сработало условие If inabor Is Nothing Then 'условие для задания первой строки и последующего добавления новых строк Set inabor = irows 'задаем первую строку в пустой набор Else Set inabor = Union(inabor, irows) 'добавляем строки по условию к существующему набору End If End If Next i
inabor.EntireRow.Hidden = vid 'скрываем/отображаем наш набор строк
Worksheets(name_ch).Protect Password:="123456" End Sub
[/vba]
и для кнопки на листе
[vba]
Код
Private Sub CommandButton1_Click() Worksheets("итоги").Unprotect Password:="123456" If vid = False Then vid = True Else vid = False End If скрытие_отображение End Sub
С файлом, который ближе к реальности, было бы проще Вам помочь.
это верно!
Посмотрите, может это Вам чем то поможет
[vba]
Код
Public vid As Boolean 'значение true или false (дополнительно передаем переменную на кнопку) Sub скрытие_отображение() Dim irows As Range Dim inabor As Range
name_ch = "итоги" 'здесь мы будем присваивать имя листа On Error Resume Next 'защита от ошибки, если условие не выполнится ни разу
Worksheets(name_ch).Unprotect Password:="123456"
For i = 5 To 100 'пребор строк с 5 по 100 If Worksheets(name_ch).Cells(i, 1) > 5 Then 'любое условие для скрытия/отображения из 1 столбца Set irows = Worksheets(name_ch).Rows(i & ":" & i) 'запоминаем строку, если сработало условие If inabor Is Nothing Then 'условие для задания первой строки и последующего добавления новых строк Set inabor = irows 'задаем первую строку в пустой набор Else Set inabor = Union(inabor, irows) 'добавляем строки по условию к существующему набору End If End If Next i
inabor.EntireRow.Hidden = vid 'скрываем/отображаем наш набор строк
Worksheets(name_ch).Protect Password:="123456" End Sub
[/vba]
и для кнопки на листе
[vba]
Код
Private Sub CommandButton1_Click() Worksheets("итоги").Unprotect Password:="123456" If vid = False Then vid = True Else vid = False End If скрытие_отображение End Sub
уважаемый Mikael, попробовал! Увы, с учетом того, что диапазон на листах разный макрос работать отказывается, а вот если оставить только один лист - макрос работает замечательно. И еще вопрос - как быть, если лист защищен паролем? Вам fan-vba тоже огромное спасибо! Буду пробовать.
уважаемый Mikael, попробовал! Увы, с учетом того, что диапазон на листах разный макрос работать отказывается, а вот если оставить только один лист - макрос работает замечательно. И еще вопрос - как быть, если лист защищен паролем? Вам fan-vba тоже огромное спасибо! Буду пробовать.graffserg
Увы, с учетом того, что диапазон на листах разный макрос работать отказывается, а вот если оставить только один лист - макрос работает замечательно.
Поэтому я и задал этот вопрос. Тут есть пара вариантов решения. Если Вы знаете диапазоны для каждого листа, можно перебрать их через select case перед вложенным циклом, примерно так: [vba]
Код
Select Case Sh Case "итоги" strRange = "A6:A19" Case "итоги_2" strRange = "A24:A37" End Select
[/vba]
Case можно сделать для каждого листа в Array. [vba]
Код
Private Sub Worksheet_Change(ByVal Target As Range) Dim rCell As Range, Sh As Variant, strRange As String For Each Sh In Array("итоги", "итоги_2") Select Case Sh Case "итоги" strRange = "A6:A19" Case "итоги_2" strRange = "A24:A37" End Select For Each rCell In Sheets(Sh).Range(strRange) If Not IsEmpty(rCell) Then rCell.EntireRow.Hidden = IIf(rCell.Value = 0, True, False) Next rCell Next Sh End Sub
[/vba]
Но лично я бы предпочел добавить исключение Вашего условия и вернутся к неопределенному диапазону из 2 поста. Нужно знать условие по которому скрываются эти ячейки. Скрываются строки с ячейками больше 5?
Увы, с учетом того, что диапазон на листах разный макрос работать отказывается, а вот если оставить только один лист - макрос работает замечательно.
Поэтому я и задал этот вопрос. Тут есть пара вариантов решения. Если Вы знаете диапазоны для каждого листа, можно перебрать их через select case перед вложенным циклом, примерно так: [vba]
Код
Select Case Sh Case "итоги" strRange = "A6:A19" Case "итоги_2" strRange = "A24:A37" End Select
[/vba]
Case можно сделать для каждого листа в Array. [vba]
Код
Private Sub Worksheet_Change(ByVal Target As Range) Dim rCell As Range, Sh As Variant, strRange As String For Each Sh In Array("итоги", "итоги_2") Select Case Sh Case "итоги" strRange = "A6:A19" Case "итоги_2" strRange = "A24:A37" End Select For Each rCell In Sheets(Sh).Range(strRange) If Not IsEmpty(rCell) Then rCell.EntireRow.Hidden = IIf(rCell.Value = 0, True, False) Next rCell Next Sh End Sub
[/vba]
Но лично я бы предпочел добавить исключение Вашего условия и вернутся к неопределенному диапазону из 2 поста. Нужно знать условие по которому скрываются эти ячейки. Скрываются строки с ячейками больше 5?
Отлично, работает по первой части из поста. Диапазон скрытия до 200 строк. Только как быть, если лист под паролем? Пробовал, но не получается. Помогите пожалуйста.
Отлично, работает по первой части из поста. Диапазон скрытия до 200 строк. Только как быть, если лист под паролем? Пробовал, но не получается. Помогите пожалуйста.graffserg
И еще вопрос - как быть, если лист защищен паролем?
Защита листа это уже отдельный вопрос. Совсем недавно была тема Можно добавить параметр UserInterfaceOnly:=True, тогда лист будет защищен, но макросы сработают. И не надо будет в каждой процедуре прописывать "снять защиту" "поставить защиту". [vba]
[/vba] Однако этот параметр слетает при закрытии книги, поэтому код нужно вставить в модуль книги в обработчик события Workbook_Open. [vba]
Код
Private Sub Workbook_Open() Dim Sh As Variant For Each Sh In Array("итоги", "итоги_2") Worksheets(Sh).Protect Password:="123456", UserInterfaceOnly:=True Next Sh End Sub
И еще вопрос - как быть, если лист защищен паролем?
Защита листа это уже отдельный вопрос. Совсем недавно была тема Можно добавить параметр UserInterfaceOnly:=True, тогда лист будет защищен, но макросы сработают. И не надо будет в каждой процедуре прописывать "снять защиту" "поставить защиту". [vba]
[/vba] Однако этот параметр слетает при закрытии книги, поэтому код нужно вставить в модуль книги в обработчик события Workbook_Open. [vba]
Код
Private Sub Workbook_Open() Dim Sh As Variant For Each Sh In Array("итоги", "итоги_2") Worksheets(Sh).Protect Password:="123456", UserInterfaceOnly:=True Next Sh End Sub
graffserg, странно у меня все работает. Вероятно ошибку вызывает неправильное название одного из листов в Array, возможно ругается на то, что защита уже установлена. Файла нет, точно сказать не могу. Попробуйте вот что: 1. перед защитой листа снять ее [vba]
Код
Worksheets(Sh).Unprotect Password:="123456"
[/vba] 2. если не поможет, запустите этот код: [vba]
Код
Sub TestShNames() On Error Resume Next Dim Sh As Variant For Each Sh In Array("итоги", "итоги_2") Worksheets(Sh).Unprotect Password:="123456" Worksheets(Sh).Protect Password:="123456", UserInterfaceOnly:=True If Err Then MsgBox Sh, vbCritical: Err.Clear Next Sh On Error GoTo 0 End Sub
[/vba] Он должен выдать сообщение, если неправильное имя листа
graffserg, странно у меня все работает. Вероятно ошибку вызывает неправильное название одного из листов в Array, возможно ругается на то, что защита уже установлена. Файла нет, точно сказать не могу. Попробуйте вот что: 1. перед защитой листа снять ее [vba]
Код
Worksheets(Sh).Unprotect Password:="123456"
[/vba] 2. если не поможет, запустите этот код: [vba]
Код
Sub TestShNames() On Error Resume Next Dim Sh As Variant For Each Sh In Array("итоги", "итоги_2") Worksheets(Sh).Unprotect Password:="123456" Worksheets(Sh).Protect Password:="123456", UserInterfaceOnly:=True If Err Then MsgBox Sh, vbCritical: Err.Clear Next Sh On Error GoTo 0 End Sub
[/vba] Он должен выдать сообщение, если неправильное имя листаMikael