Excel vba отследить изменение ячейки

Как вы могли отслеживать ячейки листа, если данные были изменены в Excel? Это может помочь вам как можно быстрее идентифицировать измененные ячейки. В этой статье я расскажу о некоторых интересных методах решения этой задачи в Excel.

Отслеживайте изменения ячеек в Excel с помощью функции отслеживания изменений

Отслеживайте изменения ячеек в Excel с помощью кода VBA


стрелка синий правый пузырь Отслеживайте изменения ячеек в Excel с помощью функции отслеживания изменений

В Excel есть полезный Отслеживать изменения функция, она может помочь вам отметить измененные ячейки, пожалуйста, сделайте следующее:

1. Нажмите Обзор > Отслеживать изменения > Выделить изменения, см. снимок экрана:

изменения в мониторе документов 1

2. В Выделить изменения диалоговом окне выполните следующие операции:

(1.) Проверить Отслеживайте изменения во время редактирования. Это также разделяет вашу книгу.

(2.) Под Выделите, какие изменения В разделе укажите нужные вам элементы Когда, Кто и Где.

(3.) Наконец, проверьте Выделите изменения на экране опцию.

изменения в мониторе документов 2

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

изменения в мониторе документов 3

Внимание: С помощью этого метода ваша книга станет общей.


стрелка синий правый пузырь Отслеживайте изменения ячеек в Excel с помощью кода VBA

Следующий код VBA также может помочь вам отслеживать значения ячеек при их изменении, пожалуйста, сделайте следующее:

1. Щелкните правой кнопкой мыши вкладку листа, на которой вы хотите отслеживать изменения ячеек, и выберите Просмотреть код из контекстного меню в открывшемся Microsoft Visual Basic для приложений окна, скопируйте и вставьте следующий код VBA в модуль:

Код VBA: отслеживание изменений ячеек на листе Excel:

Private Sub Worksheet_Change(ByVal Target As Range)
'Updateby Extendoffice 20160728
    Dim xrng As Range
    Set xrng = Range("A1:E7")
    If Not Application.Intersect(xrng, Range(Target.Address)) _
           Is Nothing Then
        MsgBox "Cell " & Target.Address & " has changed.", vbInformation, "Kutools for Excel"
    End If
End Sub

изменения в мониторе документов 4

Примечание: В приведенном выше коде A1: E7 — это диапазон данных, который вы хотите отслеживать при изменении ячейки, вы можете изменить его по своему усмотрению.

2. Затем сохраните и закройте это окно кода, и теперь, когда вы измените значение ячейки в указанном диапазоне, появится окно сообщения, напоминающее вам, см. Снимок экрана:

изменения в мониторе документов 5


Лучшие инструменты для работы в офисе

Kutools for Excel Решит большинство ваших проблем и повысит вашу производительность на 80%

  • Снова использовать: Быстро вставить сложные формулы, диаграммы и все, что вы использовали раньше; Зашифровать ячейки с паролем; Создать список рассылки и отправлять электронные письма …
  • Бар Супер Формулы (легко редактировать несколько строк текста и формул); Макет для чтения (легко читать и редактировать большое количество ячеек); Вставить в отфильтрованный диапазон
  • Объединить ячейки / строки / столбцы без потери данных; Разделить содержимое ячеек; Объединить повторяющиеся строки / столбцы… Предотвращение дублирования ячеек; Сравнить диапазоны
  • Выберите Дубликат или Уникальный Ряды; Выбрать пустые строки (все ячейки пустые); Супер находка и нечеткая находка во многих рабочих тетрадях; Случайный выбор …
  • Точная копия Несколько ячеек без изменения ссылки на формулу; Автоматическое создание ссылок на несколько листов; Вставить пули, Флажки и многое другое …
  • Извлечь текст, Добавить текст, Удалить по позиции, Удалить пробел; Создание и печать промежуточных итогов по страницам; Преобразование содержимого ячеек в комментарии
  • Суперфильтр (сохранять и применять схемы фильтров к другим листам); Расширенная сортировка по месяцам / неделям / дням, периодичности и др .; Специальный фильтр жирным, курсивом …
  • Комбинируйте книги и рабочие листы; Объединить таблицы на основе ключевых столбцов; Разделить данные на несколько листов; Пакетное преобразование xls, xlsx и PDF
  • Более 300 мощных функций. Поддерживает Office/Excel 2007-2021 и 365. Поддерживает все языки. Простое развертывание на вашем предприятии или в организации. Полнофункциональная 30-дневная бесплатная пробная версия. 60-дневная гарантия возврата денег.

