Excel VBA: SendKeys не удается на некоторых компьютерах

Я работаю над листом excel, где каждая строка должна указывать последний раз, когда какая-либо ячейка в этой строке изменилась. Самый простой метод, который я нашел для этого, - это поместить небольшое количество VBA в код листа, например:

Private Sub Worksheet_Change(ByVal Target As Range)
    Application.EnableEvents = False
    If (Target.Row > 2) And (Cells(Target.Row, "A") <> "") Then
        Cells(Target.Row, "N").Value = Date
    End If
    Application.EnableEvents = True
End Sub

это эффективно изменит дату в столбце " N " при редактировании любого другого элемента в этой строке. Здорово! За исключением одного...

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

Итак, альтернатива этому-обмануть excel, думая, что я не редактировал ячейку. Этот код сохраняет стек отмены при изменении даты:

Private Sub Worksheet_Change(ByVal Target As Range)
    Dim cursorLocation As Range
    Application.EnableEvents = False
    If Target.Row > 2 And Cells(Target.Row, "A") <> "" Then
        Set cursorLocation = ActiveCell
        Cells(Target.Row, "N").Select
        SendKeys "^;~", True
        cursorLocation.Select
    End If
    Application.EnableEvents = True
End Sub

в этом случае мы выбираем ячейку, используем SendKeys для фальшивого редактирования ячейки и восстанавливаем курсор в исходное положение. "^ ; ~ "использует сочетание клавиш "Ctrl+;" Excel для ввода даты. Здорово! За исключением одного...

этот код отлично работает на моей машине (Win7, Excel 2010), но не работает на машине коллеги (Win8, Excel 2010, возможно, немного быстрее). На машине Win8 (не знаю, если проблема в ОС, кстати), что происходит, когда ячейка изменяется, каждая ячейка непосредственно под этой ячейкой становится текущей датой, и, конечно, сохранение истории отмены бессмысленно, потому что выполнение отмены немедленно активирует код рабочего листа и превращает все в даты снова.

Я сам понял, что то же самое произойдет на моей машине, если я удалю "Wait", присущую команде SendKeys. То есть, если я использую строку:

SendKeys "^;~", False

Итак, я предполагаю, что по какой-то причине, даже при использовании той же версии Excel, мой компьютер ждет завершения команды SendKeys, но компьютер моего коллеги-нет. Есть идеи?

1 ответов


вы правы. Это дает эту проблему в Excel 2010 / Win8.

попробуйте это. Используйте пользовательский Wait код, который я написал. (Проверено в Excel 2010 / Win8)

Private Sub Worksheet_Change(ByVal Target As Range)
    Dim cursorLocation As Range
    Application.EnableEvents = False
    If Target.Row > 2 And Cells(Target.Row, "A") <> "" Then
        Set cursorLocation = ActiveCell
        Cells(Target.Row, "N").Select
        SendKeys "^;~"
        Wait 1 '<~~ Wait for 1 Second
        cursorLocation.Select
    End If
    Application.EnableEvents = True
End Sub

Private Sub Wait(ByVal nSec As Long)
    nSec = nSec + Timer
    While nSec > Timer
        DoEvents
    Wend
End Sub

enter image description here

альтернатива

используя Doevents также имеет желаемый эффект.

Private Sub Worksheet_Change(ByVal Target As Range)
    Dim cursorLocation As Range
    Application.EnableEvents = False
    If Target.Row > 2 And Cells(Target.Row, "A") <> "" Then
        Set cursorLocation = ActiveCell
        Cells(Target.Row, "N").Select
        SendKeys "^;~"
        DoEvents
        cursorLocation.Select
    End If
    Application.EnableEvents = True
End Sub