Vba excel предыдущее значение ячейки

I had a need to capture and compare old values to the new values entered into a complex scheduling spreadsheet. I needed a general solution which worked even when the user changed many rows at the same time. The solution implemented a CLASS and a COLLECTION of that class.

The class: oldValue

Private pVal As Variant
Private pAdr As String
Public Property Get Adr() As String
   Adr = pAdr
End Property
Public Property Let Adr(Value As String)
    pAdr = Value
End Property
Public Property Get Val() As Variant
   Val = pVal
End Property
Public Property Let Val(Value As Variant)
   pVal = Value
End Property

There are three sheets in which i track cells. Each sheet gets its own collection as a global variable in the module named ProjectPlan as follows:

Public prepColl As Collection
Public preColl As Collection
Public postColl As Collection
Public migrColl As Collection

The InitDictionaries SUB is called out of worksheet.open to establish the collections.

Sub InitDictionaries()
    Set prepColl = New Collection
    Set preColl = New Collection
    Set postColl = New Collection
    Set migrColl = New Collection
End Sub

There are three modules used to manage each collection of oldValue objects they are Add, Exists, and Value.

Public Sub Add(ByRef rColl As Collection, ByVal sAdr As String, ByVal sVal As Variant)
    Dim oval As oldValue
    Set oval = New oldValue
    oval.Adr = sAdr
    oval.Val = sVal
    rColl.Add oval, sAdr
End Sub

Public Function Exists(ByRef rColl As Collection, ByVal sAdr As String) As Boolean
   Dim oReq As oldValue
   On Error Resume Next
   Set oReq = rColl(sAdr)
   On Error GoTo 0

   If oReq Is Nothing Then
      Exists = False
   Else
      Exists = True
   End If
End Function
Public Function Value(ByRef rColl As Collection, ByVal sAdr) As Variant
   Dim oReq As oldValue
   If Exists(rColl, sAdr) Then
      Set oReq = rColl(sAdr)
      Value = oReq.Val
   Else
      Value = ""
   End If
End Function

The heavy lifting is done in the Worksheet_SelectionChange callback. One of the four is shown below. The only difference is the collection used in the ADD and EXIST calls.

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
   Dim mode As Range
   Set mode = Worksheets("schedule").Range("PlanExecFlag")
   If mode.Value = 2 Then
      Dim c As Range
      For Each c In Target
          If Not ProjectPlan.Exists(prepColl, c.Address) Then
             Call ProjectPlan.Add(prepColl, c.Address, c.Value)
          End If
      Next c
   End If
End Sub

THe VALUE call is called out of code executed from the Worksheet_Change Callback for example. I need to assign the correct collection based on the sheet name:

   Dim rColl As Collection
   If sheetName = "Preparations" Then
       Set rColl = prepColl
   ElseIf sheetName = "Pre-Tasks" Then
       Set rColl = preColl
   ElseIf sheetName = "Migr-Tasks" Then
       Set rColl = migrColl
   ElseIf sheetName = "post-Tasks" Then
       Set rColl = postColl
   Else
   End If

and then i am free to compute compare the some current value to the original value.

If Exists(rColl, Cell.Offset(0, 0).Address) Then
   tsk_delay = Cell.Offset(0, 0).Value - Value(rColl, Cell.Offset(0, 0).Address)
Else
   tsk_delay = 0
End If

Mark

 

Добрый день, Ув. Форумчане!

Прошу подсказать решение следующей задачи:
необходимо сохранять в переменную старое значение ячейки (до его изменения).
Сложность для меня заключается в том, что выбор нового значения происходит из выпадающего списка, поэтому событие листа Worksheet_SelectionChange срабатывает, если ячейка до этого не была активна. Если же ячейка уже активна, то не срабатывает.
Заранее благодарю за любую помощь!

Прикрепленные файлы

  • Пример.xlsm (14.85 КБ)

 

webley

Пользователь

Сообщений: 1995
Регистрация: 01.01.1970

#2

03.02.2022 11:36:08

Добрый день. А если без Worksheet_SelectionChange, вот так?

