keycode и vbKeyDelete

Программирование на Visual Basic for Applications
playa
Начинающий
Начинающий
 
Сообщения: 10
Зарегистрирован: 18.02.2008 (Пн) 0:37

keycode и vbKeyDelete

Сообщение playa » 19.03.2008 (Ср) 12:07

Доброго времени суток.

Задача проста: нужно перехватить нажатие клавиши Delete и, если значение ячейки было не пустым, выполнить определенный код.

Мои действия:

Private Sub Worksheet_Change(ByVal Target As Range)
If keycode = vbKeyDelete Then
If IsEmpty(ActiveCell.Value) Then
Else
del
End If
End If
End Sub

Столкнулся с несколькими сложностями: ни в какую не хочет работать выражение "keycode = vbKeyDelete". Пробовал и такое: "keycode = 46". В чем может быть ошибка?
Вторая сложность: Worksheet_Change - выполнение кода происходит уже ПОСЛЕ удаления данных из ячейки, т.е. IsEmpty(ActiveCell.Value) будет всегда равно TRUE, а это УЖЕ неправильно. Я пробовал этот код ставить в Worksheet_SelectionChange, но там перехват Delete не происходит вообще. Как варианты решения я вижу дублирование значения активной ячейки в "переменную" ячейку, и уж потом при нажатии клавиши Delete проверять наличие в ней данных, но этот вариант мне кажется очень "топорным".
Хотелось бы услышать ваши идеи по этому вопросу. Заранее благодарен.

alibek
Большой Человек
Большой Человек
 
Сообщения: 14205
Зарегистрирован: 19.04.2002 (Пт) 11:40
Откуда: Russia

Сообщение alibek » 19.03.2008 (Ср) 12:22

Не надо бездумно копировать код, работу которого ты не понимаешь.
Используемый код предназначен для события KeyDown.
Для листов Excel такого события нет. И вообще ты не сможешь определить код нажатой клавиши стандартными способами.
Проверяй просто на IsNull(Target.Value).
Lasciate ogni speranza, voi ch'entrate.

playa
Начинающий
Начинающий
 
Сообщения: 10
Зарегистрирован: 18.02.2008 (Пн) 0:37

Сообщение playa » 19.03.2008 (Ср) 12:40

т.е. все равно получится танец с бубном: определять значение ячейки до изменения и после?

playa
Начинающий
Начинающий
 
Сообщения: 10
Зарегистрирован: 18.02.2008 (Пн) 0:37

Сообщение playa » 19.03.2008 (Ср) 13:49

в общем, пока сделал так:

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
ActiveSheet.Cells(1, 1).Value = Target.Value ' во временную ячейку занос. значение текущей ячейки
End Sub

Private Sub Worksheet_Change(ByVal Target As Range)
If IsEmpty(ActiveSheet.Cells(1, 1)) Then
Else
If IsEmpty(Target.Value) Then ' проверка было ли удалено значение
del
End If
End If
End Sub

Возможно, коряво в плане исполнения, но зато работает. Если есть другой выход, подскажите, пожалуйста.

Димитрий
Продвинутый пользователь
Продвинутый пользователь
 
Сообщения: 194
Зарегистрирован: 26.01.2005 (Ср) 22:47
Откуда: Волгоград

Сообщение Димитрий » 19.03.2008 (Ср) 18:01

Можно использовать Application.OnKey "{Delete}", "del"
Не полностью описана цель.

KVG
Начинающий
Начинающий
 
Сообщения: 8
Зарегистрирован: 22.04.2005 (Пт) 5:57

Сообщение KVG » 20.03.2008 (Чт) 14:05

Возможно, подобный "перехват" будет более гарантированным - не надеясь на то какие события нам предоставляет VBA_Excel, можно взять необходимое событие встроенными в ОС средствами установки локальных ловушек:
Код: Выделить всё
ghHook = SetWindowsHookEx(WH_KEYBOARD, AddressOf KeyboardProc, 0&, IdThread)

ghHook это дескриптор текущей ловушки (его потом в CallNextHookEx прийдёться передать). IdThread = GetCurrentThreadId это нужно сделать при установке ловушки. Момент установки и последующего снятия (при закрытии файла, например) ловушки необходимо определять самостоятельно. А внутри функции KeyboardProc можно выполнить нужную Вам проверку.
Код: Выделить всё
Public s As String
Function KeyboardProc(ByVal ncode As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    If ncode < 0 Then   'обязательно для  ncode < 0
        KeyboardProc = CallNextHookEx(ghHook, ncode, wParam, lParam)
        Exit Function
    End If
Select Case ncode
    Case HC_ACTION
        '******************************
        If wParam = 46 Then
            s = CStr(ActiveCell.Value)
            Application.ActiveWorkbook.ActiveSheet.Range("A1").Value = s
            'конечно, копируйте это куда хотите...
            s = ""
        End If
        '******************************
End Select
    'передача сообщений по цепочке ловушек
    KeyboardProc = CallNextHookEx(ghHook, ncode, wParam, lParam)
End Function

Конечно, кода прийдётся написать ещё в 3-4 раза больше представленного, зато такая конструкция универсальна и для др. типов ловушек. Работоспособность проверил... Конечно, если VBA всё таки предоставляет гарантированную возможность поймать событие WH_KEYBOARD (со всеми нюансами объектной модели VBA знаком не достаточно хорошо), то представленный способ будет "извращением"... но по-моему это всё-таки полезная штука.


Вернуться в VBA

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 79

    TopList