вкладка kte 201905


Вкладка Office: интерфейс с вкладками в Office и упрощение работы

  • Включение редактирования и чтения с вкладками в Word, Excel, PowerPoint, Издатель, доступ, Visio и проект.
  • Открывайте и создавайте несколько документов на новых вкладках одного окна, а не в новых окнах.
  • Повышает вашу продуктивность на 50% и сокращает количество щелчков мышью на сотни каждый день!

офисный дно

Комментарии (7)


Оценок пока нет. Оцените первым!

Запуск макроса (процедуры) из кода VBA Excel при изменении значения ячейки вручную или программным способом, а также при нажатии клавиши Delete.

Запуск макроса при изменении ячейки

Пример кода

Код VBA Excel для запуска макроса (процедуры) при изменении значения ячейки на рабочем листе:

Private Sub Worksheet_Change(ByVal Target As Range)

    If Not Application.Intersect(Range(«A1:D8»), Range(Target.Address)) Is Nothing Then

        MsgBox «Значение ячейки « & Target.Address & » изменено.»

    End If

End Sub

Range("A1:D8") — это диапазон, при изменении значения любой ячейки которого, произойдет выполнение функции MsgBox. Диапазон может состоять из одной ячейки.

Код размещается в модуле рабочего листа, при изменении значения ячейки на котором следует запустить макрос (процедуру).

Вместо функции MsgBox в приведенном коде следует разместить ссылку на исполняемую процедуру (макрос) VBA Excel.

Примечания

  • Макрос будет запущен при изменении значения ячейки вручную или программным способом, а также при нажатии клавиши Delete.
  • Вызываемая процедура будет запущена и в том случае, если в ячейку будет записано то же самое значение, которое в ней и было. Например, в ячейке было число 28, и в нее записали вручную или программно число 28; или нажали клавишу Delete на пустой ячейке.
  • Макрос не будет запущен при изменении значения ячейки с формулой в результате ее пересчета.

Исключение ложного срабатывания

Если в качестве диапазона указать только одну ячейку, можно исключить срабатывание кода VBA Excel при записи в ячейку того же значения. Для этого необходимо использовать переменную уровня модуля, чтобы с ее помощью контролировать факт изменения или неизменения значения в указанной ячейке.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

Option Explicit

Dim x

Private Sub Worksheet_Activate()

x = Range(«C4»)

End Sub

Private Sub Worksheet_Change(ByVal Target As Range)

    If Not Application.Intersect(Range(«A1:D8»), Range(Target.Address)) Is Nothing _

    And x <> Range(«C4») Then

        MyMsgBox

        x = Range(«C4»)

    End If

End Sub

Private Sub MyMsgBox()

    MsgBox «Значение ячейки « & «C4» & » изменено на « & Chr(34) & Range(«C4») & Chr(34)

End Sub

В это примере функция MsgBox вынесена в отдельную процедуру, которая вызывается при изменении значения в ячейке C4.

Значение ячейки C4 присваивается переменной x при активации рабочего листа и, затем, перезаписывается при каждой перезаписи значения в ячейке.

Код этого примера размещен в модуле рабочего листа, но код вызываемой процедуры может быть вынесен из него в другой модуль.


 

Diana Tailor

Пользователь

Сообщений: 982
Регистрация: 28.12.2012

#1

07.12.2018 08:15:37

Здравствуйте.

Имеется необходимость отследить строки, в которых изменились ячейки.
Собственно, простейший макрос:

Код
Private Sub Worksheet_Change(ByVal Target As Range)
MsgBox Target.Address
End Sub

Если мы по одной ячейке изменяем, все корректно. Если работаем с диапазоном – не очень.

Пример: пустой лист.

Код
Range(“A1”)=1
Range(“A3”)=1

Как видно, в ячейке A2 значений нет. Если выделить диапазон A1:A3 нажать Delete, то Excel считает, что изменения произошли во всем диапазоне, хотя по факту только в 1 и 3 строке.

Как отследить значения именно измененных строк? (т.е. если не было значений и удалились – это уже не изменение, а если были и удалились/поменялись – уже изменение).

Спасибо.