Код
Private Sub Worksheet_Change(ByVal Target As Range)
    If Not Intersect(Target, Range("A1")) Is Nothing Then
        MsgBox Target.Value & " / " & СтароеЗначение, 64 'новое и старое значение
    End If
    СтароеЗначение = Target.Value
End Sub
 

ANDREY

Пользователь

Сообщений: 24
Регистрация: 02.02.2022

 

Спасибо за вариант, но при первом запуске это работать не будет, т.к. переменная СтароеЗначение изначально будет пустой.
В условиях задачи это не указал (формировал упрощенный пример), но в реальном файле будет диапазон изменяемых таким способом ячеек.

 

webley

Пользователь

Сообщений: 1995
Регистрация: 01.01.1970

ну тогда можно совместить — первоначальное значение присваивать, например, через Worksheet_SelectionChange (хотя можно при активации листа/открытии книги), а изменение уже отслеживать «по факту» в процедуре Worksheet_Change

 

ANDREY

Пользователь

Сообщений: 24
Регистрация: 02.02.2022

#6

03.02.2022 12:26:05

Цитата
написал:
переменная СтароеЗначение изначально будет пустой

Данная переменная перестает быть пустой при выделении или активации ячейки. Если в этой ячейке отсутствует значение, то значит предыдущее значение «». И это можно обработать.

 

vikttur

Пользователь

Сообщений: 47199
Регистрация: 15.09.2012

#7

03.02.2022 12:26:26

В Worksheet_Change

Код
Undo
Старое значение =...
Undo
 

Alexey0185

Пользователь

Сообщений: 133
Регистрация: 04.02.2016

#8

03.02.2022 12:28:01

ANDREY, в том и проблема, что через Worksheet_SelectionChange значение присваивается, если ячейка до этого не была активной. А если она в данный момент активна, то Worksheet_SelectionChange не срабатывает.

Цитата
написал: Undo

Благодарю!!! Работает!

 

Alexey0185

Пользователь

Сообщений: 133
Регистрация: 04.02.2016

#9

03.02.2022 12:33:13

Цитата
написал: Undo

Благодарю!!! Работает!

ANDREY,

Изменено: vikttur03.02.2022 12:41:53

 

БМВ

Модератор

Сообщений: 21378
Регистрация: 28.12.2016

Excel 2013, 2016

#10

03.02.2022 12:41:41

Alexey0185,  смотрите что написал vikttur.
Он конечно схитрил, не все так просто. и это применимо для одной ячейки

Код
Private Sub Worksheet_Change(ByVal Target As Range)
Dim val
If Not Intersect(Target, Cells(1, 1)) Is Nothing And Target.Count = 1 Then
    Application.EnableEvents = False
    val = Target.Value
    Application.Undo
    Cells(2, 1) = Target.Value
    Target.Value = val
    Application.EnableEvents = True
End If
End Sub

или можно с трудом натянуть на неразрывный диапазон, но сейчас если скопировать что-то в A1:b1, то сломается.

ну и

тут

не простой но вариант

По вопросам из тем форума, личку не читаю.

 

vikttur

Пользователь

Сообщений: 47199
Регистрация: 15.09.2012

#11

03.02.2022 12:45:14

Не схитрил, а предложил

Цитата
сохранять в переменную старое значение ячейки

И про application забыл…

 

Alexey0185

Пользователь

Сообщений: 133
Регистрация: 04.02.2016

#12

03.02.2022 12:58:40

БМВ

, благодарю!
Ваш вариант более логично вписался в мои «художества» )

Цитата
написал: И про application забыл…

Про application я и сам догуглил. Направление задали верное — это главное.

 

БМВ

Модератор

Сообщений: 21378
Регистрация: 28.12.2016

Excel 2013, 2016

#13

03.02.2022 13:08:03

Уппс, а я вот никогда не пользовал undo undo  и думал что по стеку идет в одном направлении, а оно именно одно действие отменяет, при этом сама отмена становится последним…
тогда можно так

