【问题标题】:Use VBA in Excel 2013 to mimic moving using arrow keys在 Excel 2013 中使用 VBA 模拟使用箭头键移动
【发布时间】:2019-08-04 20:12:02
【问题描述】:

我想为 Excel 2013 创建一个 VBA 宏来移动光标。我只是重新映射键盘快捷键,例如我想使用 CTRL+J 而不是向下箭头来向下移动光标。所以我不需要任何花哨的东西,只需一个简单的光标移动。我也想在 VBA 中执行此操作,因此我不需要寻找 Excel 插件或加载项或类似的东西。

如果在“开发人员”选项卡下,我选择“使用相对引用”,然后简单地录制一个向下移动光标的宏,我会得到以下内容,确实移动光标:

ActiveCell.Offset(1, 0).Range("A1").Select

但是,这不是向下箭头的完全模仿。这个子程序/宏将移动到隐藏的行中,这是我不想要的。

以下每个都给我一个“对象不支持此属性或方法”错误:

Selection.MoveDown Unit:=xlCell, Count:=1, Extend:=xlMove
...
Selection.MoveDown Unit:=xlWorksheetCell, Count:=1, Extend:=xlMove
...
Selection.MoveDown xlCell, 1, xlMove
...
Selection.MoveDown xlWorksheetCell, 1, xlMove

以下给我一个语法错误:

Selection.MoveDown(xlWorksheetCell, 1, xlMove)

我可以想象一个适度的宏移动光标,检查新单元格是否被隐藏,如果是,重复直到它不是。但是,我很难相信没有一个命令/方法/等不能像箭头键那样简单轻松地模拟移动光标,忽略隐藏的行/列。例如,我可以在按住控制键的同时使用箭头键进行模仿,例如 Selection.End(xlDown).Select。所以我想尽可能简单地模拟用箭头键移动光标。

(这似乎是一个如此简单的问题,我猜有人曾经问过/回答过这个问题。但是,如果是这样,并且如果您将我的问题标记为重复,请指出原始答案在哪里,因为我已经看过但找不到它。)

【问题讨论】:

  • 记住触摸 DOWNARROW 只会将ActiveCell 向下移动,而不是全部Selection
  • 谢谢。我不需要从复杂的选择(例如几个选定的单元格)开始移动活动单元格。我假设我从一个选定的单元格开始,然后只是想模仿移动活动单元格,就好像我使用了箭头键一样。
  • 让我们看看 SendKeys
  • 在下面查看我的答案
  • 使用SendKeys 通常会受到警告,但肯定有它的应用程序。但是,更广泛地说,为什么您希望在快捷方式上更改单元格选择?更改选择后是否运行宏?这可能是XY Problem

标签: excel vba cursor selection


【解决方案1】:

不确定你真正想要的是什么,但是这个呢?

Option Explicit

Sub move_right()
NextVisible "Right"
End Sub

Sub move_left()
NextVisible "Left"
End Sub

Sub move_up()
NextVisible "Up"
End Sub

Sub move_down()
NextVisible "Down"
End Sub

Private Sub NextVisible(direction As String)
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Application.EnableEvents = False

Dim i As Long
Dim r As Range
Set r = ActiveCell
For i = 1 To Rows.Count
    On Error Resume Next 'If you're in A1 and try to go up one, it'll error. This skips that error.
    Select Case direction
        Case "Up"
            Set r = r.Offset(-1, 0)
        Case "Down"
            Set r = r.Offset(1, 0)
        Case "Left"
            Set r = r.Offset(0, -1)
        Case "Right"
            Set r = r.Offset(0, 1)
        Case Else
            Set r = r
    End Select
    On Error Goto 0

    If r.EntireRow.Hidden = False And r.EntireColumn.Hidden = False Then
        r.Select
        Exit Sub
    End If
Next i

Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
Application.EnableEvents = True
End Sub

然后,只需为每个人分配一个快捷方式...

因此,按 CTRL+I 会向上移动活动单元格。

【讨论】:

  • 问题是这些不会跳过不可见的行/列,这是 OP 所追求的。
  • @ScottCraner - 啊,哎呀。已编辑。
  • 这行得通。但是,如果我隐藏了 1000 行并且我现在正试图向下移动经过它们,那么我需要几乎整整 2 秒才能向下移动“一个”行。相比之下,我在另一个答案中发布的部分解决方案基本上会立即移过隐藏的行。
  • @AndrewWillems - 查看我的编辑。这从第 3 行开始,跳过了 2000 个隐藏行,然后在不到一秒的时间内选择了下一个单元格。
  • 再次,它有效。但是,它会减慢常规光标移动,即当隐藏行不成问题时。例如,正常的箭头键移动可以在 10 秒内向下移动 290 行,而使用此代码只能在 10 秒内向下移动 80 行。我不是在吹毛求疵:(1)我不断地移动光标,所以像这样的延迟会让我发疯。 (2)我发布的另一个解决方案似乎没有这个延迟。我认为它需要基于 VBA 的循环(与 Excel 代码本身中的本机循环相反,由 rng.SpecialCells... 之类的东西访问)这一事实使得它不太有用。