Изменено: Diana Tailor07.12.2018 12:16:39

 

DenSyo

Пользователь

Сообщений: 82
Регистрация: 15.05.2018

#2

07.12.2018 09:24:22

гугол подсказывает…

Код
Dim vOldVal 'Must be at top of module

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    vOldVal = Target
End Sub

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

Изменено: DenSyo07.12.2018 09:32:50

 
DenSyo

, спасибо. Пытаюсь разобраться

 

Jack Famous

Пользователь

Сообщений: 10846
Регистрация: 07.11.2014

OS: Win 8.1 Корп. x64 | Excel 2016 x64: | Browser: Chrome

#4

07.12.2018 10:25:25

Diana Tailor, доброго утра  :)

Цитата
Diana Tailor: отследить строки, в которых изменились ячейки

а для чего? Если для отката, то есть хороший способ: задублировать лист, на котором макрос выполняет изменения и, при отмене, просто удалить его, а при подтверждении удалить исходник

Изменено: Jack Famous07.12.2018 10:25:39

Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄

 
Jack Famous

, здрасьте :)
Ситуация такая: имеем в загруженном интерфейсе лист Excel. Путем скрытия/открытия блокировки/разблокировки столбцов заносим туда разные данные.
От этих данных зависят другие данные, т.е. мы занесли какие-то значения, поменяли, и нужно пересчитать зависящие от измененных ячеек данные.
Так вот, чтобы из 1006 строк не пересчитывать все подряд, потребовалось пересчитать только те строки, в которых были произведены изменения.

Как-то так :)

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

 

Jack Famous

Пользователь

Сообщений: 10846
Регистрация: 07.11.2014

OS: Win 8.1 Корп. x64 | Excel 2016 x64: | Browser: Chrome

#6

07.12.2018 10:57:48

Цитата
Diana Tailor: пересчитать только те строки, в которых были произведены изменения

почитайте про Application.Calculate, Application.CalculateFull и Application.CalculateFullRebuild (обычно мне хватает первого). Если он пересчитывает очень долго, то стоит пересмотреть структуру организации данных и связей между ними.

Цитата
Diana Tailor: сравнить массивы

…можно очень быстро. Создавайте отдельную тему с примером и поможем  ;) Опять же, если Application.Calculate справится, то и сравнивать ничего не придётся.

Изменено: Jack Famous07.12.2018 10:58:57

Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄

 

Calculate — это круто, конечно, но снова-таки, учитывая размерность моих данных — Range(«A7:SW1006») тут любой calculate  загнется, поэтому расчеты происходят не автоматически, а в VBA по нажатию кнопки )

По поводу массивов — посмотрю, вроде у Димы Щербакова на сайте видела или у Игоря неплохие решения, вот ищу :)

 

JayBhagavan

Пользователь

Сообщений: 11833
Регистрация: 17.01.2014

ПОЛ: МУЖСКОЙ | Win10x64, MSO2019x64

#8

07.12.2018 11:08:06

Jack Famous, Calculate можно применять к конкретному диапазону. Пример из справки:

Код
Worksheets("Sheet1").UsedRange.Columns("A:C").Calculate

<#0>
Формула массива (ФМ) вводится Ctrl+Shift+Enter
Memento mori

 

DenSyo

Пользователь

Сообщений: 82
Регистрация: 15.05.2018

склоняюсь к варианту с undo/redo, если уж продолжать в этом направлении. заполнять массив на каждый клик слишком уж бессмысленно…

 
DenSyo

, спасибо за комментарий.
Теперь буду искать материалы в этом направлении :)

 

Jack Famous

Пользователь

Сообщений: 10846
Регистрация: 07.11.2014

OS: Win 8.1 Корп. x64 | Excel 2016 x64: | Browser: Chrome

#11

07.12.2018 11:23:51

Цитата
Diana Tailor: расчеты происходят не автоматически, а в VBA по нажатию кнопки

это, конечно правильно, но

Цитата
размерность моих данных — Range(«A7:SW1006»)

— это перебор  :D

Цитата
вот ищу

вангую, создав тему, результат будет лучше))

Цитата
JayBhagavan: Calculate можно применять к конкретному диапазону

да — я в курсе, спасибо  ;)

Изменено: Jack Famous07.12.2018 11:24:08

Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄

 

БМВ

Модератор

Сообщений: 21376
Регистрация: 28.12.2016

