Страницы: 1
RSS
VBA. Автоматический запуск макроса на опр. листе при изменении в книге Excel
 
Уважаемые форумчане, добрый день.  
 
...прочитал несколько веток форума, но все равно не смог решить проблему - поэтому прошу подсказать,если быть совсем честным, то даже не подсказать, а наверное написать за меня код :-), ибо пока даун в вопросах VBA.  
 
Есть книга Excel, назовем ее "Example"  
 
Внутри несколько листов:  
- entry data  
- calculate - different  
- calculate - annuity  
- output form  
 
На листе "calculate - different" таблица с расчетом аннуитетного платежа, который рассчитывается по нажатию на кнопку, на которую подвешен макрос:  
 
Sub Annuitet()  
'  
' Annuitet Макрос  
'  
Range("F124").GoalSeek Goal:=Range("E3"), ChangingCell:=Range("F127")  
 
End Sub  
 
И все бы ничего, но очень бы хотелось реализовать механизм, чтобы этот макрос, на этом листе запускался при любом изменении какой-бы то ни было ячейки на листе "entry data". Знаю что это реализуется методом Worksheet_Change, но вот как правильно написать всю обвязку и как все это корректно встроить, до меня не доходит.  
 
Помогите, пожалуйста.
 
Пардон муа... для особо одаренных:  
{post}Правый клик мыши на ярлычке листа-Исходный текст {/post}  
Это на ярлычке листа "entry data", или в самом VBA встать на значок "ЭтаКнига" (Microsoft Excel Objects) и "Insert - Module"?
 
...так, я понял - некорректно сформулировал свой вопрос:  
 
Нужно чтобы при изменении любой ячейки на листе "entry data" автоматом запускался макрос "Annuitet", который сейчас привязан к кнопке на листе "calculate - annuity", сам макрос "Annuitet" нужно оставить без изменений, он работает корректно.
 
Дмитрий Вам уже ответил, в первой части его поста.  
Щелкать надо на имени листа (не в ВБА)
 
Товарищи, во-первых спасибо огромное за помощь - буду пробовать.  
 
...а во-вторых, можете хоть запинать ногами  - чем больше стебетесь, тем лучше, быстрее учится буду и меньше задавать тупых вопросов... просто вам уже трудно понять, что человек может ТАК тупить, но для меня VBA - китайская грамота, так что и не такие вопросы возникают - это нормально когда учишься с нуля...
 
Нихт арбайтен:  
 
1. Сделал так, как вы говорили: нажал на лист "entry data" - выбрал "Исходный текст", вставил код:  
 
Private Sub Worksheet_Change(ByVal Target As Range)  
If Target <> "" then Call Annuitet  
End Sub  
 
2. Поменял сумму на листе "entry data" - вылетела ошибка VBA: Run-time error '1004', Неверная ссылка.  
 
Ругается на мой макрос - "Annuitet", прямо в нем подсвечивает желтым строчку:  
 
Range("F124").GoalSeek Goal:=Range("E3"), ChangingCell:=Range("F127")  
 
...перед тем, как окончательно зачмырите, помогите разобраться, пожалуйста.
 
Правильно ругается. В строке  
Range("F124").GoalSeek Goal:=Range("E3"), ChangingCell:=Range("F127")  
перед каждым Range укажите лист, на котором работать макросу.
Я сам - дурнее всякого примера! ...
 
...я понимаю, что всех достал - но нужно уточнить (синтаксис не знаю), должно быть так:  
calculate - annuity.Range("F124").GoalSeek Goal:=calculate - annuity.Range("E3"), ChangingCell:=calculate - annuity.Range("F127") ???
 