Код
Private Sub Worksheet_Change(ByVal Target As Range)
Dim val
If Not Intersect(Target, Cells(1, 1)) Is Nothing Then
    Application.EnableEvents = False
    Application.Undo
    val = Target.Value
     Application.Undo
     Cells(2, 1) = val
    Application.EnableEvents = True
End If
End Sub

По вопросам из тем форума, личку не читаю.

 

_Igor_61

Пользователь

Сообщений: 3007
Регистрация: 18.07.2016

Михаил, СПАСИБО!!!
Подобные задачи у меня получалось решать только способами типа :»старое значение сохраняю в другой ячейке», а как сделать чтобы запомнить сразу в переменной — не мог додуматься как это сделать. Ну и к тому же  на «Undo» только в меню в ленте видел и там же ей пользовался, и не думал что это тоже в макрос можно записать для решения подобных задач и будет работать… И про контроль событий даже в голову не приходило, что это можно (и нужно :) ) использовать в подобных случаях…
Ваши самокрутки очень пользительны и помогательны! :) Еще раз спасибо!!! Взял на заметку, в будущем думаю пригодится не раз. :idea:

.

Изменено: _Igor_6103.02.2022 15:44:02
(P.S. Не я не автор темы, но тема для меня актуальна оказалась :) )

 

Достаточно давно я описывал данный подход в статье:

Выделение сделанных изменений

только возвращал я свойство .Formula, т.к. это чуть более правильно в случаях, если изменения вносились в ячейку с формулой. Ну и еще парочка дополнений там есть, вроде возврата выделенных ячеек в исходное положение, т.к. после Undo выделенная область тоже может смениться.

Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы…

 

sokol92

Пользователь

Сообщений: 4445
Регистрация: 10.09.2017

Здравствуйте, коллеги!
C Undo надо быть поаккуратнее и уж тем более не вызывать два раза.
В исходном примере:
1. Заносим в A1 значение 1.
2. Возвращаемся в A1 и заносим 999 (например) и нажимаем Enter.  В сообщении об ошибке выбираем «Повторить», далее нажимаем Backspace и Enter.
Получаем сообщение о некорректном выполнении метода Undo (в макросах Михаила и Дмитрия).
Вывод: надо перехватывать возможную ошибку Undo.

Изменено: sokol9203.02.2022 17:55:42

 

sokol92, что-то у меня не получилось повторить. Сделал четко по озвученному алгоритму. Ни сообщения, ни ошибку не получил. Что делаю не так?

Изменено: Дмитрий(The_Prist) Щербаков03.02.2022 17:59:36

Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы…

 

sokol92

Пользователь

Сообщений: 4445
Регистрация: 10.09.2017

Дмитрий, не знаю — я раз 20 проверял. Важно нажимать именно Backspace, а не Del.
Естественно, я имел в виду пример #1 с добавленными макросами (Вашим или Михаила)

Изменено: sokol9203.02.2022 18:11:29

 

Дмитрий(The_Prist) Щербаков

Пользователь

Сообщений: 14182
Регистрация: 15.09.2012

Профессиональная разработка приложений для MS Office

#19

03.02.2022 18:16:56

Цитата
sokol92 написал:
имел в вмду пример #1

вот теперь понятно. Дело-то по сути в проверке данных и не Undo проблему создает, а проверка данных, т.к. Und-ить нечего :) Обойти-то можно и не так уж проблематично. Если чуть более умно, то так:

Код
Private Sub Worksheet_Change(ByVal Target As Range)
    'если изменили более одной ячейки - ничего не отслеживаем
    Dim lcnt As Long
    'игнорируем ошибки на случай, если выделено слишком много ячеек для помещения в Long
    On Error Resume Next
    lcnt = Target.Count
    If lcnt > 1 Then Exit Sub
    On Error GoTo 0
 
    Dim vOldVal, vNewVal, sSel As String
    With Application
        'отключаем отслеживание событий
        .EnableEvents = False
        .ScreenUpdating = False
        'запоминаем текущее выделение ячеек
        sSel = Selection.Address
        'запоминаем текущее значение
        vNewVal = Target.Formula
        'возвращаем предыдущее значение
        On Error Resume Next
        .Undo
        If Err.Description Like "*'Undo'*" Then
            GoTo END_
        End If
        'запоминаем предыдущее значение
        vOldVal = Target.Formula
        'возвращаем текущее значение
        Target.Formula = vNewVal
        'если значение/формула изменились окрашиваем в красный цвет
        If vOldVal <> vNewVal Then
            Target.Interior.Color = vbRed
        End If
        'возвращаем прежнее выделение ячеек
        Me.Range(sSel).Select
