如何将操作推送到Excel撤消堆栈?

时间:2013-04-10 15:03:45

标签: c# excel vsto

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

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

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

4 个答案:

答案 0 :(得分:5)

您没有提到您希望使用哪个版本的Excel / .NET / VSTO运行时,但这并不重要:]

如果没有注入VBA,就无法完成自定义撤消,您需要设置撤消方法以回滚您的操作,使用补偿(即反向操作)或恢复已保存的状态。

答案 1 :(得分: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

答案 2 :(得分:0)

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

Application.OnUndo text, procedureName

文字是与撤消命令(编辑菜单)一起显示的文字, procedureName 是您的某个潜点名称。您还可以使用以下命令以编程方式撤消操作:

Application.Undo

我认为不可能访问现有的撤消操作;至少我从来没有听说过。您可以在线访问可以访问的库。

希望这有帮助。

答案 3 :(得分:-2)

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

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

显然,这是本地化的单元操作,因此您无法将任意操作/回调推送到撤消堆栈。另外,我明显违反了Windows中剪贴板使用的原则,但如果微软为这些事情公开了更好的API(提示),我就不必这么做了。

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

无论如何,谢谢大家!

相关问题