sheets("calculate - different").Range(....  
Если операции происходят на листе "calculate - different"
 
Про синтаксис:  
Лист_Точка_Диапазон. Например:  
Sheets("annuity").Range("E3")
 
sheets("calculate - different").Range("F124").GoalSeek Goal:=sheets("calculate - different").Range("E3"), ChangingCell:=sheets("calculate - different").Range("F127")
Я сам - дурнее всякого примера! ...
 
Все поправил, запустил, ругается:  
 
Compile error: Sub or function not define  
 
подсветил желтым:  
Private Sub Worksheet_Change(ByVal Target As Range)
 
давайте, лучше файл сюда :) согласно Правилам.
 
Был бы файл, дискуссия закончилась бы как минимум четыре часа назад:-)
Я сам - дурнее всякого примера! ...
 
Назвали дауном, так дайте побороться за свою честь :-) ...если сам не смогу - выложу, и буду надеяться, что поможите.  
 
...но сначала сам буду колупаться :-)
 
Никто Вас так не называл и никого Вы не достали. Как видите, все стараются помочь Вам.  
 
22447
Я сам - дурнее всякого примера! ...
 
Да я сам над стобой стебусь... мозг стимулирует, знаете ли... огромное всем спасибо, правда!!!  
 
...просто если я сам не попытаюсь разобраться и понять, то смысл в этом какой?
 
Минутку! Вас кто так обозвал? Читайте Ваше первое сообщение. Может опечатка? - "назвался дауном"? :-)  
По теме: а зачем Вам "при любом изменении какой-бы то ни было ячейки на листе"? Ведь ячеек о-о-очень много. Может ограничимся каким-то диапазоном?
 
Диапазон ячеек, в которых хоть что-то можно изменить: А1:I30 (лист: "entry data")
 
Посмотрите простенький пример. В модуле ЛИСТА макрос, отслеживающий изменение в "жёлтых" ячейках. Как только в указанных ячейках произойдёт изменение, то сразу будет вызван на исполнение "Ваш" макрос, который у меня называется "Макрос1". Он находится в общем модуле.
 
Юрий, спасибо огромное - работает.  
 
Граждане товарищи, всем также огромное мерси, что помогли советами, без Вас бы жмакать мне на кнопки до одурения...  
 
Юрий, еще минут 15 повозитесь со мной? В итоге получилось следующее:  
 
Private Sub Worksheet_Change(ByVal Target As Range)  
   If Target.Cells.Count > 1 Then Exit Sub  
   If Not Intersect(Target, Range("A1:I20")) Is Nothing Then  
       Call Annuitet_leasing  
       Call Annuitet_credit  
   End If  
End Sub  
 
т.е. там два листа и два макроса, которые нужно запустить:  
лист "calculate - annuity" и макрос "Annuitet_leasing"  
лист "comparison" и макрос "Annuitet_credit"  
 
Пара вопросов:  
1. Если "отвязать" эти макросы от кнопок и вставить код в сами листы, т.е. правая кнопка мыши на листе - Исходный текст... макрос на автозапуск будет работать?  
 
2. Ваш код:  
 If Target.Cells.Count > 1 Then Exit Sub  
 If Not Intersect(Target, Range("A1:I20")) Is Nothing Then  
 
..не до конца понимаю, что происходит... т.е. если в этих ячейка произошел какой-то расчет - то выйти из процедуры? sub - это же процедура?  
 
...вторую сточку вообще не понимаю - если не выделено - то ничего... я, пардон, мыслю структурами обычного языка, но очень хочется понять...  
 
Заранее спасибо.
 
По второму вопросу:    
первая строка - досрочный выход из процедуры при условии, если выделено более одной ячейки.  
вторая строка - если изменяемая ячейка находится внутри диапазона (принадлежит диапазону), то...  
Первый вопрос (про отвязку) не понял.
 
1. Т.е. это как встроенная защита? Если не делать проверку на то, сколько ячеек выделено, чем это грозит?  
 
2. Спасибо - понял, почитаю про синтаксис, буду разбираться в логике языка...  
 
3. Смотрите, сейчас если зайти в VBA, то:  
- в папке "Microsoft Excel Objects" перечислены названия листов моей книги Excel, и в "Лист1 (entry data)" вставлен код:  
 