END_:
        'возвращаем отслеживание событий
        .EnableEvents = True
        .ScreenUpdating = True
    End With
End Sub

Но можно и при любой ошибке выход делать

Даже самый простой вопрос можно превратить в огромную проблему. Достаточно не уметь формулировать вопросы…

 

sokol92

Пользователь

Сообщений: 4445
Регистрация: 10.09.2017

#20

03.02.2022 18:22:34

Цитата
Дмитрий(The_Prist) Щербаков написал:
не Undo проблему создает, а проверка данных, т.к. Und-ить нечего

Да. Там событие изменения ячейки A1 вызывается дважды.
Я ранее сталкивался с подобными ситуациями и «на автомате» перехватываю возможные ошибки при выполнении Undo.

P.S. Ошибка исчезновения имени при цитировании не исправлена. Все время забываю нажимать на «BB code». :)

Изменено: sokol9203.02.2022 18:25:54

Владимир

 

БМВ

Модератор

Сообщений: 21378
Регистрация: 28.12.2016

Excel 2013, 2016

#21

03.02.2022 19:48:01

Цитата
sokol92 написал:
Ошибка исчезновения имени при цитировании не исправлена.

там тоже On Error Resume Next  :D

Спасибо за тест кейс.  ДА все верно, нужно обрабатывать ошибки подобные.  Я тут на досуге посмотрел вариант для подобного контроля в диапазоне на случай копирования диапазона. ну собственно идея то примитивная, но приходится сохранять адреса, ячеек измененных и их значение в массив а потом по нему  уже все тоже самое.

По вопросам из тем форума, личку не читаю.

Обычно при обновлении ячейки новым содержимым предыдущее значение будет закрыто, если не отменить операцию в Excel. Однако, если вы хотите сохранить предыдущее значение для сравнения с обновленным, сохранение предыдущего значения ячейки в другую ячейку или в комментарий к ячейке будет хорошим выбором. Метод, описанный в этой статье, поможет вам в этом.

Сохранить предыдущее значение ячейки с кодом VBA в Excel


Сохранить предыдущее значение ячейки с кодом VBA в Excel

Предположим, у вас есть таблица, как показано на скриншоте ниже. Если какая-либо ячейка в столбце C изменилась, вы хотите сохранить ее предыдущее значение в соответствующей ячейке столбца G или автоматически сохранить в комментарии. Для этого сделайте следующее.

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

2. В дебюте Microsoft Visual Basic для приложений Скопируйте приведенный ниже код VBA в окно кода.

Следующий код VBA помогает сохранить предыдущее значение ячейки указанного столбца в другой столбец.

Код VBA: сохранить предыдущее значение ячейки в другую ячейку столбца

Dim xRg As Range
Dim xChangeRg As Range
Dim xDependRg As Range
Dim xDic As New Dictionary
Private Sub Worksheet_Change(ByVal Target As Range)
    Dim I As Long
    Dim xCell As Range
    Dim xDCell As Range
    Dim xHeader As String
    Dim xCommText As String
    On Error Resume Next
    Application.ScreenUpdating = False
    Application.EnableEvents = False
    xHeader = "Previous value :"
    x = xDic.Keys
    For I = 0 To UBound(xDic.Keys)
        Set xCell = Range(xDic.Keys(I))
        Set xDCell = Cells(xCell.Row, 7)
        xDCell.Value = ""
        xDCell.Value = xDic.Items(I)
    Next
    Application.EnableEvents = True
    Application.ScreenUpdating = True
