2013-04-10 105 views
8

我正在構建一個處理多個單元格值的VSTO Excel加載項。我希望允許用戶通過標準Excel功能撤銷和重做由加載項創建的更改。我寧願避免使用VBA。如何將操作推送到Excel撤消堆棧?

這可能嗎?如果是這樣,怎麼樣?

另一個問題:是否有可能檢查現有的撤消/重做堆棧?

回答

-3

其實我跟去的解決方案是以下幾點:

  • 保存分隔剪貼板狀態
  • 清除剪貼板
  • 產生一個標籤/換行我想要的數據的一個副本格式,將其推送到剪貼板
  • 模擬Ctrl + V操作到Excel
  • 清除剪貼板
  • 恢復原來的狀態剪貼板

顯然,這是定位在細胞操作,所以你不能把任意操作/回調撤消堆棧。另外,我顯然違反了Windows中剪貼板使用的原則,但是如果微軟公開了更好的API來處理這些事情(提示),我不必這樣做。

此外,我沒有跟我對大衛Zemens的回答第一個註釋說明,因爲我擊出了一些安全違規在我們的環境的解決方案去(即注入VBA代碼到一個工作簿是一個禁忌)。

反正,謝謝大家!

+0

劫持剪貼板是不可行的,因爲你可能會覆蓋用戶的內容,如果你這樣做,他們會非常生氣。 – 2016-09-14 17:21:14

0

您可以通過使用添加到堆棧操作:

Application.OnUndo text, procedureName 

文本是與撤消命令(編輯菜單)出現在文本和過程名是你的潛艇之一的名稱。您也可以通過編程方式使用撤消操作:

Application.Undo 

我不認爲這是可以訪問現有的撤銷操作;至少我從來沒有聽說過任何。可能有一個圖書館,你可以在線訪問,將允許這一點。

希望這會有所幫助。

+0

......這意味着我需要使用VBA? – 2013-04-17 00:52:57

+1

'Application.OnUndo'缺少必需的參數... – 2013-04-24 05:06:30

4

你沒有提到你希望使用的Excel中/ .NET/VSTO運行庫的版本,但它並不真正的問題:]
自定義撤消只是不能在沒有注射VBA,在那裏你將需要設置完成撤銷回滾動作的方法,使用補償(即反向操作)或恢復保存的狀態。

3

我知道你想避免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 
+0

我可以使用某種唯一的ID從C#中生成並注入VBA,將ID存儲在我的應用程序中,並映射到狀態轉換,並讓子組本身就是一個C#的回調,當調用時,反轉變換? – 2013-04-26 02:44:02

+0

呃,無法編輯我的評論...像這樣的http://stackoverflow.com/questions/15196534/is-there-a-way-to-add-vba-macro-code-to-excel與這http://msdn.microsoft.com/en-us/library/vstudio/bb608614(v=vs.100).aspx也許? – 2013-04-26 02:54:25

+0

這裏有一種不在我的元素,但撇開那些似乎可能結合這些方法。最終,您需要反轉程序,或將受影響數據的副本存儲在內存中,並在「撤銷」調用中恢復到該狀態。似乎任何一個都可以在C#中完成 - 但是將它們綁定到Excel的標準接口(例如,用於撤銷的Ctrl + Z'hotkey等)需要一些代碼注入 - 即使它只是一個VBA調用例程來調用外部對象(C#)執行「撤消」。 – 2013-04-26 03:17:06