Excel 2013, 2016

#12

07.12.2018 11:28:05

Цитата
Diana Tailor написал:
Range(«A7:SW1006»)

конечно все зависит от того что делается, но объем данных не такой и большой.
#2 не прокатит в случае выделения нескольких диапазонов.

По вопросам из тем форума, личку не читаю.

 

Если не получится отточить быстродейственный макрос, попрошу модератора перенести тему в форум основной :)

 

bedvit

Пользователь

Сообщений: 2477
Регистрация: 02.04.2015

Виталий

Diana Tailor, напишите, что вам нужно в конечном итоге, возможно вам посоветуют другой подход к решению вашего вопроса. Хорошо бы приложить и файл пример, что есть/что нужно получить.

«Бритва Оккама» или «Принцип Калашникова»?

 

Собственно, пример во вложении :)

 

Суть такова: в диапазоне (только он намного больше) изменяем ячейки, в этих же строках от измененных ячеек будут произведены дальнейшие вычисления. Вот и приходится искать строки, в которых были изменены ячейки, и в них уже принудительно в vba производить расчет

 

Neufazendnik

Гость

#18

07.12.2018 12:34:59

У меня в Логпрог данная задача остро стоит и решена следующим образом:
Листы, на которых идет контроль измененных строк содержат обработчик:

Код
Private Sub Worksheet_Change(ByVal Target As Range)
Call hi(Target)
End Sub

Таких листов у меня несколько. Номер активного контролируется глобальной переменной ge18.
Существует процедура hi, которая заполняет глобальную переменною — массив ge102(ge18,ххх),содержающю номера для ххх строк листа ge18, в которых произошли изменения.
число ххх помещенных в массив элементов вписывается в ge102(ge18,0)
Код наверняка можно оптимизировать. Мне некогда. Меня устраивает, что он рабочий и с удалением строк справляется корректно.

Код
Sub hi(Target As Range)
'проставляет номера строк, в которых были сделаны изменения данных в массив ge102
'эта подпрограмма отрабатывается до selectionCange, поэтому vc1 содержит именно строку, которая модифицировалась, а не строку, в которой уже находится фокус ввода.
Static hi01 As Long 'номер ВЕРХНЕЙ строки, в которой произошло изменение.
Static hi02 As Long 'Число строк, которые изменялись одновременно.
Static hi03 As Long 'уже вписанное в ge102 до этого число строк.
Static hi04 As Long 'текущий номер индекса в ge102
Static hi05 As Long 'номер элемента в  ge102
'hi06 -loop
Static hi07 As Long 'число вписанных элементов в ge102
Dim hi08 As Long 'число элементов hi102 обработано
Dim hi09 As Long 'номер строки, вписываемый в ge102
Dim hi10 'элемент target
Dim hi11 As String 'address hi10

If Target.Columns.Count = Columns.Count Then Exit Sub
If TypeName(Selection) = "Range" And Selection.Columns.Count = Columns.Count Then Exit Sub
'If Selection.EntireColumn.Count  ge158 Then 'http://www.planetaexcel.ru/forum/index.php?PAGE_NAME=message&FID=1&TID=100712&TITLE_SEO=100712-otslezhivanie-komandy-udaleniya-strok-iz-worksheetchange&MID=832563#message832563 Target.Address  Target.EntireRow.Address Then ' обходим случай  MsgBox "Удаляются строки, игнорируем обработку"
  hi07 = 0
  hi03 = ge102(ge18, 0)
  For Each hi10 In Target
    hi11 = hi10.Address
    hi09 = Range(hi11).Row
    If hi09 > ge126 - 1 Then 'на строки заголовка и вышележащие не реагируем.
      hi04 = hi03 + hi07
      For hi05 = 1 To hi03 + hi07
        If ge102(ge18, hi05) = hi09 Then GoTo hi06
        Next
      hi04 = hi03 + hi07 + 1
      If hi04 > ge129 Then
        If ge102(ge18, 0)  ge129 Then MsgBox ("Изменена информация одновременно более, чем в " & ge129 & " строках. Сохранение будет произведено только для первых " & ge129 & " изменений. Остальная модифицированная информация не сохранится.")
        ge102(ge18, 0) = ge129
  Exit Sub
        End If
      hi07 = hi07 + 1
      ge102(ge18, hi04) = hi09
      End If