End Sub
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    Dim I, J As Long
    Dim xRgArea As Range
    On Error GoTo Label1
    If Target.Count > 1 Then Exit Sub
    Application.EnableEvents = False
    Set xDependRg = Target.Dependents
    If xDependRg Is Nothing Then GoTo Label1
    If Not xDependRg Is Nothing Then
        Set xDependRg = Intersect(xDependRg, Range("C:C"))
    End If
Label1:
    Set xRg = Intersect(Target, Range("C:C"))
    If (Not xRg Is Nothing) And (Not xDependRg Is Nothing) Then
        Set xChangeRg = Union(xRg, xDependRg)
    ElseIf (xRg Is Nothing) And (Not xDependRg Is Nothing) Then
        Set xChangeRg = xDependRg
    ElseIf (Not xRg Is Nothing) And (xDependRg Is Nothing) Then
        Set xChangeRg = xRg
    Else
        Application.EnableEvents = True
        Exit Sub
    End If
    xDic.RemoveAll
    For I = 1 To xChangeRg.Areas.Count
        Set xRgArea = xChangeRg.Areas(I)
        For J = 1 To xRgArea.Count
            xDic.Add xRgArea(J).Address, xRgArea(J).Formula
        Next
    Next
    Set xChangeRg = Nothing
    Set xRg = Nothing
    Set xDependRg = Nothing
    Application.EnableEvents = True
End Sub

Чтобы сохранить предыдущее значение ячейки в комментарии, примените приведенный ниже код VBA.

Код VBA: сохранить предыдущее значение ячейки в комментарии

Dim xRg As Range
Dim xChangeRg As Range
Dim xDependRg As Range
Dim xDic As New Dictionary
Private Sub Worksheet_Change(ByVal Target As Range)
    Dim I As Long
    Dim xCell As Range
    Dim xHeader As String
    Dim xCommText As String
    On Error Resume Next
    Application.ScreenUpdating = False
    Application.EnableEvents = False
    xHeader = "Previous value :"
    For I = 0 To UBound(xDic.Keys)
        Set xCell = Range(xDic.Keys(I))
        If Not xCell.Comment Is Nothing Then xCell.Comment.Delete
        With xCell
            .AddComment
            .Comment.Visible = False
            .Comment.Text xHeader & vbCrLf & xDic.Items(I)
        End With
    Next
    Application.EnableEvents = True
    Application.ScreenUpdating = True
End Sub
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    Dim I, J As Long
    Dim xRgArea As Range
    On Error GoTo Label1
    If Target.Count > 1 Then Exit Sub
    Application.EnableEvents = False
    Set xDependRg = Target.Dependents
    If xDependRg Is Nothing Then GoTo Label1
    If Not xDependRg Is Nothing Then
        Set xDependRg = Intersect(xDependRg, Range("C:C"))
    End If
Label1:
    Set xRg = Intersect(Target, Range("C:C"))
    If (Not xRg Is Nothing) And (Not xDependRg Is Nothing) Then
        Set xChangeRg = Union(xRg, xDependRg)
    ElseIf (xRg Is Nothing) And (Not xDependRg Is Nothing) Then
        Set xChangeRg = xDependRg
    ElseIf (Not xRg Is Nothing) And (xDependRg Is Nothing) Then
        Set xChangeRg = xRg
    Else
        Application.EnableEvents = True
        Exit Sub
    End If
    xDic.RemoveAll
    For I = 1 To xChangeRg.Areas.Count
        Set xRgArea = xChangeRg.Areas(I)
        For J = 1 To xRgArea.Count
            xDic.Add xRgArea(J).Address, xRgArea(J).Text
        Next
    Next
    Set xChangeRg = Nothing
    Set xRg = Nothing
    Set xDependRg = Nothing
    Application.EnableEvents = True
End Sub

Внимание: В коде цифра 7 указывает столбец G, в который вы сохраните предыдущую ячейку, а C: C — столбец, в котором вы сохраните предыдущее значение ячейки. Пожалуйста, измените их в соответствии с вашими потребностями.

