Хитрости »
24 Февраль 2012 61043 просмотров
Как отменить действия макроса
Многие из тех, кто программирует в VBA знают, что после действий макроса пропадает возможность отмены действий. И если с отменой тех действий, которые были совершены до выполнения макроса совершенно точно можно распрощаться(невозможно будет это сделать), то отменить действия макроса возможно. И рано или поздно каждый программирующий в VBA задается вопросом: как можно отменить действия, совершенные макросом? Для начала надо понять, в каких ситуациях это нам надо. Например был выполнен код, который испортил или удалил данные в файле, но эти данные еще нужны. Самое простое, что можно сделать это закрыть файл без сохранения и открыть заново. Все данные будут на месте(если, конечно, в коде не было строки, сохраняющей файл). Второй способ: это перед выполнением макроса делать резервную копию файла — тогда Ваши исходные данные всегда будут целы.
Но как же сделать отмену действий макроса через стандартную кнопку на панели или сочетанием клавиш
Ctrl
+
Z
и можно ли? Ответ — можно. Но сразу вопрос: а насколько это нужно? В каких ситуациях это может пригодиться? Я навскидку сразу не сказал бы, если бы не являлся разработчиком программ и надстроек в среде Microsoft Excel. Именно в надстройках отмена действий наиболее востребована, на мой взгляд. Например надстройка объединяет ячейки. Объединили случайно и…В стандартной ситуации после такого макроса нельзя отменить действия. Закрывать файл без сохранения? Как-то некрасиво получается, если продукт является коммерческим. И тогда приходится извращаться и пытаться сделать возможным отмену действий макроса. В моей надстройке MulTEx в некоторых командах отмена действий команд как раз и применяется. Наиболее распространенное решение по отмене действий макроса заключается в запоминании свойств изменяемых ячеек:
'Создаем свой пользовательский тип данных Type SaveRange vFormula As Variant sAddr As String lColor As Long lColorIndex As Long End Type 'Переменные для запоминания данных Public wbWBook As Excel.Workbook Public wsSh As Excel.Worksheet Public vOldVals() As SaveRange '--------------------------------------------------------------------------------------- ' Procedure : Fill_Numbers ' Purpose : Основная процедура. Это тот код, который вносит изменения на лист ' и действия которого нам необходимо отменить ' Процедура заполняет выделенные ячейки номерами ' и изменяет цвет заливки '--------------------------------------------------------------------------------------- Sub Fill_Numbers() Dim rCell As Range, li As Long ' Сначала запоминаем значения выделенных ячеек на листе ReDim vOldVals(1 To Selection.Count) 'Запоминаем активную книгу 'это на случай, если отмена действий будет производиться из другой книги Set wbWBook = ActiveWorkbook 'Запоминаем активный лист 'на случай, если отмена действий будет производиться из другого листа Set wsSh = ActiveSheet 'Запоминаем значения(заносим в массив) li = 1 For Each rCell In Selection 'запоминаем адрес ячейки vOldVals(li).sAddr = rCell.Address 'запоминаем формулу(если нет формулы - значение) vOldVals(li).vFormula = rCell.Formula 'запоминаем цвет заливки ячейки vOldVals(li).lColor = rCell.Interior.Color 'запоминаем индекс цвета заливки(чтобы на заливать бесцветные ячейки) vOldVals(li).lColorIndex = rCell.Interior.ColorIndex li = li + 1 Next rCell '====================================== 'Выполняем основные действия(собственно тот код, который надо будет отменить) li = 1 For Each rCell In Selection rCell = li rCell.Interior.ColorIndex = li li = li + 1 Next rCell '====================================== 'Назначаем стандартному вызову отмены действий выполнение нашего макроса возвращения значений Application.OnUndo "Отменить заполнение ячеек номерами", "Restore_Vals" End Sub '--------------------------------------------------------------------------------------- ' Procedure : Restore_Vals ' Purpose : Процедура отмены действия(возврат значений) '--------------------------------------------------------------------------------------- Sub Restore_Vals() Dim li As Long 'В случае непредвиденной ошибки переходим на метку 'и показываем сообщение об ошибке On Error GoTo Erreble 'Активируем книгу, в которой были сделаны изменения wbWBook.Activate 'Активируем лист, в котором были сделаны изменения wsSh.Activate 'Возвращаем значения For li = 1 To UBound(vOldVals) Range(vOldVals(li).sAddr).Formula = vOldVals(li).vFormula 'если заливка была безцветная, то ColorIndex = xlNone 'значит выставляем безцветность If Not vOldVals(li).lColorIndex = xlNone Then Range(vOldVals(li).sAddr).Interior.Color = vOldVals(li).lColor Else 'если цвет был - возвращаем его Range(vOldVals(li).sAddr).Interior.ColorIndex = xlNone End If Next li Exit Sub 'Показываем сообщение о невозможности отмены действия Erreble: MsgBox "Нельзя отменить действие!", vbCritical, "Error" End Sub
Комментарии к коду я старался сделать максимально подробными, поэтому думаю, что больше нечего разъяснять. К тому же по древней традиции я приложил к статье пример с данным кодом Единственное, что могу добавить: пользовательский тип SaveRange может быть дополнен еще какими-либо переменными, помимо vFormula, sAddr и lColor. Например цвет границ ячейки, цвет шрифта и т.д. Все зависит от того, какие изменения Вы будете делать кодом и что захотите затем вернуть.
Скачать пример
Отменить действия макроса.xls (62,0 KiB, 3 360 скачиваний)
Код, приведенный выше, несомненно хорош, но если кол-во изменяемых ячеек достаточно велико, то код будет очень замедлять работу. Поэтому если есть возможность добавлять/удалять листы в книгах, то можно схитрить: сделать резервную копию листа, лист сделать очень скрытым и как только потребуется отмена действия — вернуть этот лист, удалив исходный(с уже испорченными данными):
'Переменные для запоминания данных Public wbWBook As Workbook Public wsSh As Worksheet, wsActSh As Worksheet, sSh_Name As String, lShPoz As Long '--------------------------------------------------------------------------------------- ' Procedure : Fill_Numbers ' Purpose : Основная процедура. Это тот код, который вносит изменения на лист ' и действия которого нам необходимо отменить ' Процедура заполняет выделенные ячейки номерами ' и изменяет цвет заливки '--------------------------------------------------------------------------------------- Sub Fill_Numbers() Dim rCell As Range, li As Long 'Запоминаем активную книгу 'это на случай, если отмена действий будет производиться из другой книги Set wbWBook = ActiveWorkbook 'Запоминаем активный лист 'на случай, если отмена действий будет производиться из другого листа Set wsActSh = ActiveSheet lShPoz = wsActSh.Index sSh_Name = wsActSh.Name Application.ScreenUpdating = 0 wsActSh.Copy , wbWBook.Sheets(wbWBook.Sheets.Count) Set wsSh = wbWBook.Sheets(wbWBook.Sheets.Count) wsSh.Visible = xlVeryHidden wsActSh.Activate Application.ScreenUpdating = 1 '====================================== 'Выполняем основные действия(собственно тот код, который надо будет отменить) li = 1 For Each rCell In Selection rCell = li rCell.Interior.ColorIndex = li li = li + 1 Next rCell '====================================== 'Назначаем стандартному вызову отмены действий выполнение нашего макроса возвращения значений Application.OnUndo "Отменить заполнение ячеек номерами", "Restore_Vals" End Sub '--------------------------------------------------------------------------------------- ' Procedure : Restore_Vals ' Purpose : Процедура отмены действия(возврат значений) '--------------------------------------------------------------------------------------- Sub Restore_Vals() 'В случае непредвиденной ошибки переходим на метку 'и показываем сообщение об ошибке On Error GoTo Erreble Application.ScreenUpdating = 0 'Активируем книгу, в которой были сделаны изменения wbWBook.Activate 'делаем видимым резервный лист wsSh.Visible = -1 'Удаляем исходный лист, данные в котором уже изменены Application.DisplayAlerts = 0 wsActSh.Delete Application.DisplayAlerts = 1 'назначаем резервному листу имя исходного wsSh.Name = sSh_Name wsSh.Move wbWBook.Sheets(lShPoz) 'Активируем резервный лист wsSh.Activate Application.ScreenUpdating = 0 Exit Sub 'Показываем сообщение о невозможности отмены действия Erreble: MsgBox "Нельзя отменить действие!", vbCritical, "www.excel-vba.ru" End Sub
Скачать пример
Tips_Restore_Macro_HiddenSh.xls (45,0 KiB, 2 366 скачиваний)
Конечно, в этом приеме тоже есть недостаток — если на этот лист ссылаются формулы из других листов есть большой шанс получить в этих формулах ошибку
#ССЫЛКА!(#REF!)
, т.к. исходный лист удаляется.
В этом случае можно из резервного листа копировать все ячейки и вставлять на рабочий лист. Да и вообще можно много чего придумать — вплоть до сохранения и последующего извлечения резервных копий файлов. Все как всегда зависит от задач и ситуации.
И самая большая ложка дегтя к обоим кодам: VBA не позволяет таким образом делать МНОГОКРАТНЫЕ отмены действий(многократное Ctrl+Z), что делает бесполезными попытки запомнить пошагово несколько разных изменений макросами. Отменить можно будет все равно только последнее запомненное действие.
Статья помогла? Поделись ссылкой с друзьями!
Видеоуроки
Поиск по меткам
Access
apple watch
Multex
Power Query и Power BI
VBA управление кодами
Бесплатные надстройки
Дата и время
Записки
ИП
Надстройки
Печать
Политика Конфиденциальности
Почта
Программы
Работа с приложениями
Разработка приложений
Росстат
Тренинги и вебинары
Финансовые
Форматирование
Функции Excel
акции MulTEx
ссылки
статистика
RoMuLX
Пользователь
Сообщений: 8
Регистрация: 16.06.2017
The_Prist, хорошо, расскажу полную ситуацию) внимание: много букв))
У меня есть инженерный расчетный файл. Он считает таблицы без макросов.
А макрос как раз на отслеживание входа из этой темы:
http://www.planetaexcel.ru/techniques/5/196/
Но тут проблема, что окошко при выходе не вылезает, да и всегда идет сохранение файла (значит можно что-то по ошибке испортить и выйти).
И что бы правильно работало добавил форму при выходе:
http://www.planetaexcel.ru/forum/index.php?PAGE_NAME=message&FID=1&TID=71378&…
В итоге у меня форма fmQueryClose на «сохранить» «не сохранять» «отмена».
1. Если жмем «сохранить» — то в реестр добавляется пользователь+дата, потом скрывает все листы, потом идет сейв, потом выход.
2. Если жмем «не сохранять» — то откатывает все изменения, потом скрывает все листы, потом идет сейв, потом выход.
3. Если жмем «отмена» — то просто закрывается форма и ничего больше.
Во всех этих вариантах стандартного диалога при выходе не будет.
и такой код у меня склепался из вышеперечисленных источников:
Код |
---|
Private Sub Workbook_Open() For Each sh In ActiveWorkbook.Worksheets 'отображаем все листы sh.Visible = True Next sh Worksheets("Предупреждение").Visible = xlSheetVeryHidden 'скрываем лист ПРЕДУПРЕЖДЕНИЕ Worksheets("Реестр изменений").Rows("2:2").Insert Shift:=xlDown 'вставляем между строками 1 и 2 новую строку Worksheets("Реестр изменений").Rows("1001:1001").Delete Shift:=xlUp 'удаляем строку 1001 (реестр на 1000 строк) Worksheets("Реестр изменений").Cells(2, 1) = Environ("USERNAME") 'запись в первую ячейку второй строки Worksheets("Реестр изменений").Cells(2, 2) = Now 'запись во вторую ячейку второй строки ActiveWorkbook.Save End Sub Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean) Worksheets("Реестр изменений").Rows("2:2").Insert Shift:=xlDown 'вставляем между строками 1 и 2 новую строку Worksheets("Реестр изменений").Rows("1001:1001").Delete Shift:=xlUp 'удаляем строку 1001 (реестр на 1000 строк) Worksheets("Реестр изменений").Cells(2, 1) = Environ("USERNAME") 'запись в первую ячейку второй строки Worksheets("Реестр изменений").Cells(2, 3) = Now 'запись в третью ячейку второй строки End Sub Private Sub Workbook_BeforeClose(Cancel As Boolean) If Not Me.Saved Then fmQueryClose.Show Select Case fmQueryClose.DialogResult Case VbMsgBoxResult.vbYes: Me.Save Worksheets("Предупреждение").Visible = True 'скрываем все листы, кроме листа ПРЕДУПРЕЖДЕНИЕ For Each sh In ActiveWorkbook.Worksheets If sh.Name = "Предупреждение" Then sh.Visible = True Else sh.Visible = xlSheetVeryHidden End If Next sh ActiveWorkbook.Save Case VbMsgBoxResult.vbNo: Me.Saved = True >>>> Тут как раз и нужен код на откат всех изменений <<<< Worksheets("Предупреждение").Visible = True 'скрываем все листы, кроме листа ПРЕДУПРЕЖДЕНИЕ For Each sh In ActiveWorkbook.Worksheets If sh.Name = "Предупреждение" Then sh.Visible = True Else sh.Visible = xlSheetVeryHidden End If Next sh ActiveWorkbook.Save Case VbMsgBoxResult.vbCancel: Cancel = True End Select Unload fmQueryClose End If End Sub |
При выходе без сохранения я подумал именно про откаты(Undo), т.к. вручную-то я могу после открытия откатить все, что исправил в ячейках, зажатием Ctrl+Z.
Получаем только открытый открытый файл, но после отката нужно скрыть все страницы.
Цитата |
---|
До какого момента, кстати? |
Откат до открытия файла
Цитата |
---|
Как понять, когда закончить откатывать? |
Закончить откат, когда уже нечего отменять (кнопка Undo будет неактивна)
Цитата |
---|
Ведь количество откатов может быть разным на разных ПК. |
Да, кто-то может 1 ячейку косякнуть и выйти, а кто-то и 40.
в файле в принципе не более 100 ячеек для ввода данных (остальное ВПРом подцепляется в зависимости от того что ввели в исходных + математические формулы )
Цитата |
---|
Да и событие-то какое: перед сохранением. |
Да, уже подумал что лучше перед выходом + форма (то о чем я писал выше. Надеюсь из кода понятно что я хочу)
Цитата |
---|
Через Undo это сделать нереально. |
Спасибо, я не знал. Надеюсь, сейчас подскажите, как сделать то, что мне нужно)
Ну если что, буду использовать методы для отмены действий макросов (по идее должно помочь)
Изменено: RoMuLX — 17.06.2017 13:18:13
title | keywords | f1_keywords | ms.prod | api_name | ms.assetid | ms.date | ms.localizationpriority |
---|---|---|---|---|---|---|---|
Application.Undo method (Excel) |
vbaxl10.chm133221 |
vbaxl10.chm133221 |
excel |
Excel.Application.Undo |
b56bb8a0-2cd1-356a-03ba-47eb6f56f455 |
04/05/2019 |
medium |
Application.Undo method (Excel)
Cancels the last user-interface action.
Syntax
expression.Undo
expression A variable that represents an Application object.
Remarks
This method undoes only the last action taken by the user before running the macro, and it must be the first line in the macro. It cannot be used to undo Visual Basic commands.
Example
This example cancels the last user-interface action. The example must be the first line in a macro.
[!includeSupport and feedback]
Содержание
- Метод UndoAction (Microsoft Forms)
- Синтаксис
- Замечания
- См. также
- Поддержка и обратная связь
- Как отменить действия макроса
- Как отменить действие макроса excel
- Как отозвать макрос в Excel?
- 2 ответов
- Метод Application.Undo (Excel)
- Синтаксис
- Примечания
- Пример
- Поддержка и обратная связь
- Как отменить действие макроса excel
Метод UndoAction (Microsoft Forms)
Отменяет последнее действие, поддерживающее команду Undo (Отменить).
Синтаксис
Логических = object. UndoAction
Синтаксис метода UndoAction включает следующие элементы:
Part | Описание |
---|---|
object | Обязательно. Допустимый объект. |
Замечания
Команда пользовательского интерфейса Undo (Отменить) использует метод UndoAction. Например, если вставить текст в TextBox, можно использовать UndoAction , чтобы удалить этот текст и восстановить предыдущее содержимое TextBox.
Не все действия пользователя можно отменить. Если действие невозможно отменить, после его выполнения команда Undo будет недоступна.
Если значение свойства CanUndo равно False, команда Undo недоступна в пользовательском интерфейсе, а метод UndoAction недопустим в коде.
Если метод UndoAction применяется к форме, все изменения текущей записи теряются. Если метод UndoAction применяется к элементу управления, он влияет только на этот элемент.
Этот метод следует применять перед обновлением формы или элемента управления. Его можно добавить в событие BeforeUpdate формы или событие Change элемента управления.
UndoAction — это альтернатива использованию инструкции SendKeys для отправки значения ESC в процедуре события.
См. также
Поддержка и обратная связь
Есть вопросы или отзывы, касающиеся Office VBA или этой статьи? Руководство по другим способам получения поддержки и отправки отзывов см. в статье Поддержка Office VBA и обратная связь.
Источник
Как отменить действия макроса
Многие из тех, кто программирует в VBA знают, что после действий макроса пропадает возможность отмены действий. И если с отменой тех действий, которые были совершены до выполнения макроса совершенно точно можно распрощаться(невозможно будет это сделать), то отменить действия макроса возможно. И рано или поздно каждый программирующий в VBA задается вопросом: как можно отменить действия, совершенные макросом? Для начала надо понять, в каких ситуациях это нам надо. Например был выполнен код, который испортил или удалил данные в файле, но эти данные еще нужны. Самое простое, что можно сделать это закрыть файл без сохранения и открыть заново. Все данные будут на месте(если, конечно, в коде не было строки, сохраняющей файл). Второй способ: это перед выполнением макроса делать резервную копию файла — тогда Ваши исходные данные всегда будут целы.
Но как же сделать отмену действий макроса через стандартную кнопку на панели или сочетанием клавиш Ctrl + Z и можно ли? Ответ — можно. Но сразу вопрос: а насколько это нужно? В каких ситуациях это может пригодиться? Я навскидку сразу не сказал бы, если бы не являлся разработчиком программ и надстроек в среде Microsoft Excel. Именно в надстройках отмена действий наиболее востребована, на мой взгляд. Например надстройка объединяет ячейки. Объединили случайно и. В стандартной ситуации после такого макроса нельзя отменить действия. Закрывать файл без сохранения? Как-то некрасиво получается, если продукт является коммерческим. И тогда приходится извращаться и пытаться сделать возможным отмену действий макроса. В моей надстройке MulTEx в некоторых командах отмена действий команд как раз и применяется. Наиболее распространенное решение по отмене действий макроса заключается в запоминании свойств изменяемых ячеек:
‘Создаем свой пользовательский тип данных Type SaveRange vFormula As Variant sAddr As String lColor As Long lColorIndex As Long End Type ‘Переменные для запоминания данных Public wbWBook As Excel.Workbook Public wsSh As Excel.Worksheet Public vOldVals() As SaveRange ‘————————————————————————————— ‘ Procedure : Fill_Numbers ‘ Purpose : Основная процедура. Это тот код, который вносит изменения на лист ‘ и действия которого нам необходимо отменить ‘ Процедура заполняет выделенные ячейки номерами ‘ и изменяет цвет заливки ‘————————————————————————————— Sub Fill_Numbers() Dim rCell As Range, li As Long ‘ Сначала запоминаем значения выделенных ячеек на листе ReDim vOldVals(1 To Selection.Count) ‘Запоминаем активную книгу ‘это на случай, если отмена действий будет производиться из другой книги Set wbWBook = ActiveWorkbook ‘Запоминаем активный лист ‘на случай, если отмена действий будет производиться из другого листа Set wsSh = ActiveSheet ‘Запоминаем значения(заносим в массив) li = 1 For Each rCell In Selection ‘запоминаем адрес ячейки vOldVals(li).sAddr = rCell.Address ‘запоминаем формулу(если нет формулы — значение) vOldVals(li).vFormula = rCell.Formula ‘запоминаем цвет заливки ячейки vOldVals(li).lColor = rCell.Interior.Color ‘запоминаем индекс цвета заливки(чтобы на заливать бесцветные ячейки) vOldVals(li).lColorIndex = rCell.Interior.ColorIndex li = li + 1 Next rCell ‘====================================== ‘Выполняем основные действия(собственно тот код, который надо будет отменить) li = 1 For Each rCell In Selection rCell = li rCell.Interior.ColorIndex = li li = li + 1 Next rCell ‘====================================== ‘Назначаем стандартному вызову отмены действий выполнение нашего макроса возвращения значений Application.OnUndo «Отменить заполнение ячеек номерами», «Restore_Vals» End Sub ‘————————————————————————————— ‘ Procedure : Restore_Vals ‘ Purpose : Процедура отмены действия(возврат значений) ‘————————————————————————————— Sub Restore_Vals() Dim li As Long ‘В случае непредвиденной ошибки переходим на метку ‘и показываем сообщение об ошибке On Error GoTo Erreble ‘Активируем книгу, в которой были сделаны изменения wbWBook.Activate ‘Активируем лист, в котором были сделаны изменения wsSh.Activate ‘Возвращаем значения For li = 1 To UBound(vOldVals) Range(vOldVals(li).sAddr).Formula = vOldVals(li).vFormula ‘если заливка была безцветная, то ColorIndex = xlNone ‘значит выставляем безцветность If Not vOldVals(li).lColorIndex = xlNone Then Range(vOldVals(li).sAddr).Interior.Color = vOldVals(li).lColor Else ‘если цвет был — возвращаем его Range(vOldVals(li).sAddr).Interior.ColorIndex = xlNone End If Next li Exit Sub ‘Показываем сообщение о невозможности отмены действия Erreble: MsgBox «Нельзя отменить действие!», vbCritical, «Error» End Sub
Комментарии к коду я старался сделать максимально подробными, поэтому думаю, что больше нечего разъяснять. К тому же по древней традиции я приложил к статье пример с данным кодом 🙂 Единственное, что могу добавить: пользовательский тип SaveRange может быть дополнен еще какими-либо переменными, помимо vFormula , sAddr и lColor . Например цвет границ ячейки, цвет шрифта и т.д. Все зависит от того, какие изменения Вы будете делать кодом и что захотите затем вернуть.
Отменить действия макроса.xls (62,0 KiB, 3 346 скачиваний)
Код, приведенный выше, несомненно хорош, но если кол-во изменяемых ячеек достаточно велико, то код будет очень замедлять работу. Поэтому если есть возможность добавлять/удалять листы в книгах, то можно схитрить: сделать резервную копию листа, лист сделать очень скрытым и как только потребуется отмена действия — вернуть этот лист, удалив исходный(с уже испорченными данными):
‘Переменные для запоминания данных Public wbWBook As Workbook Public wsSh As Worksheet, wsActSh As Worksheet, sSh_Name As String, lShPoz As Long ‘————————————————————————————— ‘ Procedure : Fill_Numbers ‘ Purpose : Основная процедура. Это тот код, который вносит изменения на лист ‘ и действия которого нам необходимо отменить ‘ Процедура заполняет выделенные ячейки номерами ‘ и изменяет цвет заливки ‘————————————————————————————— Sub Fill_Numbers() Dim rCell As Range, li As Long ‘Запоминаем активную книгу ‘это на случай, если отмена действий будет производиться из другой книги Set wbWBook = ActiveWorkbook ‘Запоминаем активный лист ‘на случай, если отмена действий будет производиться из другого листа Set wsActSh = ActiveSheet lShPoz = wsActSh.Index sSh_Name = wsActSh.Name Application.ScreenUpdating = 0 wsActSh.Copy , wbWBook.Sheets(wbWBook.Sheets.Count) Set wsSh = wbWBook.Sheets(wbWBook.Sheets.Count) wsSh.Visible = xlVeryHidden wsActSh.Activate Application.ScreenUpdating = 1 ‘====================================== ‘Выполняем основные действия(собственно тот код, который надо будет отменить) li = 1 For Each rCell In Selection rCell = li rCell.Interior.ColorIndex = li li = li + 1 Next rCell ‘====================================== ‘Назначаем стандартному вызову отмены действий выполнение нашего макроса возвращения значений Application.OnUndo «Отменить заполнение ячеек номерами», «Restore_Vals» End Sub ‘————————————————————————————— ‘ Procedure : Restore_Vals ‘ Purpose : Процедура отмены действия(возврат значений) ‘————————————————————————————— Sub Restore_Vals() ‘В случае непредвиденной ошибки переходим на метку ‘и показываем сообщение об ошибке On Error GoTo Erreble Application.ScreenUpdating = 0 ‘Активируем книгу, в которой были сделаны изменения wbWBook.Activate ‘делаем видимым резервный лист wsSh.Visible = -1 ‘Удаляем исходный лист, данные в котором уже изменены Application.DisplayAlerts = 0 wsActSh.Delete Application.DisplayAlerts = 1 ‘назначаем резервному листу имя исходного wsSh.Name = sSh_Name wsSh.Move wbWBook.Sheets(lShPoz) ‘Активируем резервный лист wsSh.Activate Application.ScreenUpdating = 0 Exit Sub ‘Показываем сообщение о невозможности отмены действия Erreble: MsgBox «Нельзя отменить действие!», vbCritical, «www.excel-vba.ru» End Sub
Tips_Restore_Macro_HiddenSh.xls (45,0 KiB, 2 360 скачиваний)
Конечно, в этом приеме тоже есть недостаток — если на этот лист ссылаются формулы из других листов есть большой шанс получить в этих формулах ошибку #ССЫЛКА! (#REF!) , т.к. исходный лист удаляется.
В этом случае можно из резервного листа копировать все ячейки и вставлять на рабочий лист. Да и вообще можно много чего придумать — вплоть до сохранения и последующего извлечения резервных копий файлов. Все как всегда зависит от задач и ситуации.
И самая большая ложка дегтя к обоим кодам: VBA не позволяет таким образом делать МНОГОКРАТНЫЕ отмены действий(многократное Ctrl + Z ), что делает бесполезными попытки запомнить пошагово несколько разных изменений макросами. Отменить можно будет все равно только последнее запомненное действие.
Источник
Как отменить действие макроса excel
Как отозвать макрос в Excel?
после выполнения макроса в Excel, нет кнопки, чтобы отменить его, если вы не закроете книгу и выбрать, чтобы не сохранить его.
есть ли аккуратный и простой способ просто отменить его?
2 ответов
короткий ответ: вы не можете отменить (я предполагаю, что это то, что вы имеете в виду отмены) действия макроса. Решения, которые происходят внутри языка программирования может быть хлопотно для Excel, чтобы обратить вспять, так что есть одеяло» не может отменить » состояние, вызванное пиная макроса.
длинный ответ заключается в том, что если вы ожидаете отмены, ваш код должен учитывать этот запрос, сохраняя предыдущее состояние данных перед выполнением. Это очень широкий предположение, что вы работаете с данными в VBA; прямое создание файла и манипуляции могут быть сложнее в зависимости от того, что выполняется.
Джон Walkenbach дает хороший пример хранения данных, чтобы обеспечить будущее средство отмены:
пользователи компьютеров привыкли к возможности «отменить» операцию. Почти каждую операцию, выполняемую в Excel, можно отменить. Если вы программируете в VBA, вы, возможно, задавались вопросом, Можно ли отменить эффекты подпрограммы. Ответ утвердительный ответ. Квалифицированный ответ-это не всегда легко.
Я думаю, что его вступительное заявление немного вводит в заблуждение: для некодирующих пользователям ответ «Нет, вы не можете отменить макрос».
Метод Application.Undo (Excel)
Отменяет последнее действие пользовательского интерфейса.
Синтаксис
выражения. Отмена
выражение: переменная, представляющая объект Application.
Примечания
Этот метод отменяет только последнее действие, принятое пользователем перед запуском макроса, и он должен быть первой строкой макроса. Его нельзя использовать для отмены Visual Basic команд.
Пример
В этом примере отменяется последнее действие пользовательского интерфейса. Пример должен быть первой строкой макроса.
Поддержка и обратная связь
Есть вопросы или отзывы, касающиеся Office VBA или этой статьи? Руководство по другим способам получения поддержки и отправки отзывов см. в статье Поддержка Office VBA и обратная связь.
Как отменить действие макроса excel
Регистрация на форуме тут, о проблемах пишите сюда — alarforum@yandex.ru, проверяйте папку спам! Обязательно пройдите восстановить пароль
Поиск по форуму |
Расширенный поиск |
Страница 1 из 2 | 1 | 2 | Следующая > |
Chelentano |
Посмотреть профиль |
Найти ещё сообщения от Chelentano |
Это достаточно долгая история, постараюсь прояснить часть в кратце.
Откат можно сделать несколькими способами:
1. Самый неудобный, но и самый надежный. Вы не сохраняете изменения в файле, после выполнения макроса и закрываете файл без сохранения.
2. Наиболее геморный для пользователя. В меню Сервис — Доступ к книге, выделить закладку Правка. Установить галочку напротив «Разрешить совместный доступ» -ОК. Затем на все вопросы — ОК.
Для просмотра и отмены изменений в книге — Сервис — Исправления — Принять/отклонить исправления.
Примечание : Общая книга имеет ряд ограничений, которые обязательно необходимо учитывать при работе с ней.
3. Через Aplication.OnUndo
Данный метод более прост для использования конечным пользователем, но сложноват в исполнении и надо учитывать, что все данные об изменениях, совершенных до макроса, будут стерты.
В общих чертах:
Создаете глобальные переменные, в которые будете заносить информацию о данных, содержащихся в изменяемом макросом диапазоне.
Создаете отдельную процедуру, в которой заполняете эти пременыне данными. Перед выполнением основного макроса вызываете эту процедуру, а в конце основного макроса вставляете строку
Application.OnUndo «Отмена», «Здесь_имя_макроса_запоминания_знач ений»
Вроде так. Может кто дополнит.
Это достаточно долгая история, постараюсь прояснить часть в кратце.
Откат можно сделать несколькими способами:
.
Вроде так. Может кто дополнит.
перед выполнением макроса сделать
и потом откатываться на него.
DiemonStar |
Посмотреть профиль |
Найти ещё сообщения от DiemonStar |
fil_v, чем так «глобальность» испугала? В такое время живём
Глобальные/публичные — это переменные, которые живут и тогда, когда макрос уже отработал.
Т.е. создали такие переменные, затем одним макросом задали им значения, другим позже эти значения прочитали/изменили.
перед выполнением макроса сделать
и потом откатываться на него.
fil_v, чем так «глобальность» испугала? В такое время живём
Глобальные/публичные — это переменные, которые живут и тогда, когда макрос уже отработал.
Т.е. создали такие переменные, затем одним макросом задали им значения, другим позже эти значения прочитали/изменили.
Источник
I always save immediately before running my macros (during testing at least) then, if everything goes pear-shaped, I can just exit without saving and re-open it.
Baking it into the actual macro, you’ll have to basically record the old state of everything that changes (cell contents, formulae, formatting and so on) in a list then have an undo macro which plays back that list in reverse order.
For example if your macro changes a cell C22 contents from «3» to «7» and formatting from «general» to «number, 2 decimals), your list would be:
C22 value 3
C22 format general
Playing this back in reverse order (with another macro) would revert the changes.
You could have a whole extra sheet to hold the macro undo information such as:
Step Cell Type Value
---- ---- ----- -------
1 C22 value 3
C22 format general
2...
It wouldn’t integrate very well with the ‘real’ undo unfortunately, but I don’t think there’s any way around that.