hi06:
    Next
  ge102(ge18, 0) = hi03 + hi07
  'End If
End Sub

Изменено: Neufazendnik07.12.2018 12:37:35

 

bedvit

Пользователь

Сообщений: 2477
Регистрация: 02.04.2015

Виталий

#19

07.12.2018 13:49:13

Цитата
Diana Tailor написал:
Вот и приходится искать строки, в которых были изменены ячейки,

Diana Tailor, Excel сам помечает какие ячейки надо пересчитать.
Для ИНФО см.

Пересчет в Excel

Цитата
Вычисление листов в Excel можно рассматривать как процесс из трех этапов:
1.Создание дерева зависимостей
2.Создание цепочки вычислений
3.Пересчет ячеек

Если вы используете VBA, возможно проставить программно ячейки для пересчета, для этого вам пригодится связка Range.Dirty —  Range.Calculate :

Цитата
Начиная с Microsoft Excel 2002, объект Range в Microsoft Visual Basic для приложений (VBA) поддерживает метод Range.Dirty, который отмечает ячейки как требующие подсчета. Когда он используется совместно с методом Range.Calculate, он включает принудительный пересчет ячеек в заданном диапазоне. Это удобно при выполнении ограниченного вычисления в макросе, где установлен ручной режим подсчета (для избежания избытка вычисляемых ячеек, не относящихся к функции макроса). Методы подсчета диапазонов недоступны через API C ( … к моему сожалению.)

Если вы считаете все в VBA, а данные храните на листах Excel, думаю здесь в любом случае нужно идти через Worksheet_Change.
Далее, уже сверять изменились ли данные — было/стало и делать пересчет по изменениям. Пока не совсем ясно. как изменяется ваш большой массив, пользователь вставляет данные сразу массивом? Как с ним работает пользователь? зачем пользователю тысячи строк и множество столбцов для изменения? Если вставляется массив, обрабатывайте сразу массивом изменения.

«Бритва Оккама» или «Принцип Калашникова»?

 

Diana Tailor

Пользователь

Сообщений: 982
Регистрация: 28.12.2012

#20

07.12.2018 14:25:50

Как много сегодня нового узнала :)

bedvit

,

Neufazendnik

спасибо, что помогаете!

Цитата
Пока не совсем ясно. как изменяется ваш большой массив, пользователь вставляет данные сразу массивом? Как с ним работает пользователь?

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

Например, ввели/изменили значение в D7, возникла необходимость посмотреть, как изменились значения в C7, F7, G7. Нажали кнопочку, все посчиталось. Поэтому необходим весь гигантский диапазон «под рукой».

Или, пакетно ввели информацию в ячейки D7:E17, нажали рассчитать, посмотрели, что получилось везде.

После сохранения, происходит выгрузка информации со всего листа в базу данных (это уже отдельная история, пока у меня просто копируется лист в новый файл, сохраняется в отдельную книгу, так как до БД мне далековато на VBA).

Перерасчет ячеек идет построчно, т.е. если значения менялись только в одной строке, то перерасчет будет только в этой же строке…

Прикрепленные файлы

  • 2 Пример 18-12-07.xlsx (9.86 КБ)

Изменено: Diana Tailor07.12.2018 14:28:36
(не то прикрепила :) )

 

БМВ

Модератор

Сообщений: 21376
Регистрация: 28.12.2016

Excel 2013, 2016

#21

07.12.2018 15:16:30

Повторю

Цитата
БМВ написал:
Diana Tailor  написал:Range(«A7:SW1006»)конечно все зависит от того что делается, но объем данных не такой и большой.

Что там считается?

По вопросам из тем форума, личку не читаю.

 
БМВ

, простите, как-то упустила Ваше сообщение :)

В ячейки, например, вводим разновидность льда, его температуру, массы пустого оборудования, массу оборудования, заполненного льдом, цвет льда и т.д.
В других (заблокированных) ячейках уже вычисляются его характеристики: плотность, коэффициенты оттаивания и др.
В зависимости от этих рассчитанных характеристик вычисляются другие — углы преломления, спектральные характеристики и т.д.

Очень много параметров рассчитывается в одной строке :)

Т.е. идет список точек опробования льда в столбце 1, а в других столбцах — параметры, соответствующие точке опробования.

 