3. Нажмите Tools
> Рекомендации для открытия Ссылки — VBAProject диалоговое окно, проверьте Среда выполнения сценариев Microsoft поле и, наконец, щелкните OK кнопка. Смотрите скриншот:

4. нажмите другой + Q ключи, чтобы закрыть Microsoft Visual Basic для приложений окно.

С этого момента, когда значение ячейки в столбце C обновляется, предыдущее значение ячейки будет сохранено в соответствующие ячейки в столбце G или будет сохранено в комментариях, как показано на скриншотах ниже.

Сохраните предыдущие значения ячеек в других ячейках:

Сохраните предыдущие значения ячеек в комментариях:


Лучшие инструменты для работы в офисе

Kutools for Excel Решит большинство ваших проблем и повысит вашу производительность на 80%

  • Снова использовать: Быстро вставить сложные формулы, диаграммы и все, что вы использовали раньше; Зашифровать ячейки с паролем; Создать список рассылки и отправлять электронные письма …
  • Бар Супер Формулы (легко редактировать несколько строк текста и формул); Макет для чтения (легко читать и редактировать большое количество ячеек); Вставить в отфильтрованный диапазон
  • Объединить ячейки / строки / столбцы без потери данных; Разделить содержимое ячеек; Объединить повторяющиеся строки / столбцы… Предотвращение дублирования ячеек; Сравнить диапазоны
  • Выберите Дубликат или Уникальный Ряды; Выбрать пустые строки (все ячейки пустые); Супер находка и нечеткая находка во многих рабочих тетрадях; Случайный выбор …
  • Точная копия Несколько ячеек без изменения ссылки на формулу; Автоматическое создание ссылок на несколько листов; Вставить пули, Флажки и многое другое …
  • Извлечь текст, Добавить текст, Удалить по позиции, Удалить пробел; Создание и печать промежуточных итогов по страницам; Преобразование содержимого ячеек в комментарии
  • Суперфильтр (сохранять и применять схемы фильтров к другим листам); Расширенная сортировка по месяцам / неделям / дням, периодичности и др .; Специальный фильтр жирным, курсивом …
  • Комбинируйте книги и рабочие листы; Объединить таблицы на основе ключевых столбцов; Разделить данные на несколько листов; Пакетное преобразование xls, xlsx и PDF
  • Более 300 мощных функций. Поддерживает Office/Excel 2007-2021 и 365. Поддерживает все языки. Простое развертывание на вашем предприятии или в организации. Полнофункциональная 30-дневная бесплатная пробная версия. 60-дневная гарантия возврата денег.

вкладка kte 201905


Вкладка Office: интерфейс с вкладками в Office и упрощение работы

  • Включение редактирования и чтения с вкладками в Word, Excel, PowerPoint, Издатель, доступ, Visio и проект.
  • Открывайте и создавайте несколько документов на новых вкладках одного окна, а не в новых окнах.
  • Повышает вашу продуктивность на 50% и сокращает количество щелчков мышью на сотни каждый день!

офисный дно

Комментарии (20)


Оценок пока нет. Оцените первым!

Мне понадобилась эта функция, и мне не нравились все вышеприведенные решения после большинства попыток, поскольку они либо

  • Медленный
  • Имеют сложные последствия, например, применение application.undo.
  • Не снимать, если они не были выбраны.
  • Не фиксирует значения, если они не были изменены до
  • Слишком сложно

Ну, я очень об этом думал, и я закончил решение для полной истории UNDO, REDO.

Чтобы записать старое значение, на самом деле это очень просто и очень быстро.

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

Чтобы записать все значения, я использовал эту простую команду

SheetStore = sh.UsedRange.Formula

Да, просто это, На самом деле excel вернет массив, если диапазон — это несколько ячеек, поэтому нам не нужно использовать команду FOR EACH, и это очень быстро

