Хитрости »
Основные понятия (22)
Сводные таблицы и анализ данных (7)
Графики и диаграммы (4)
Работа с VB проектом (10)
Power BI и Power Query (8)
Условное форматирование (5)
Списки и диапазоны (5)
Макросы(VBA процедуры) (60)
Разное (36)

Как отменить действия макроса

Многие из тех, кто программирует в VBA знают, что после действий макроса пропадает возможность отмены действий. И если с отменой тех действий, которые были совершены до выполнения макроса совершенно точно можно распрощаться(невозможно будет это сделать), то отменить действия макроса возможно. И рано или поздно каждый программирующий в VBA задается вопросом: как можно отменить действия, совершенные макросом? Для начала надо понять, в каких ситуациях это нам надо. Например был выполнен код, который испортил или удалил данные в файле, но эти данные еще нужны. Самой простое, что можно сделать это закрыть файл без сохранения и открыть заново. Все данные будут на месте(если, конечно, в коде не было строки, сохраняющей файл). Второй способ: это перед выполнением макроса делать резервную копию файла - тогда Ваши исходные данные всегда будут целы.


Но как же сделать отмену действий макроса через стандартную кнопку на панели или сочетанием клавиш Ctrl+Z и можно ли? Ответ - можно. Но сразу вопрос: а насколько это нужно? В каких ситуациях это может пригодиться? Я вот так вот навскидку сразу не сказал бы, если бы не являлся разработчиком программ и надстроек в среде Microsoft Excel. Именно в надстройках отмена действий наиболее востребована, на мой взгляд. Например надстройка объединяет ячейки. Объединили случайно и...В стандартной ситуации после такого макроса нельзя отменить действия. Закрывать файл без сохранения? Как-то некрасиво получается, если продукт является коммерческим. И тогда приходится извращаться и пытаться сделать возможным отмену действий макроса. В моей надстройке MulTEx в некоторых командах отмена действий команд как раз и применяется. Наиболее распространенное решение по отмене действий макроса заключается в запоминании свойств изменяемых ячеек:

Комментарии к коду я старался сделать максимально подробными, поэтому думаю, что больше нечего разъяснять. К тому же по древней традиции я приложил к статье пример с данным кодом :) Единственное, что могу добавить: пользовательский тип SaveRange может быть дополнен еще какими-либо переменными, помимо vFormula, sAddr и lColor. Например цвет границ ячейки, цвет шрифта и т.д. Все зависит от того, какие изменения Вы будете делать кодом и что захотите затем вернуть.

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

  Tips_Restore_Macro.xls (48,5 KiB, 1 444 скачиваний)


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

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

  Tips_Restore_Macro_HiddenSh.xls (45,0 KiB, 1 127 скачиваний)


Конечно, в этом приеме тоже есть недостаток - если на этот лист ссылаются формулы из других листов есть большой шанс получить в этих формулах ошибку #ССЫЛКА!(#REF!), т.к. исходный лист удаляется.
В этом случае можно из резервного листа просто вставлять все ячейки из резервного листа. Да и вообще можно много чего придумать - вплоть до сохранения и последующего извлечения резервных копий файлов. Все как всегда зависит от задач и ситуации.


Статья помогла? Не держи в себе, поделись ссылкой с друзьями!

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

Access Multex Outlook Power BI Power Query и Power BI VBA работа в редакторе VBA управление кодами Бесплатные надстройки Дата и время Диаграммы и графики Записки Защита Защита данных Интернет Картинки и объекты Листы и книги Макросы и VBA Настройка Печать Поиск данных Поиск решения Почта Программы Работа с приложениями Работа с файлами Разработка приложений Сводные таблицы Списки Тренинги и вебинары Финансовые Форматирование Формулы и функции Функции Excel Функции VBA Ячейки и диапазоны акции MulTEx анализ данных вебинар ссылки статьи тренинг
Обсуждение: 10 комментариев
  1. n1k1t0ss:

    Супер, спасибо большое за приведенный пример.
    Первый метод хорош - достаточно вынести из метода Fill_Numbers() пример с изменением данных, и он превращается в почти полноценный метод для сохранения действий для выделенного диапазона, который можно будет вызывать в начале своего метода. К сожалению, строчку

    Рейтинг: 0
  2. n1k1t0ss:

    Application.OnUndo
    придется вызывать в конце каждого своего метода: написать универсальный метод не получилось - возможность использования делегатов для vba excel я не нашел (может, плохо искал).
    А вообще, способ отличный - если хранить ссылку (или массив состояний) на предыдущие действия, то можно будет отменить не только последний макрос, но еще и предпоследний и так далее )

    Рейтинг: 0
  3. Сергей:

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

    Нужно создавать скрытый лист для надстройки и на нём хранить диапозон, имя листа, имя книги и имя процедуры, делавшая изменения.
    И когда нужно будет, отменять эти действия от конца, а в случае закрытия файла надстройки - очищать лист истории.

    Рейтинг: 0
  4. Сергей, не совсем понял Вашу мысль. Зачем создавать лист для хранения данных, если в первом методе для этого и так используется массив? К тому же на лист придется заносить так же и все значения диапазона, формулы, параметры ячеек, что весьма емко. А запись и извлечение значений с листа значительно замедлит действия кода, что на более-менее больших объемах будет более чем заметно. Но тут, в принципе, дело фантазии - я не претендовал на оригинальность и универсальность решения. Моей задачей было показать принцип и если Вы нашли решение лучше - это только плюс Вам.

    Рейтинг: 0
  5. Сергей:

    Я сейчас пересмотрел код и столкнулся с такой проблемой. Почему не добавляется пункты по отмене действий макроса?

    Рейтинг: 0
  6. Сергей:

    Вот код:
    И вопрос нужно чтоб нижняя строка массива обрезалась при отмене действия, а второй вопрос в прошлом сообщении =)

    Рейтинг: 0
  7. По порядку:
    1. Выложенный код подразумевает отмену ТОЛЬКО последнего макроса и лишь один пункт соответственно будет отображаться.
    2. Как-то непонятно строка какого массива должна обрезаться.И какое отношение этот вопрос имеет к данной статье?

    Рейтинг: 0
  8. Геннадий:

    Ваш "макрос отмены" возвращает состояние листа, "запомненное" перед первым выполнением "макроса действия." При этом плодятся новые листы.
    Делаю 2 "макроса действия", потом свое действие, потом опять "макрос действия". Далее жму отмену - исчезают и 3 действия "макроса действия", и мое действие.

    Рейтинг: 0
  9. Геннадий, а вопрос-то в чем? Выложенные коды работают так, как заявлено. Вашей проблемы не понимаю: какие листы плодятся, какие Ваши действия и действия макроса...

    Рейтинг: 0
  10. Игорь:

    Вот только не понятно почему в Excel нельзя отменить действия макроса? Разработчики этого не предусмотрели?
    Программировал в OpenOffice Calc (на StarBasic) и не смотря на то что это бесплатный продукт и довольно таки более скромный там есть возможность отмены любого действия макроса (где-то на 30 шагов).
    Это очень удобно на этапе разработки - чтобы что-то подправить, оптимизировать, протестировать. Что ж мелкомягкие до сих пор этого не сделали?

    Рейтинг: 0
Поделитесь своим мнением

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


Для оформления сообщений Вы можете использовать следующие тэги:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">

Тренинги

Заказать
Наши партнеры
Перейти
Перейти
Счетчики
Анализ сайта

Яндекс.Метрика
© 2017 Excel для всех  Войти
Авторизация
*
*
Регистрация
*
*
*
Пароль не введен
*
captcha
Перейти на страницу