Есть два макроса, один создает дополнительные строчки другой их откатывает. Работают нормально, но не нравиться, что тот который создает доп. строчки, добавляет дополнительные листы в книгу (которые нужны для макроса отката), хотелось бы что бы он это не делал, а использовал всё время один доп. лист или вообще их не создавал, но что бы макрос отката при этом продолжал работать так же нормально, задача что бы книга листами не разросталась до бесконечности после многократного использования макроса, но оба макроса бы успешно так же работали. Кусочек файла с ним приложил. В VBA полный ноль, если можно подправьте этот исходник макроса или выложите своё решение. Спасибо
'Переменные для запоминания данных Public wbWBook As Workbook Public wsSh As Worksheet, wsActSh As Worksheet, sSh_Name As String, lShPoz As Long '--------------------------------------------------------------------------------------- ' Procedure : Вставить_строку ' Purpose : Основная процедура. Это тот код, который вносит изменения на лист ' и действия которого нам необходимо отменить '--------------------------------------------------------------------------------------- Sub Вставить_строку() 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 '====================================== 'Выполняем основные действия(собственно тот код, который надо будет отменить) ' ' Добавление строки ' 'ActiveSheet.Unprotect With ActiveCell.EntireRow .Offset(1).Insert .Copy .Offset(1) End With Cells(ActiveCell.Row + 1, 1).Resize(, 3).ClearContents Cells(ActiveCell.Row + 1, "K").Resize(, 2).ClearContents 'ActiveSheet.Protect '====================================== 'Назначаем стандартному вызову отмены действий выполнение нашего макроса возвращения значений Application.OnUndo "Отменить макрос", "Откат" End Sub
'--------------------------------------------------------------------------------------- ' Procedure : Откат ' Purpose : Процедура отмены действия(возврат значений) '--------------------------------------------------------------------------------------- Sub Откат() 'В случае непредвиденной ошибки переходим на метку 'и показываем сообщение об ошибке 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, "Error" End Sub
[/vba]
Есть два макроса, один создает дополнительные строчки другой их откатывает. Работают нормально, но не нравиться, что тот который создает доп. строчки, добавляет дополнительные листы в книгу (которые нужны для макроса отката), хотелось бы что бы он это не делал, а использовал всё время один доп. лист или вообще их не создавал, но что бы макрос отката при этом продолжал работать так же нормально, задача что бы книга листами не разросталась до бесконечности после многократного использования макроса, но оба макроса бы успешно так же работали. Кусочек файла с ним приложил. В VBA полный ноль, если можно подправьте этот исходник макроса или выложите своё решение. Спасибо
'Переменные для запоминания данных Public wbWBook As Workbook Public wsSh As Worksheet, wsActSh As Worksheet, sSh_Name As String, lShPoz As Long '--------------------------------------------------------------------------------------- ' Procedure : Вставить_строку ' Purpose : Основная процедура. Это тот код, который вносит изменения на лист ' и действия которого нам необходимо отменить '--------------------------------------------------------------------------------------- Sub Вставить_строку() 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 '====================================== 'Выполняем основные действия(собственно тот код, который надо будет отменить) ' ' Добавление строки ' 'ActiveSheet.Unprotect With ActiveCell.EntireRow .Offset(1).Insert .Copy .Offset(1) End With Cells(ActiveCell.Row + 1, 1).Resize(, 3).ClearContents Cells(ActiveCell.Row + 1, "K").Resize(, 2).ClearContents 'ActiveSheet.Protect '====================================== 'Назначаем стандартному вызову отмены действий выполнение нашего макроса возвращения значений Application.OnUndo "Отменить макрос", "Откат" End Sub
'--------------------------------------------------------------------------------------- ' Procedure : Откат ' Purpose : Процедура отмены действия(возврат значений) '--------------------------------------------------------------------------------------- Sub Откат() 'В случае непредвиденной ошибки переходим на метку 'и показываем сообщение об ошибке 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, "Error" End Sub
Господа может поможете даме, как вставить мой рабочий код «Добавление строки», чтобы он работал и откатывался так же, как и код который я привела ниже этот новый макрос уже не создаёт лишних листов в книге, как предыдущий, пусть хотя бы с одноразовым откатом, такой вариант устроил бы то же.
Это мой рабочий код. [vba]
Код
' Добавление строки ' With ActiveCell.EntireRow .Offset(1).Insert .Copy .Offset(1) End With Cells(ActiveCell.Row + 1, 1).Resize(, 3).ClearContents Cells(ActiveCell.Row + 1, "K").Resize(, 2).ClearContents
[/vba]
Вот два макросы которые исполняют и откатывают, без создания лишних листов, но к сожалению с другим рабочим кодом, помогите туда вставить мой, что бы так же откатывался, как этот, совсем в VBA не чего не смыслю.
Это два макроса куда нужно вставить мой рабочий код. [vba]
Код
'Создаем свой пользовательский тип данных Type SaveRange vFormula As Variant sAddr As String lColor As Long End Type 'Переменные для запоминания данных Public wbWBook As Workbook Public wsSh As 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 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 Range(vOldVals(li).sAddr).Interior.Color = vOldVals(li).lColor Next li Exit Sub
'Показываем сообщение о невозможности отмены действия Erreble: MsgBox "Нельзя отменить действие!", vbCritical, "Error" End Sub
[/vba]
Господа может поможете даме, как вставить мой рабочий код «Добавление строки», чтобы он работал и откатывался так же, как и код который я привела ниже этот новый макрос уже не создаёт лишних листов в книге, как предыдущий, пусть хотя бы с одноразовым откатом, такой вариант устроил бы то же.
Это мой рабочий код. [vba]
Код
' Добавление строки ' With ActiveCell.EntireRow .Offset(1).Insert .Copy .Offset(1) End With Cells(ActiveCell.Row + 1, 1).Resize(, 3).ClearContents Cells(ActiveCell.Row + 1, "K").Resize(, 2).ClearContents
[/vba]
Вот два макросы которые исполняют и откатывают, без создания лишних листов, но к сожалению с другим рабочим кодом, помогите туда вставить мой, что бы так же откатывался, как этот, совсем в VBA не чего не смыслю.
Это два макроса куда нужно вставить мой рабочий код. [vba]
Код
'Создаем свой пользовательский тип данных Type SaveRange vFormula As Variant sAddr As String lColor As Long End Type 'Переменные для запоминания данных Public wbWBook As Workbook Public wsSh As 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 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 Range(vOldVals(li).sAddr).Interior.Color = vOldVals(li).lColor Next li Exit Sub
'Показываем сообщение о невозможности отмены действия Erreble: MsgBox "Нельзя отменить действие!", vbCritical, "Error" End Sub
'Переменные для запоминания данных Public wbWBook As Workbook Public wsSh As Worksheet, wsActSh As Worksheet, sSh_Name As String, lShPoz As Long '--------------------------------------------------------------------------------------- ' Procedure : Вставить_строку ' Purpose : Основная процедура. Это тот код, который вносит изменения на лист ' и действия которого нам необходимо отменить '--------------------------------------------------------------------------------------- Sub Вставить_строку() Dim rCell As Range, li As Long 'Запоминаем активную книгу 'это на случай, если отмена действий будет производиться из другой книги Set wbWBook = ActiveWorkbook 'Запоминаем активный лист 'на случай, если отмена действий будет производиться из другого листа Set wsActSh = ActiveSheet lShPoz = wsActSh.Index sSh_Name = wsActSh.Name Application.ScreenUpdating = 0
On Error Resume Next Set wsSh = wbWBook.Sheets("резерв") If Err.Number <> 0 Then Set wsSh = wbWBook.Sheets.Add(After:=wbWBook.Sheets(wbWBook.Sheets.Count)) wsSh.Visible = xlVeryHidden wsSh.Name = "резерв" End If Err.Clear On Error GoTo 0
wsActSh.Cells.Copy wsSh.[a1] wsActSh.Activate Application.ScreenUpdating = 1 '====================================== 'Выполняем основные действия(собственно тот код, который надо будет отменить) ' ' Добавление строки ' 'ActiveSheet.Unprotect With ActiveCell.EntireRow .Offset(1).Insert .Copy .Offset(1) End With Cells(ActiveCell.Row + 1, 1).Resize(, 3).ClearContents Cells(ActiveCell.Row + 1, "K").Resize(, 2).ClearContents 'ActiveSheet.Protect '====================================== 'Назначаем стандартному вызову отмены действий выполнение нашего макроса возвращения значений Application.OnUndo "Отменить макрос", "Откат" End Sub
'--------------------------------------------------------------------------------------- ' Procedure : Откат ' Purpose : Процедура отмены действия(возврат значений) '--------------------------------------------------------------------------------------- Sub Откат() 'В случае непредвиденной ошибки переходим на метку 'и показываем сообщение об ошибке 'On Error GoTo Erreble Application.ScreenUpdating = 0 'Активируем книгу, в которой были сделаны изменения wbWBook.Activate 'делаем видимым резервный лист wsSh.Visible = -1 'Удаляем исходный лист, данные в котором уже изменены Application.DisplayAlerts = 0 wsActSh.Delete 'назначаем резервному листу имя исходного wsSh.Name = sSh_Name On Error Resume Next wsSh.Move wbWBook.Sheets(lShPoz) 'Активируем резервный лист wsSh.Activate Application.ScreenUpdating = 0 Application.DisplayAlerts = True Exit Sub 'Показываем сообщение о невозможности отмены действия Erreble: MsgBox "Нельзя отменить действие!", vbCritical, "Error" End Sub
[/vba]
kiramiD, здравствуйте, попробуйте так:
[vba]
Код
Option Explicit
'Переменные для запоминания данных Public wbWBook As Workbook Public wsSh As Worksheet, wsActSh As Worksheet, sSh_Name As String, lShPoz As Long '--------------------------------------------------------------------------------------- ' Procedure : Вставить_строку ' Purpose : Основная процедура. Это тот код, который вносит изменения на лист ' и действия которого нам необходимо отменить '--------------------------------------------------------------------------------------- Sub Вставить_строку() Dim rCell As Range, li As Long 'Запоминаем активную книгу 'это на случай, если отмена действий будет производиться из другой книги Set wbWBook = ActiveWorkbook 'Запоминаем активный лист 'на случай, если отмена действий будет производиться из другого листа Set wsActSh = ActiveSheet lShPoz = wsActSh.Index sSh_Name = wsActSh.Name Application.ScreenUpdating = 0
On Error Resume Next Set wsSh = wbWBook.Sheets("резерв") If Err.Number <> 0 Then Set wsSh = wbWBook.Sheets.Add(After:=wbWBook.Sheets(wbWBook.Sheets.Count)) wsSh.Visible = xlVeryHidden wsSh.Name = "резерв" End If Err.Clear On Error GoTo 0
wsActSh.Cells.Copy wsSh.[a1] wsActSh.Activate Application.ScreenUpdating = 1 '====================================== 'Выполняем основные действия(собственно тот код, который надо будет отменить) ' ' Добавление строки ' 'ActiveSheet.Unprotect With ActiveCell.EntireRow .Offset(1).Insert .Copy .Offset(1) End With Cells(ActiveCell.Row + 1, 1).Resize(, 3).ClearContents Cells(ActiveCell.Row + 1, "K").Resize(, 2).ClearContents 'ActiveSheet.Protect '====================================== 'Назначаем стандартному вызову отмены действий выполнение нашего макроса возвращения значений Application.OnUndo "Отменить макрос", "Откат" End Sub
'--------------------------------------------------------------------------------------- ' Procedure : Откат ' Purpose : Процедура отмены действия(возврат значений) '--------------------------------------------------------------------------------------- Sub Откат() 'В случае непредвиденной ошибки переходим на метку 'и показываем сообщение об ошибке 'On Error GoTo Erreble Application.ScreenUpdating = 0 'Активируем книгу, в которой были сделаны изменения wbWBook.Activate 'делаем видимым резервный лист wsSh.Visible = -1 'Удаляем исходный лист, данные в котором уже изменены Application.DisplayAlerts = 0 wsActSh.Delete 'назначаем резервному листу имя исходного wsSh.Name = sSh_Name On Error Resume Next wsSh.Move wbWBook.Sheets(lShPoz) 'Активируем резервный лист wsSh.Activate Application.ScreenUpdating = 0 Application.DisplayAlerts = True Exit Sub 'Показываем сообщение о невозможности отмены действия Erreble: MsgBox "Нельзя отменить действие!", vbCritical, "Error" End Sub
Здравствуйте!!! Manyasha, или еще кто-нибудь )) у меня тоже просьба
так же взял модуль из первого поста и внедрил к себе в файл с макросом.
макрос (или исходная строка) - не совсем понимаю их отличия... ну в общем задача такая:
есть файл с таблицей. в двух столбиках я (не совсем я, с помощью ваших коллег на форуме) сделал выпадающий список (с выбором формулировок).
т.е. в любую ячейку одного столбика мы вносим данные из выпадающего списка через точку с запятой с возможностью редактировать их.
вот такой: [vba]
Код
Private Sub Worksheet_Change(ByVal Target As Range) On Error Resume Next If Not Intersect(Target, Range("W:W;BA:BA")) Is Nothing And Target.Cells.Count = 1 Then Application.EnableEvents = False newval = Target Application.Undo oldval = Target If IsError(Application.WorksheetFunction.Match(newval, Range(Replace(Target.Validation.Formula1, "=", "")), 0))Then Target = newval Else If Len(oldval) <> 0 And oldval <> newval Then Target = Target & ";" & Chr(10) & " " & newval Else Target = newval End If End If If Len(newval) = 0 Then Target.ClearContents Application.EnableEvents = True End If End Sub
[/vba]
Однако при внесении изменений макрос сразу их сохраняет. нельзя откатить через ctrl +z.
попробовал использовать код что выше: [vba]
Код
'Создаем свой пользовательский тип данных Type SaveRange vFormula As Variant sAddr As String lColor As Long End Type 'Переменные для запоминания данных Public wbWBook As Workbook Public wsSh As 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 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 Range(vOldVals(li).sAddr).Interior.Color = vOldVals(li).lColor Next li Exit Sub
'Показываем сообщение о невозможности отмены действия Erreble: MsgBox "Нельзя отменить действие!", vbCritical, "Error" End Sub
[/vba]
конечно свои функции он выполняет - откатить заливку.
Но у нас вариантов может быть множество: не ту дату дописал, не то слово, не ту формулировку, не туда цифры воткнул и т.д.
Есть ли список всевозможных Type SaveRange чтоб их прописать в код??? или как-то иначе сделать? только чтоб можно было откатить изменения как в столбце с выпадающим списком, так и во всем листе!
и столкнулся с еще одной проблемой: по какой-то причине теперь нельзя скопировать строку и вставить ниже - ну чтоб дублирующие ячейки в таблице при заполнении не писать вручную.. копируется но когда вставляешь "миркнет" что вроде выставляет, но "бам" и ничего не вставил!!! - как эту пролему решить ? заранее благодарю!)
Здравствуйте!!! Manyasha, или еще кто-нибудь )) у меня тоже просьба
так же взял модуль из первого поста и внедрил к себе в файл с макросом.
макрос (или исходная строка) - не совсем понимаю их отличия... ну в общем задача такая:
есть файл с таблицей. в двух столбиках я (не совсем я, с помощью ваших коллег на форуме) сделал выпадающий список (с выбором формулировок).
т.е. в любую ячейку одного столбика мы вносим данные из выпадающего списка через точку с запятой с возможностью редактировать их.
вот такой: [vba]
Код
Private Sub Worksheet_Change(ByVal Target As Range) On Error Resume Next If Not Intersect(Target, Range("W:W;BA:BA")) Is Nothing And Target.Cells.Count = 1 Then Application.EnableEvents = False newval = Target Application.Undo oldval = Target If IsError(Application.WorksheetFunction.Match(newval, Range(Replace(Target.Validation.Formula1, "=", "")), 0))Then Target = newval Else If Len(oldval) <> 0 And oldval <> newval Then Target = Target & ";" & Chr(10) & " " & newval Else Target = newval End If End If If Len(newval) = 0 Then Target.ClearContents Application.EnableEvents = True End If End Sub
[/vba]
Однако при внесении изменений макрос сразу их сохраняет. нельзя откатить через ctrl +z.
попробовал использовать код что выше: [vba]
Код
'Создаем свой пользовательский тип данных Type SaveRange vFormula As Variant sAddr As String lColor As Long End Type 'Переменные для запоминания данных Public wbWBook As Workbook Public wsSh As 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 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 Range(vOldVals(li).sAddr).Interior.Color = vOldVals(li).lColor Next li Exit Sub
'Показываем сообщение о невозможности отмены действия Erreble: MsgBox "Нельзя отменить действие!", vbCritical, "Error" End Sub
[/vba]
конечно свои функции он выполняет - откатить заливку.
Но у нас вариантов может быть множество: не ту дату дописал, не то слово, не ту формулировку, не туда цифры воткнул и т.д.
Есть ли список всевозможных Type SaveRange чтоб их прописать в код??? или как-то иначе сделать? только чтоб можно было откатить изменения как в столбце с выпадающим списком, так и во всем листе!
и столкнулся с еще одной проблемой: по какой-то причине теперь нельзя скопировать строку и вставить ниже - ну чтоб дублирующие ячейки в таблице при заполнении не писать вручную.. копируется но когда вставляешь "миркнет" что вроде выставляет, но "бам" и ничего не вставил!!! - как эту пролему решить ? заранее благодарю!)lok888