Вопрос: Worksheet_Change | Добавлено: 01.01.10 19:29 |
Автор вопроса: ![]() |
Здравствуйте, Уважаемые!
Всех от души с Новым годом! У меня такой вопрос (проблема) возник по ходу разработки макроса под Excel. Дело в следующем... На одном из листов моей рабочей книги имеется ячейка, в которую транслируется значение из ячейки с другого листа. Когда значение в этой ячейке изменяется, программа должна проанализировать изменение и выполнить определённые действия. Разумеется, я решил воспользоваться событием Worksheet_Change в Коде изменяемого листа. Но не тут-то было! Оказалось, что если этот лист не активен, то макрос никак не реагирует на это событие. Реакцию вызывает только НЕПОСРЕДСТВЕННОЕ изменение значения ячейки в АКТИВНОМ листе! Подскажите, пожалуйста, можно как-нибудь обойти эту проблему? Мне бы хотелось вообще не заглядывать на тот лист, и чтобы там всё происходило автоматически, без моего участия... Если я путано объяснил суть своей проблемы, то попробую сейчас показать её на простом примере. Если вы мне подскажете, как надо организовать работу программы в этом примере, то дальше я уже самостоятельно соображу... Итак, имеются два листа: Лист1 и Лист2. На Лист2 в ячейку А1 вписана формула "=Лист1!A1". Таким образом, когда мы изменяем значение в ячейке А1 первого листа, автоматически изменяется и значение в ячейке А1 второго листа. Теперь в Коде второго листа вписываем вот такую процедуру: Private Sub Worksheet_Change(ByVal Target As Range) MsgBox (Target) End Sub После этого при НЕПОСРЕДСТВЕННОМ изменении любой ячейки на Лист2, выскакивает сообщение с тем значением, которое мы вводим. Но когда мы изменяем ячейку А1 на первом листе, то сообщение не выскакивает (реакции на событие нет!), хотя значение в ячейке А1 второго листа тоже изменилось... Как заставить программу реагировать на изменение ячеек на НЕАКТИВНОМ в данный момент листе? |
Ответы | Всего ответов: 17 |
Номер ответа: 1 Автор ответа: ![]() ![]() ![]() ![]() Вопросов: 5 Ответов: 276 |
Web-сайт: Профиль | Цитата | #1 | Добавлено: 02.01.10 14:00 |
____ Ну, а если использовать в книге самой событие Workbook_SheetChange? |
Номер ответа: 2 Автор ответа: ![]() ![]() ![]() ![]() ![]() ICQ: adamis@list.ru Вопросов: 153 Ответов: 3632 |
Профиль | Цитата | #2 | Добавлено: 02.01.10 16:23 |
Или написать сторожа, правда цикл не есть гуд |
Номер ответа: 3 Автор ответа: ![]() ![]() ![]() Вопросов: 3 Ответов: 22 |
Профиль | Цитата | #3 | Добавлено: 02.01.10 16:51 |
А сделать все необходимое в коде первого листа нельзя разве? Только переменной Target не удастся воспользоваться в этом случае - в ней будет диапазон с первого листа.
|
Номер ответа: 4 Автор ответа: ![]() ![]() ![]() ![]() Вопросов: 9 Ответов: 30 |
Профиль | Цитата | #4 | Добавлено: 02.01.10 17:53 |
Большое спасибо, что откликнулись на мою просьбу помочь! Я даже не ожидал, что будет так много откликов, особенно если учесть, что сейчас у всех сейчас "отходняк" после Новогодней ночи ![]() Smith пишет:
Или написать сторожа, правда цикл не есть гуд Я совсем не опытный программист на VBA, поэтому что такое "сторож" не знаю. Но, на самом деле, хотел бы узнать! ![]() ![]() hip пишет:
А сделать все необходимое в коде первого листа нельзя разве? Только переменной Target не удастся воспользоваться в этом случае - в ней будет диапазон с первого листа. 'в коде листа, на котором происходят непосредственные изменения (Лист1): Private Sub Worksheet_Change(ByVal Target As Range) MsgBox (Sheets("Лист2" ![]() End Sub Да в том-то и проблема, что я постоянно перемещаюсь по всем листам и на всех листах происходят ПОСТОЯННЫЕ быстрые изменения (получение информации из внешних источников, подсчёт, построение диаграмм). А ту ячейку, изменения в которой для меня особенно важны, я специально "вынес" на отдельный лист, чтобы там могла изменяться только она одна! (Чтобы не отфильтровывать "лишних" изменений!) Очень уж я рассчитывал на событие Worksheet_Change, наивно думал, что прога должна реагировать на изменения, даже когда лист не активен... ADSemenov.ru пишет:
Ну, а если использовать в книге самой событие Workbook_SheetChange? На данный момент, для меня этот совет звучит самым заманчивым из всех... Сейчас буду экспериментировать... Потом отпишусь! Хотя сразу вижу большой минус этой затеи в том, что много ресурсов компа будет уходить на реакцию (с последующей отфильтровкой) на ВСЕ изменения, которых в моей книге огромное количество. Боюсь, что тогда комп будет сильно тормозить. Ведь я же для того и собирался транслировать интересующее меня значение в ЕДИНСТВЕННУЮ изменяемую ячейку на ОТДЕЛЬНОМ листе, чтобы избежать затрат ресурсов на лишнюю фильтрацию. Макросы ведь и без того не слишком быстро работают, сами знаете... |
Номер ответа: 5 Автор ответа: ![]() ![]() ![]() ![]() Вопросов: 5 Ответов: 276 |
Web-сайт: Профиль | Цитата | #5 | Добавлено: 02.01.10 18:21 |
____ Так лист сразу отбить на входе в обработку и про ресурсы можно забыть. ![]() |
Номер ответа: 6 Автор ответа: ![]() ![]() ![]() ![]() Вопросов: 9 Ответов: 30 |
Профиль | Цитата | #6 | Добавлено: 02.01.10 18:45 |
ADSemenov.ru пишет:
Так лист сразу отбить на входе в обработку и про ресурсы можно забыть. ![]() На этом месте хотелось бы поподробнее ![]() В смысле, что такое "лист сразу отбить на входе в обработку", и как это сделать практически?
|
Номер ответа: 7 Автор ответа: ![]() ![]() ![]() ![]() Вопросов: 5 Ответов: 276 |
Web-сайт: Профиль | Цитата | #7 | Добавлено: 02.01.10 21:13 |
____ Проверить Sh на предмет идентичности листу с Вашей ячейкой и только после этого что-то делать.
____ Если машина не тройка [ ![]() ____ А в чём сомнение? |
Номер ответа: 8 Автор ответа: ![]() ![]() ![]() ![]() Вопросов: 9 Ответов: 30 |
Профиль | Цитата | #8 | Добавлено: 02.01.10 22:04 |
ADSemenov.ru пишет:
Проверить Sh на предмет идентичности листу с Вашей ячейкой и только после этого что-то делать. Попробовал вот так вот сделать:
Почему-то у меня не получается... Бибикает, только когда изменяю что-нибудь только НЕПОСРЕДСТВЕННО на втором листе, когда он активен. А если изменять значение ячейки А1 первого листа (и при этом изменяется ячейка А1 второго листа тоже), то не бибикает... Нужны дополнительные фильтры, наверно... Ниже я описал, как я потом ещё попробовал, но тоже неудачно ![]() ADSemenov.ru пишет:
__ Если машина не тройка [ ![]() ____ А в чём сомнение? Машина хоть и не тройка, конечно ![]() ![]() А изменений, на самом деле, очень много: программа непрерывно получает данные из внешнего источника, обрабатывает их, строит графики, а масштаб хочется покрупнее, чтобы зрение беречь. А крупная графика, разумеется, съедает много ресурсов, а тут ещё и макрос будет... Вот и не уверен я: потянет ли "мой старичок"?! ![]() Хоть на том листе у меня других изменяемых ячеек не предполагается размещать, но всё равно, согласуясь с хорошим стилем программирования, хотелось бы фильтр поставить на возможные случайные изменения в других ячейках интересующего меня листа. Попробовал вот так вот:
Почему-то не работает. Отказывается бибикать, когда изменяю значение в ячейке А1 первого листа, хотя при этом значение в ячейке А1 второго листа тоже изменяется... Что я делаю не так, не подскажете? |
Номер ответа: 9 Автор ответа: ![]() ![]() ![]() ![]() Вопросов: 5 Ответов: 276 |
Web-сайт: Профиль | Цитата | #9 | Добавлено: 02.01.10 22:49 |
____ Да. И тут событие не обрабатывается только на открытом листе.
____ Можно схитрить и это вполне работает:
____ Первая ячейка на Лист2 меняется по значению с Лист1. При активном Лист1 прекрасно "ловит" событие изменения в первой ячейке на Лист2. |
Номер ответа: 10 Автор ответа: ![]() ![]() ![]() ![]() Вопросов: 9 Ответов: 30 |
Профиль | Цитата | #10 | Добавлено: 02.01.10 23:35 |
ADSemenov.ru пишет:
_ Первая ячейка на Лист2 меняется по значению с Лист1. При активном Лист1 прекрасно "ловит" событие изменения в первой ячейке на Лист2. Огромное спасибо!!! Классно!!! |
Номер ответа: 11 Автор ответа: ![]() ![]() ![]() ![]() Вопросов: 9 Ответов: 30 |
Профиль | Цитата | #11 | Добавлено: 04.01.10 23:32 |
Снова задумался по ходу разработки... Всё-таки как-то неуклюже получается... Меня интересует изменение только ОДНОЙ-ЕДИНСТВЕННОЙ ячейки на отдельном листе, где кроме этой ячейки вообще ничего потенциально изменяемого нет. А с таким кодом, программа будет так или иначе реагировать АБСОЛЮТНО НА ВСЕ изменения НА ВСЕХ листах! Это даже обидно как-то. Ну неужели нет другого выхода?! Хотя бы Sh заставить как-нибудь работать... |
Номер ответа: 12 Автор ответа: ![]() ![]() ![]() ![]() Вопросов: 9 Ответов: 30 |
Профиль | Цитата | #12 | Добавлено: 06.01.10 13:42 |
На самом первом этапе разработки программы я предполагал использовать Таймер, по которому макрос будет заглядывать в интересующую меня ячейку каждую секунду, фиксировать изменения (если будут) и реагировать на них соответствующим образом. Но потом я подумал: "Это ж каждую секунду программа будет заглядывать в эту ячейку, ресурсов много будет расходоваться впустую. А кроме того, возможны (хотя это очень маловероятно) резкие изменения значения этой ячейки ВНУТРИ 1-секундного промежутка, которые программа "прозевает"...
А потом меня озарило: "Можно же транслировать значение из этой ячейки на отдельный, "персонально" для неё выделенный лист, а там "ловить" событие Worksheet_Change"... Но оказалось, что не всё так просто ![]()
Кстати, я уже на трёх(!) форумах поднял этот вопрос, и только на одном (на вашем!) хоть как-то пытаются помочь. На самом деле, большое вам спасибо! |
Номер ответа: 13 Автор ответа: ![]() ![]() ![]() ![]() Вопросов: 9 Ответов: 30 |
Профиль | Цитата | #13 | Добавлено: 07.01.10 22:45 |
Кому интересно, я ответ нашёл на свой вопрос!!! На одном форуме мне подсказали...
В данном случае событие Worksheet_Change для второго листа и не генерируется... На втором листе используйте событие Код: Private Sub Worksheet_Calculate() ' Срабатывает пересчёт формул на листе End Sub |
Номер ответа: 14 Автор ответа: ![]() ![]() ![]() Вопросов: 3 Ответов: 22 |
Профиль | Цитата | #14 | Добавлено: 07.01.10 23:10 |
М-да, ларчик то просто открывался. Вот всегда так получается. |
Номер ответа: 15 Автор ответа: ![]() ![]() ![]() ![]() Вопросов: 9 Ответов: 30 |
Профиль | Цитата | #15 | Добавлено: 07.01.10 23:23 |
Я над этим "ларчиком" полгода пыхтел! Ну правда с перерывами ![]() А на том форуме создал такую же тему около часа тому назад, - просто всё из этой темы тупо скопировал туда. А там модератор - 30-летний парнишка с Урала - ответил сразу же через несколько минут после того, как я тему создал! В результате, у той (аналогичной!) темы всего два просмотра было и один ответ! Но какой ответ!!! |
|