Private Sub Worksheet_Change(ByVal Target As Range)  
   If Target.Cells.Count > 1 Then Exit Sub  
   If Not Intersect(Target, Range("A1:I20")) Is Nothing Then  
       Call Annuitet_leasing  
       Call Annuitet_credit  
   End If  
End Sub  
 
- ниже в VBA есть папка "Modules", в которой указаны, собственно, два модуля: Module1 и Module2 (соответственно к первому привязан макрос "Annuitet_leasing", ко второму "Annuitet_credit"). По моему предположению, код вынесен в модули, т.к. я создавал "кнопки", по нажатию на которые соответствующие макросы и запускались... а если эти "кнопки" удалить и вставить код макросов в соответствующие листы книги, т.е. код макроса "Annuitet_leasing" в лист "calculate - annuity", а код макроса "Annuitet_credit" в лист "comparison".Теперь же необходимость что-либо нажимать на листах отпала, будет ваш макрос работать?
 
1. Если без этой строки, то, например, выделив несколько ячеек, и нажать Delete _ получим ошибку.  
3. Оба макроса могут находится и в одном модуле - это не очень важно. Код (макросы) из модулей удалять не нужно. И переносить их в Листы тоже не нужно. Просто удалите/скройте кнопку, и при изменении значений в указанном диапазоне будут поочерёдно вызваны два Ваших макроса из общих модулей, как, если бы Вы нажали на кнопку.
 
Юрий, спасибо огромное за помощь и разъяснения.
 
Снова обращаюсь к спецам!  
имеется макрос (Макрос1)  
Какой код нужно написать,чтобы данный макрос запускался при заполнении любой ячейки в первом столбце на листе1  
Заранее спасибо!
 
Вопрос снят,поглубже капнула форум! Спасибо!
 
Ну вот, а я старался...  
Нет уж, теперь читайте :)  
 
Private Sub Worksheet_Change(ByVal Target As Range)  
   If Target.Cells.Count > 1 Then Exit Sub ' только по одной!!!  
   If Not Intersect(Target, Range("A:A")) Is Nothing Then  
       Application.EnableEvents = False    'чтоб не зациклились  
       macro1  
       Application.EnableEvents = True  
   End If  
End Sub  
 
Sub macro1()  
   MsgBox 1  
End Sub
 
Все равно к вам за помощью пришла)))  
Спасибо за работу!  
Мой макрос такой  
 
Sub Копирование_формул()  
Dim iLastRow As Long  
iLastRow = Cells(Rows.Count, 1).End(xlUp).Row  
For i = 3 To iLastRow  
If Not IsEmpty(Cells(i, 1)) Then  
Cells(i - 1, 4).Copy Cells(i, 4)  
Cells(i - 1, 5).Copy Cells(i, 5)  
End If  
Next  
End Sub  
 
а запускается этим (пока что) )))  
Private Sub Worksheet_Change(ByVal Target As Range)  
If Target.Cells.Count > 1 Then Exit Sub  
If Not Intersect(Target, Range("C:C")) Is Nothing Then  
Call Копирование_формул  
End If  
End Sub  
 
Теперь вопрос. У меня таблица,где будет работать макрос уже заполнена и кое где ячейки помечены пользователем. Можно ли исключить уже заполненные ячейки,чтобы из макрос их не трогал, а работал лишь в той строке, где ячейка в которой заполняется  
Т.е. при заполнении ячейки С3, макрос срабатывал только на строку 3 т.д.  
Это вообще реально?
 
Т.е. нужно скопировать данные только в одной строке?  
Тогда зачем вызывать Sub Копирование_формул()?  
Вместо его вызова напишите  
Cells(target.row, 4).Copy Cells(target.row+1, 4)  
ну или куда там что нужно копировать, без примера непонятно...
Страницы: 1
Читают тему
Наверх