На данный момент штудирую Range.Dirty, но, что-то мне подсказывает, придется обойтись свободным столбцом, в нем помечать, что в данной строке были изменения через Target, и, следовательно, пересчитать только эти строки. Более простого решения пока не нашла.

 

БМВ

Модератор

Сообщений: 21376
Регистрация: 28.12.2016

Excel 2013, 2016

Diana Tailor, Я не верю что для расчета таблицы нужен VBA . Функции листа справятся и снимут головняк определения что считать а что нет.

Посмотрите на

это

и формул много и пересчитываются все и ничего.

По вопросам из тем форума, личку не читаю.

 
БМВ

, я видела эту штуку :) мощно :)
я правильно понимаю алгоритм, что нужно будет прописать формулы в расчетных ячейках, протянуть их на все 1000 строк моих, поставить ручную калькуляшку, и калькулировать уже конкретный диапазон строк?

 

БМВ

Модератор

Сообщений: 21376
Регистрация: 28.12.2016

Excel 2013, 2016

#26

07.12.2018 16:06:41

Цитата
Diana Tailor написал:
поставить ручную калькуляшку, и калькулировать уже конкретный диапазон строк?

Зачем? пусть автомат считает

По вопросам из тем форума, личку не читаю.

 

bedvit

Пользователь

Сообщений: 2477
Регистрация: 02.04.2015

Виталий

Diana Tailor, лучшим решением, если есть такая возможность, будет расчет в самом листе Excel. Во-первых — сам Excel позаботится о пересчете изменений. Во-вторых это будет происходить в многопоточном режиме, в отличии от VBA. Собственно,БМВ, пишет о том же.

«Бритва Оккама» или «Принцип Калашникова»?

 
БМВ

,

bedvit

, спасибо!
Прописываю формулы, посмотрим, что получится :)

 

Выражаю слова благодарности всем, кто принял участие в обсуждении данной темы.
Также спасибо модераторам за терпение!
Перешла на Calculate в автоматическом режиме, работает значительно быстрее, чем в VBA.

 

БМВ

Модератор

Сообщений: 21376
Регистрация: 28.12.2016

Excel 2013, 2016

#30

08.12.2018 14:24:36

Цитата
Diana Tailor написал:
работает значительно быстрее, чем в VBA.

А я говорил :-) .
Diana Tailor, часто макрушники забывают про то, что сперва был табличный процессор потом к нему появился макро язык , на котором писать было прям скажем не удобно. С появлением VBA стало намного легче, но не следует превращать Excel в набор таблиц с данными и оболочку для обработки из при помощи скриптов. Есть то что без VBA не сделать, и всему есть свое применение.
Успехов.

По вопросам из тем форума, личку не читаю.

Отслеживание изменений значения ячейки

shtirlic39

Дата: Среда, 25.10.2017, 15:52 |
Сообщение № 1

Группа: Пользователи

Ранг: Прохожий

Сообщений: 2


Репутация:

0

±

Замечаний:
0% ±


Excel 2007

