Итак общими усилиями сделали файлик в котором с помощью макросов и 2 дополнительных листов организовано сохранение истории. И даже кнопочки при нажатии на которые происходит действие аналогичное действию Ctrl+z и Ctrl+Shift+z получились. Но, опять проблема, попробовала повесить макрос на кнопки Ctrl+z, а перехват этой комбинации перестает работать после любого срабатывания одной из кнопок. В чем может быть дело? После любой правки документа перехват начинает работать дальше. А кнопки работают постоянно. Ниже обработчик нажатия кнопки "undo" тоже самое (с точностью до имени процедуры) должно вызываться при нажатии Ctrl+z.
Код
Private Sub CommandButton2_Click()
Dim ptr As Integer
Dim rng As Range
Dim val As Variant
Dim i As Integer
Dim Cell As Range
ptr = Sheets("LOG").Range("h1").Value
If Sheets("LOG").Range("b" & ptr).Value = "" Then
MsgBox ("сохраненная история кончилась...")
Application.EnableEvents = True
Exit Sub
End If
Application.EnableEvents = False
Set rng = Worksheets(Sheets("LOG").Range("d" & ptr).Value).Range(Sheets("LOG").Range("b" & ptr).Value)
val = Sheets("LOG").Range("e" & ptr).Value
If InStr(val, "#") <> 0 Then
val = WorksheetFunction.Transpose(Split(val, "#"))
i = 1
For Each Cell In rng
Cell.Value = val(i, 1)
i = i + 1
Next
Else
rng.Value = val
End If
Worksheets("Back").Range("a1:t400").Value = ActiveSheet.Range("a1:t400").Value
Sheets("LOG").Range("h1").Value = Sheets("LOG").Range("h1").Value - 1
Application.EnableEvents = True
End Sub
так же прилагаю и весь получившийся файл - может не правильно поняла где ошибка и/или еще кому-то пригодиться. P.S. если б еще придумать как повесить макросы на пункты меню "отмена", "возврат" и на стрелочки... Совсем модно вышло бы.
YuryK пишет: Для себя решил проблему так просто копированием листа по событию изменение в листе. Десять скрытых листов и циклическая перезапись. Способ дубовый, но может Вам такая идея подойдет.
И так, я решила скомбинировать 2 подхода. Собственно проблема подхода от Юрий М была в том, что в случае протягивания ячейки не правильно заполнялось поле старого значения, все остальное вроде бы было правильно. Вот я и решила использовать подход YuryK для поучения корректных данных для поля старого значения. И так, мои правки в модулях найденных здесь. 1) добавила второй служебный лист "back" (для получения старых значений) 2) добавила к каждому рабочему листу копирование данных с листа на "back" по событию активации листа (собственно мне достаточно не всего листа, а только его зоны, но это детали) 3) заменила обработчик Workbook_SheetSelectionChange на подобную функцию get_sValue, с тем чтоб функция добывала старые значения из резервной копии, а не запоминала при смене выделения. 4) в обработчик Workbook_SheetChange добавила обращение к функции get_sValue (в начале) и обновление резервной копии (в конце)
Ну и все - вроде работает. Глючит правда при вырезании значений на одном листе и вставке на другой, но меня это не смущает, т.к. я вырезания в своей книге вообще запрещаю (чтоб формулы не сбивались).
А теперь вопрос. Как мне сделать так, чтоб журнал продолжался не до бесконечности (на самом-то деле до конца листа), а включал в себя только N последних изменений записанных на строках с 2 по N+2 в хронологическом порядке? Т.е. при N+1 изменении удалить строку 2 (с тем чтоб все строки сдвинулись на одну вверх) и дополнить журнал снизу. По идее правка должна быть не большой, но я что-то не могу разобраться в коде. Свое творчество прилагаю (служебные листы не скрыты т.к. это рабочий вариант).
когда мозг программиста отдыхает процессор работает на 100%, и наоборот
У меня в книге 4 листа, соответственно, добавить надо будет 4*10 = 40 листов, с учетом что у пользователя машина оч. слабенькая боюсь тормозить сильно будет. Хотя... наверно, можно подумать в сторону комбинирования резервной копии с журналом - как-то так чтоб копия была одна но благодаря ей получалось вести журнал...
Начала думать и наткнулась на глупый вопрос - а как не переводя курсор скопировать заданный диапазон с одного листа на другой?
и все-таки не совсем то ( макрос глючит в случа использован я автозаполнения. Ввод, копирование и вставка обрабатываются на ура, а с протягиванием проблема. В принципе, по идее мне это автозаполнение не особо нужно, но как тогда запретить пользователю им пользоваться?
когда мозг программиста отдыхает процессор работает на 100%, и наоборот
Юрий М, там, в принципе, то, и даже больше чем мне надо (мне не важно кто и когда менял), но хочется чего-то по-проще, хотя если ничего лучше не найду - применю и этот подход.
когда мозг программиста отдыхает процессор работает на 100%, и наоборот
ikki пишет: включение/отключение защиты листа очищает буфер. любым способом - вручную или макросом.
Не знала, теперь хотя бы знаю в чем проблема. Спасибо )
Цитата
ikki пишет: что значит "случайно перетёр"?
Например, рядом есть колонки типа "запланировано" и "сделано". Хотел подправить "сделано", но промахнулся и вбил в планы, потом хватился, но что планировалось уже затерто. Определить это может только пользователь, поэтому и не могу я эти ошибки макросом перехватить.
Цитата
ikki пишет: есть хороший способ бороться с ошибками - не допускать их.
Я же не себе делаю - свои мозги не вставишь, да и не ошибается только тот кто ничего не делает.
когда мозг программиста отдыхает процессор работает на 100%, и наоборот
ikki пишет: по поводу буфера обмена - вообще-то запуск макроса не очищает буфер автоматом. но кто ж знает, что именно и как делают ваши макросы?
Мне казалось, что я ничего особенного не делаю... Вот собственно мой макрос
Код
Private Sub Set_Filter()
Unprotect "*****"
If OptionButtonAll.Value Then
Cells(30, 4).AutoFilter Field:=30, Criteria1:=">=0", Operator:=xlAnd
Else
Cells(30, 4).AutoFilter Field:=30, Criteria1:=">0", Operator:=xlAnd
End If
Protect "*****", DrawingObjects:=True, Contents:=True, Scenarios:=True _
, AllowFormattingCells:=True, AllowFormattingColumns:=True, _
AllowFormattingRows:=True, AllowFiltering:=True
End Sub
Цитата
ikki пишет: по поводу "выборочной" отмены ... вы хотите странного.
Видимо коряво сформулировала вопрос. Будут ли оседать в истории действия макроса мне не важно - главное чтоб история просто не прерывалась. И если пользователь случайно перетер нужные данные, он мог бы их вернуть пусть не одним, а 2, 3, 10-ю отменами последних действий. В такой формулировке, есть более легкое решение?
когда мозг программиста отдыхает процессор работает на 100%, и наоборот
Здравствуйте, я использую макросы для перерасчета автофильтров по мере ввода данных и проверки этих самых данных. Таким образом маленькие макросы срабатывают практически при каждом изменении таблицы и или перелистывании листа.
При этом почему-то теряются две возможности: 1) отката действий пользователя. На случай ввел что-то что выглядит правдоподобно, но хотел ввести другое или в другое место, а пути назад уже нет - только заново вбивать. 2) возможность вставки заранее скопированных данных. Например, скопировал данные на одном листе, хотел вставить на другом, а данных (в буфере) уже нет.
Собственно эти две возможности и хотелось бы сохранить.
P.S. Видела тему про откат действий макроса, но у меня задача можно сказать обратная. Т.е. мне не надо хранить данные которые меняет макрос, а только то что меняет пользователь, но в не зависимости от того было это до или после работы макроса.
когда мозг программиста отдыхает процессор работает на 100%, и наоборот