【解决方案2】:

最初是作为解决方案编写的,但后来我发现它也有问题。我会留下它,因为其他人已经发表了评论,但请注意它不是解决方案(至少不是目前的形式)。

我找到了另一个网站here,它回答了我的确切问题。以下是建议的解决方案:

Dim rng As Range
Set rng = Range( _
  Cells(ActiveCell.Row + 1, ActiveCell.Column), _
  Cells(Rows.Count, ActiveCell.Column) _
)
rng.SpecialCells(xlCellTypeVisible).Cells(1).Select

但是,经过仔细研究,这确实适用于向下移动,但适用于向上移动。具体来说,您可以向下移动越过隐藏行,但如果您尝试向上移动越过隐藏行,则向上移动会停止。

向上:

Dim rng As Range
Set rng = Range( _
  Cells(1, ActiveCell.Column), _
  Cells(ActiveCell.Row - 1, ActiveCell.Column) _
)
Dim rw As Long
rw = rng.SpecialCells(xlCellTypeVisible).Areas( _
    rng.SpecialCells(xlCellTypeVisible).Areas.Count _
    ).Row + rng.SpecialCells(xlCellTypeVisible).Areas( _
    rng.SpecialCells(xlCellTypeVisible).Areas.Count).Rows.Count - 1
rng.SpecialCells(xlCellTypeVisible).Cells(rw).Select

对:

Dim rng As Range
Set rng = Range( _
  Cells(ActiveCell.Row, ActiveCell.Column + 1), _
  Cells(ActiveCell.Row, Columns.Count) _
)
rng.SpecialCells(xlCellTypeVisible).Cells(1).Select

左:

Set rng = Range( _
  Cells(ActiveCell.Row, 1), _
  Cells(ActiveCell.Row, ActiveCell.Column - 1) _
)
Dim rw As Long
rw = rng.SpecialCells(xlCellTypeVisible).Areas( _
    rng.SpecialCells(xlCellTypeVisible).Areas.Count _
    ).Column + rng.SpecialCells(xlCellTypeVisible).Areas( _
    rng.SpecialCells(xlCellTypeVisible).Areas.Count).Columns.Count - 1
rng.SpecialCells(xlCellTypeVisible).Cells(rw).Select

我将继续努力,但因为这是我自己对自己问题的回答,如果其他人(比我更了解 VBA)想要采用此解决方案并在您的自己的答案,我完全祝福你这样做。

还要注意,即使对于成功的向下移动,如果行号大于 32766,此解决方案也会产生“溢出”错误。

【讨论】:

  • 我没有收到我用第 1048562 行测试过的溢出错误,它应该会向下移动。
  • 如果你遇到溢出,那是因为你是如何使用它的,这让我相信@BruceWaynes 的评论是正确的。
  • 溢出错误可能是由于我的确切设置,即在 Parallels Desktop 13 for Mac 上运行的 Windows 7 中使用 Excel 2013。但是,如果溢出错误是唯一的问题,我可能会使用它。但是,我最近对此解决方案的编辑讨论了此解决方案的其他更大(但可能可以解决?!)的问题。
  • 我有一个解决方案,我不想自己回答,因为它只是对您的补充,您介意我编辑并添加到您的吗?
  • Left 和 right 将分别只是对 up 和 down 的修改。
【解决方案3】:

将快捷键分配给:

Sub MoveDown()
    Application.SendKeys "{DOWN}"
End Sub

【讨论】:

  • 如果我将此宏分配给“CTRL+J”,现在这会将我的光标向下移动并根据需要跳过隐藏的行。但是,要让它第二次工作,我需要在再次按下 CTRL 和 J 键之前将手指从它们上移开,而不是让我继续按住 CTRL 键并重新按下 J 键。当我使用ActiveCell.Offset(1, 0).Range("A1").Select 时,它会移动光标但不恰当地移动到隐藏行中,正如我在问题中指出的那样,但至少它不需要我每次都取消按 CTRL 键。因此,我仍然希望有更好的解决方案。
  • 非常聪明的加里! :)
  • @AndrewWillems 按住 CTRL 键将不起作用。这是因为 Excel 需要不同的组合键来触发宏!!
  • 我很抱歉,但我不明白你的评论。当我的宏使用ActiveCell.Offset(1, 0).Range("A1").Select 时,我确实使用 CTRL+J 就好了,即我按一次 CTRL 键,按 J 十次,活动单元格将向下移动十次。除了忽略隐藏的行之外,我想重现对我的击键的响应。
  • @AndrewWillems 我没有解释清楚......我之前的评论涉及使用 CNTRL-j 触发我的宏............对不起
【解决方案4】:

要向下移动一个单元格,前提是在隐藏行的位置没有应用过滤器。

Selection.End(xlDown).Select
Selection.End(xlUp).Offset(1).Select

【讨论】:

    猜你喜欢
    • 2019-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-11
    • 2013-10-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多