Добрый день!
Хочу скрыть строки в зависимости от значения в ячейке. Нужный макрос нашел, он работает. НО. Приходится нажимать на кнопку, а хочется, чтобы макрос сам отлавливал изменения в ячейках и скрывал/показывал строку в зависимости от значения в ячейке.
Я попробовал сам написать, но не получилось(.
[vba]

Код

Private Sub Worksheet_Change(ByVal Target As Range)
   If Intersect(Target, Range(«I:I»)) Is Nothing Then Exit Sub

    Dim cell As Range
    Application.ScreenUpdating = False

    For Each cell In ActiveSheet.UsedRange.Columns(9).Cells
        If cell.Value = «Скрыть» Then cell.EntireRow.Hidden = True
    Next
    Application.ScreenUpdating = True
End Sub

[/vba]
Файл прикрепляю.

К сообщению приложен файл:

111.xlsm
(15.7 Kb)

Сообщение отредактировал shtirlic39Среда, 25.10.2017, 15:53

 

Ответить

_Boroda_

Дата: Среда, 25.10.2017, 15:56 |
Сообщение № 2

Группа: Модераторы

Ранг: Местный житель

Сообщений: 16618


Репутация:

6465

±

Замечаний:
0% ±


2003; 2007; 2010; 2013 RUS

Положите макрос не в модуль книги, а в модуль листа
(Правой мышой на ярлык листа — Исходный код — откроется окошко — вот туда макрос и нужно писать

Ну и сам макрос немного иначе нужно
[vba]

Код

Private Sub Worksheet_Change(ByVal Target As Range)
    If Intersect(Target, Columns(2)) Is Nothing Then Exit Sub
    Dim cell As Range
    Application.ScreenUpdating = False
    For Each cell In ActiveSheet.UsedRange.Columns(9).Cells
        cell.EntireRow.Hidden = cell.Value = «Скрыть»
    Next
    Application.ScreenUpdating = True
End Sub

[/vba]

К сообщению приложен файл:

111-1-1.xlsm
(16.8 Kb)


Скажи мне, кудесник, любимец ба’гов…
Платная помощь:
Boroda_Excel@mail.ru
Яндекс-деньги: 41001632713405 | Webmoney: R289877159277; Z102172301748; E177867141995

 

Ответить

shtirlic39

Дата: Среда, 25.10.2017, 16:05 |
Сообщение № 3

Группа: Пользователи

Ранг: Прохожий

Сообщений: 2


Репутация:

0

±

Замечаний:
0% ±


Excel 2007

Спасибо! Все работает!
Получается макрос отслеживает изменение только во втором столбце?
А можно такой макрос сделать для всей книги, а не для одного листа?

 

Ответить

_Boroda_

Дата: Среда, 25.10.2017, 16:12 |
Сообщение № 4

Группа: Модераторы

Ранг: Местный житель

Сообщений: 16618


Репутация:

6465

±

Замечаний:
0% ±


2003; 2007; 2010; 2013 RUS

макрос отслеживает изменение только во втором столбце?

Конечно. Ведь именно там Вы вручную меняете значения

А можно такой макрос сделать для всей книги

Конечно. Вот теперь нужно класть в модуль книги
[vba]

Код

Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)
    With Sh
        If Intersect(Target, .Columns(2)) Is Nothing Then Exit Sub
        Dim cell As Range
        Application.ScreenUpdating = False
        For Each cell In Sh.UsedRange.Columns(9).Cells
            cell.EntireRow.Hidden = cell.Value = «Скрыть»
        Next
        Application.ScreenUpdating = True
    End With
End Sub

[/vba]

К сообщению приложен файл:

111-1-2.xlsm
(20.0 Kb)


Скажи мне, кудесник, любимец ба’гов…
Платная помощь:
Boroda_Excel@mail.ru
Яндекс-деньги: 41001632713405 | Webmoney: R289877159277; Z102172301748; E177867141995

 

Ответить

Хитрости »

1 Май 2011              58485 просмотров


Как отследить событие(например выделение ячеек) в любой книге?

Иногда при разработке надстройки просто необходимо отследить какое-либо событие в книге. Но модуль ЭтаКнига и модули листов надстройки позволяют отследить лишь те события, которые происходят в той книге, в которой этот код прописан. А как же другие книги? Как, например, отследить событие открытия любой книги в Excel и сделать какое-то действие в зависимости от имени открытой книги? Или как отследить выделение ячейки в любой книге? Изменение значений ячеек?

Если не знаете что такое надстройка — Как создать свою надстройку?

На самом деле все до смешного просто:
В модуле ЭтаКнига главной книги(надстройка либо PERSONAL.XLS) необходимо создать переменную, которая будет ссылкой на все приложение Excel

Private WithEvents App As Application

На событие открытия главной книги (той, в которой пишется код и в которой объявили переменную App — опять же это надстройка либо PERSONAL.XLS) присваиваем этой переменной App значение запущенного приложения Excel:

Private Sub Workbook_Open()
    Set App = Application
End Sub

Т.е. мы теперь имеем как бы свою локальную управляемую ссылку на Excel. Это позволит нам получить доступ к событиям приложения Excel из VBA и отследить их. И среди прочих событий есть такие, которые относятся ко всем открытым книгам. Т.е. то же выделение ячеек мы сможем обработать только внутри своей надстройки, но срабатывать оно будет при выделении ячеек в любой открытой книге.
Теперь создаем непосредственно событие — аналогично выбору других событий в книге в левом окне выбора объектов выбираем App. В правом появятся все доступные события для нашего объекта App:

в этом окне перечислены все события, которые могут быть «перехвачены» в любой открытой книге, а не только той, в которой этот код записан. Сразу после выбора какого-либо события из списка автоматически будет создана пустая процедура, в которую надо будет лишь добавить необходимый код.
Рассмотрим некоторые из этих событий.

Вот так, например, будет выглядеть код отслеживания открытия любой книги:

Private Sub App_WorkbookOpen(ByVal Wb As Workbook)
    MsgBox "Вы открыли книгу:" & Wb.Name
End Sub

Теперь при открытии любой книги будет появляться сообщение с именем именно открытой книги.
Wb — это переменная событийной процедуры. Для каждой процедуры они могут отличаться или вовсе отсутствовать. Но если они есть — значит можно их использовать. Например, в этой процедуре(App_WorkbookOpen) Wb это открываемая книга, т.е. объект типа Workbook. И к ней можно обращаться как к любой книге: перебрать листы, изменить какие-то свойства и т.п. Например, в коде выше я просто вывожу в информационное окно с именем открываемой книги.

Сам по себе код не заработает. Т.к. назначение значения переменной App происходит только при открытии самой книги(надстройки или PERSONAL), то после создания кодов надо будет сохранить эту книгу и открыть заново

А с помощью этого кода можно отследить создание новой книги:

Private Sub App_NewWorkbook(ByVal Wb As Workbook)
    MsgBox "Вы создали новую книгу"
End Sub

Отслеживаем выделение ячеек во всех открытых книгах:

Private Sub App_SheetSelectionChange(ByVal Sh As Object, ByVal Target As Range)
    MsgBox "Вы выделили ячейку с адресом: " & Target.Address
End Sub

Target — это объект Range(ячейка или диапазон ячеек), которые были выделены в книге.
Sh — это объект Worksheet, ячейки которого были выделены.
Таким образом у нас есть две переменные, которые мы можем использовать. Например, можно производить определенные действия только на листах с конкретным именем:

Private Sub App_SheetSelectionChange(ByVal Sh As Object, ByVal Target As Range)
    If Sh.Name = "Отчет" Then
        MsgBox "Вы выделили ячейку с адресом: " & Target.Address
    End If
End Sub

А процедура ниже поможет отследить изменение значений ячеек во всех открытых книгах и отменить нежелательные изменения:

Private Sub App_SheetChange(ByVal Sh As Object, ByVal Target As Range)
    Dim bUndo As Boolean
    If Sh.Name <> "Для изменений" Then
        If Sh.Name = "Описание" Then 'для этого листа можно изменять только ячейки диапазона "A16:B20"
            If Intersect(Target, Sh.Range("A16:B20")) Is Nothing Then
                MsgBox "На этом листе изменять можно только ячейки в диапазоне 'A16:B20'!", vbCritical, "www.excel-vba.ru"
                bUndo = True
            End If
        Else 'для всех других листов, кроме листа "Для изменений" - изменять значения ячеек вообще нельзя
            MsgBox "Ячейки на этом листе нельзя изменять!", vbCritical, "www.excel-vba.ru"
            bUndo = True
        End If
        If bUndo Then
            With Application
                .EnableEvents = False
                .Undo
                .EnableEvents = True
            End With
        End If
    End If
End Sub

В приложенном к статье файле будет чуть более понятно что делает эта процедура.

Естественно, в таких процедурах можно назначить выполнение и других(нужных) действий. Например, вызов макроса (Call ИмяМакроса). Макрос в таком случае должен быть размещен в стандартном модуле и иметь статус Public(или вовсе без статуса). Сам модуль должен тоже находится в той же книге.

Скачать пример

  Tips_Macro_How_Catch_Events.xls (60,5 KiB, 4 649 скачиваний)

Также см.:
Что такое переменная и как правильно её объявить?


Статья помогла? Поделись ссылкой с друзьями!

  Плейлист   Видеоуроки


Поиск по меткам



Access
apple watch
Multex
Power Query и Power BI
VBA управление кодами
Бесплатные надстройки
Дата и время
Записки
ИП
Надстройки
Печать
Политика Конфиденциальности
Почта
Программы
Работа с приложениями
Разработка приложений
Росстат
Тренинги и вебинары
Финансовые
Форматирование
Функции Excel
акции MulTEx
ссылки
статистика

Понравилась статья? Поделить с друзьями:
  • Excel vba отправка почты outlook
  • Excel vba отображение формы
  • Excel vba относительный путь к файлу
  • Excel vba отмена действия
  • Excel vba открыть файл скрыто