10

我正在构建一个操作多个单元格值的 VSTO Excel 加载项。我想允许用户通过标准 Excel 功能撤消和重做由加载项创建的更改。我宁愿避免使用 VBA。

这可能吗?如果是这样,怎么做?

另一个问题:是否可以检查现有的撤消/重做堆栈?

4

4 回答 4

5

您没有提及您希望使用哪个版本的 Excel/.NET/VSTO 运行时,但这并不重要:]
如果不注入 VBA,就无法完成自定义撤消,您需要设置一个撤消方法来回滚您的操作,通过使用补偿(即反向操作)或通过恢复保存的状态。

于 2013-04-22T22:14:57.820 回答
4

我知道您想避免使用 VBA,但正如其他人所提到的,这实际上是不可能获得Undo.

这是一个 VBA 示例,它将现有选择保留为自定义数据类型,以便以后可以撤消。

Option Explicit
'Stores info about current selection'
Public OldWorkbook As Workbook
Public OldSheet As Worksheet
Public OldSelection() As SaveRange

'Custom data type for undoing'
Type SaveRange
    Value As Variant
    Address As String
End Type

Public Sub YourSubRoutine()
    'A simple subroutine that acts on a Range selection'
    Dim UserRange As Range

    Set UserRange = Selection


    If UserRange Is Nothing Then
        Exit Sub
    End If

'## The next block of statements '
'## Save the current values for undoing '
    Set OldWorkbook = ActiveWorkbook
    Set OldSheet = ActiveSheet

    Application.ScreenUpdating = False

    '## Code to manipulate the Selection range '
    '## Code to manipulate the Selection range '
    '## Code to manipulate the Selection range '

    '## Specify the Undo Sub '
    Application.OnUndo "Undo the YourSubRoutine macro", "UndoYourSubRoutine"

End Sub
Public Sub UndoYourSubRoutine()

Dim i As Integer

'   Undoes the effect of the YourSubRoutine '

'   Tell user if a problem occurs '
    On Error GoTo Problem

    Application.ScreenUpdating = False

'##  Make sure the correct workbook and sheet are active '
    OldWorkbook.Activate
    OldSheet.Activate

'## Restore the saved information '
    For i = 1 To UBound(OldSelection)
        Range(OldSelection(i).Address).Value = OldSelection(i).Value
    Next i
    Exit Sub

'   Error handler'
Problem:
    MsgBox "Can't undo"

End Sub
于 2013-04-24T03:24:23.893 回答
0

您可以使用以下方法将操作添加到堆栈:

Application.OnUndo text, procedureName

其中Text是与 Undo 命令(编辑菜单)一起出现的文本,procedureName是您的一个潜艇的名称。您还可以使用以下方式以编程方式撤消操作:

Application.Undo

我认为不可能访问现有的撤消操作;至少我从来没有听说过。可能有一个您可以在线访问的图书馆允许这样做。

希望这可以帮助。

于 2013-04-11T19:26:53.930 回答
-1

我实际使用的解决方案如下:

  • 保存剪贴板状态的副本
  • 清除剪贴板
  • 以制表符/换行符分隔的格式生成我想要的数据,将其推送到剪贴板
  • 模拟 Ctrl+V 操作到 Excel
  • 清除剪贴板
  • 恢复原始剪贴板状态

显然,这仅限于单元格操作,因此您不能将任意操作/回调推送到撤消堆栈。此外,我显然违反了在 Windows 中使用剪贴板的原则,但如果 Microsoft 为此类事情公开了更好的 API(提示),我就不必这样做了。

此外,我没有采用我在对 David Zemens 的回答的第一条评论中描述的解决方案,因为我在我们的环境中遇到了一些安全违规行为(即,将 VBA 代码注入工作簿是禁止的)。

不管怎样,谢谢大家!

于 2013-06-04T14:28:30.313 回答