我正在构建一个VSTO Excel插件,用于操作多个单元格的值。我希望通过标准的Excel功能,允许用户撤销和重做插件所创建的更改。我倾向于避免使用VBA。
这是否可能?如果是,怎么做?
另一个问题:是否可能检查现有的撤消/重做堆栈?
这是否可能?如果是,怎么做?
另一个问题:是否可能检查现有的撤消/重做堆栈?
我知道你想避免使用VBA,但正如其他人所提到的那样,这是不可能实现撤销功能的。
以下是一个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
您可以使用以下方法将操作添加到堆栈中:
Application.OnUndo text, procedureName
其中Text是撤销命令(编辑菜单)中显示的文本,procedureName是您其中一个子程序的名称。您还可以通过编程方式撤销操作,方法如下:
Application.Undo
我最终选择的解决方案如下:
显然,这仅适用于单元格操作,因此不能将任意操作/回调推送到撤消堆栈中。此外,我很明显违反了有关 Windows 剪贴板使用的原则,但如果 Microsoft 为这些事情公开了更好的 API(提示),我就不必这样做。
此外,我没有选择我在 David Zemens 的答案第一条评论中描述的解决方案,因为我在我们的环境中遇到了一些安全问题(即,在工作簿中注入 VBA 代码是不允许的)。
总之,感谢大家!
Ctrl+Z
快捷键进行撤消等)绑定需要一些代码注入--即使只是一个VBA子程序来调用外部对象(C#)执行“撤消”。 - David Zemens