Следующий подраздел — это полный код, который должен вызываться в Workbook_SheetActivate. Для сбора изменений необходимо создать другой элемент. Например, у меня есть sub под названием «catchChanges», который работает на Workbook_SheetChange. Он зафиксирует изменения, а затем сохранит их на другом листе истории изменений. затем запускает UpdateCache для обновления кэша новыми значениями

' should be added at the top of the module
Private SheetStore() As Variant 
Private SheetStoreName As String  ' I use this variable to make sure that the changes I captures are in the same active sheet to prevent overwrite

Sub UpdateCache(sh As Object)
      If sh.Name = ActiveSheet.Name Then ' update values only if the changed values are in the activesheet
          SheetStoreName = sh.Name
          ReDim SheetStore(1 To sh.UsedRange.Rows.count, 1 To sh.UsedRange.Columns.count) ' update the dimension of the array to match used range
          SheetStore = sh.UsedRange.Formula
      End If
End Sub

теперь, чтобы получить старое значение, это очень просто, так как массив имеет одинаковый адрес ячеек

если мы хотим использовать ячейку D12, мы можем использовать следующие

SheetStore(row_number,column_number)
'example
return = SheetStore(12,4)
' or the following showing how I used it. 
set cell = activecell ' the cell that we want to find the old value for
newValue = cell.value ' you can ignore this line, it is just a demonstration
oldValue = SheetStore(cell.Row, cell.Column)

это фрагмент, объясняющий метод, я надеюсь, что всем это нравится

Hello,

I have a column (A) with eight different text drop down options.  I need a code that will allow me to track each time the drop down is changed to a different option. I want each change to be tracked in a different cell so that I can see how each line has progressed — e.g. from Received to Query to Invalid etc.

I have the following code which works to remember the last value of the cell from column A, but I cannot figure out how to make it work for my needs:

Private Sub Worksheet_Change(ByVal Target As Range)
Dim I As Long
Dim xCell As Range
Dim xDCell As Range
Dim xHeader As String
Dim xCommText As String
On Error Resume Next
Application.ScreenUpdating = False
Application.EnableEvents = False
xHeader = «Previous value :»
x = xDic.Keys
For I = 0 To UBound(xDic.Keys)
Set xCell = Range(xDic.Keys(I))
Set xDCell = Cells(xCell.Row, 49)
xDCell.Value = «»
xDCell.Value = xDic.Items(I)
Next
Application.EnableEvents = True
Application.ScreenUpdating = True
End Sub
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim I, J As Long
Dim xRgArea As Range
On Error GoTo Label1
If Target.Count > 1 Then Exit Sub
Application.EnableEvents = False
Set xDependRg = Target.Dependents
If xDependRg Is Nothing Then GoTo Label1
If Not xDependRg Is Nothing Then
Set xDependRg = Intersect(xDependRg, Range(«A:A»))
End If
Label1:
Set xRg = Intersect(Target, Range(«A:A»))
If (Not xRg Is Nothing) And (Not xDependRg Is Nothing) Then
Set xChangeRg = Union(xRg, xDependRg)
ElseIf (xRg Is Nothing) And (Not xDependRg Is Nothing) Then
Set xChangeRg = xDependRg
ElseIf (Not xRg Is Nothing) And (xDependRg Is Nothing) Then
Set xChangeRg = xRg
Else
Application.EnableEvents = True
Exit Sub
End If
xDic.RemoveAll
For I = 1 To xChangeRg.Areas.Count
Set xRgArea = xChangeRg.Areas(I)
For J = 1 To xRgArea.Count
xDic.Add xRgArea(J).Address, xRgArea(J).Formula
Next
Next
Set xChangeRg = Nothing
Set xRg = Nothing
Set xDependRg = Nothing
Application.EnableEvents = True
End Sub

Essentially, I want every change made in column A tracked in column AW, AX, AY and so on.  There will be no more than 10 changes to an individual cell in column A.

Thanks.

Понравилась статья? Поделить с друзьями:
  • Vba excel правый символ
  • Vba excel пошаговое выполнение макроса
  • Vba excel посчитать непустые ячейки
  • Vba excel получить путь к папке
  • Vba excel посчитать количество строк в таблице excel