При създаването на макроси които да следят промяната на клетки често се налага да се извършват обработки с участието на данните в клетката преди тя да бъде променена. Проблемът тук е, че събитието Worksheet_change носи само информация за новата стойност! Т.е. нямаме две събития ПРЕДИ и СЛЕД промяната, а само едно събитие. Това налага правенето на различни трикове. Един от тези трикове е в момента на избор на клетка (събитието SelectionChange) да се запомнят данните в променлива или скрит работен лист.
В примера ще използвам факта че старата стойност се пази от самия Excel и може да бъде възстановена с помощта на UnDo! Тук има един гоооолям камък (не бих го нарекъл подводен). Проблемът произтича от факта, че Undo и промяната се извършва в събитие и имаме голяма опасност да се зациклим. Трябва да забраним генерирането на събития при извършване на манипулацията.
Ето едно забавно (и не много смислено;) примерче за по-лесно разбиране на решението:
Условие: Да се направи област, в която при въвеждане да не се изтрива старата стойност ами да се създава списък разделен със запетайка.Потребителя въвежда нова стойност и тя се "долепя" към текущите стойности.
Решение: Заставате върху името на листа. Десен бутон. View Code и копирате в редактора следния код:
'---------------------------------------- Начало
Private Sub Worksheet_Change(ByVal Target As Range)
Dim r As Range
Dim oldvalue, newvalue
' Зоната която се наблюдава в примера (променете за вашия случай!)
'------
Set r = Range("A1:A100")
'-----
' Изход ако се променят повече от една клетка
Dim r As Range
Dim oldvalue, newvalue
' Зоната която се наблюдава в примера (променете за вашия случай!)
'------
Set r = Range("A1:A100")
'-----
' Изход ако се променят повече от една клетка
' или клетката не е в наблюдаваната зона
If Target.Cells.Count > 1 Or Intersect(r, Target) Is Nothing Then Exit Sub
If Target.Cells.Count > 1 Or Intersect(r, Target) Is Nothing Then Exit Sub
'Изход ако се изтрива клетка
If IsEmpty(Target) Then Exit Sub
' Изключване на събитията (така се предпазваме от зацикляне!)
Application.EnableEvents = False
'Вземаме текущата стойност
newvalue = Target.Value
newvalue = Target.Value
'Връщаме старата стойност чрез Undo
Application.Undo
oldvalue = Target.Value
'Създаване на новата стойност
Application.Undo
oldvalue = Target.Value
'Създаване на новата стойност
'(променете според вашите изисквания)
'-----
'-----
'Ако клетката е била празна
If IsEmpty(oldvalue) Then
Target.Value = newvalue
Else ' Ако клетката не е била празна долепяме новата стойност с запетайка
Target.Value = oldvalue & "," & newvalue
End If
'-----
' Възстановяване обработката на събития
Application.EnableEvents = True
End Sub
' ----------------------------- Край
Забележка: Опитайте да въвеждате стойности в зоната A1:A100. Когато въведете стойност в клетка в която вече има въведени данни те се запазват! Както казах примерът е по-скоро илюстративен, но може да ви послужи:) Според вашите нужди променяте редовете които са заградени с "-".
Успех
Няма коментари:
Публикуване на коментар