本帖最后由 iCells 于 2022-10-1 23:28 编辑
在VBA环境下,运行VBA代码后,Excel的撤销按钮是灰色的,这意味着VBA代码导致工作表、工作簿的改变是无法撤销的,其实VBA内置了一个Application.OnUndo 方法 ,能够在运行代码后实现撤销功能,但是具体的撤销过程需要自行实现。
OnUndo(Text,Procedure) 方法有两个参数,第一个是撤销按钮显示是文字信息,第二个是撤销命令具体的过程名称,其实就是在模块中函数的名称。第二个参数通过特殊的构造,可以实现传递参数效果,具体实现过程如下图:
由于OnUndo方法的第二个参数是模块中函数名称,在VBA中较容易可以实现,那如何在VSTO中实现。想解决这个问题,核心在于如何把撤销代码放入VBA工程,以及如何在VSTO中调用VBA工程模块中的代码。
一、新建一个Excel外接程序
然后在VSTO的debug目录建立一个xlam格式的加载宏,命名为iCells_Undo.xlam,如图:
在加载宏中的模块中,写入撤销的代码: - <font face="微软雅黑" size="4">Sub undo(str As String)
- ActiveSheet.Range("a1").Value = str
- End Sub</font>
复制代码
如图:
二、在VSTO项目中的ThisAddIn中加入以下代码:
- <font face="微软雅黑" size="4">Private xlam As Object = Nothing
- Private Sub ThisAddIn_Startup() Handles Me.Startup
- Dim strPath As String = System.AppDomain.CurrentDomain.BaseDirectory
- Dim strXlam As String = System.IO.Path.Combine(strPath, "iCells_Undo.xlam")
- If IO.File.Exists(strXlam) Then
- xlam = Globals.ThisAddIn.Application.Workbooks.Open(strXlam)
- Else
- xlam = Nothing
- End If
- End Sub
- Private Sub ThisAddIn_Shutdown() Handles Me.Shutdown
- Try
- If xlam IsNot Nothing Then
- xlam.close(False)
- End If
- Catch ex As Exception
- End Try
- End Sub</font>
复制代码
以上代码作用是在加载项开始的时候,就打开iCells_Undo.xlam,打开iCells_Undo.xlam的目的在于之后需要在加载宏中存放撤销的代码,并且调用。
三、在VSTO中添加一个Button,命名Button1,为这个Button添加事件:
- <font face="微软雅黑" size="4">Private Sub Button1_Click(sender As Object, e As RibbonControlEventArgs) Handles Button1.Click
- Dim str As String = Nothing
- Dim ExcelApp As Excel.Application = Globals.ThisAddIn.Application
- str = ExcelApp.ActiveSheet.Range("a1").Value
- ExcelApp.ActiveSheet.Range("a1").Value = "iCells"
- ExcelApp.OnUndo("撤销A1单元格赋值", "'undo" & """" & str & """" & "'")
- End Sub</font>
复制代码
最后,运行项目就可以实现撤销功能,但是如果每一个撤销过程如果都放入到iCells_Undo.xlam加载项中,已然失去了VSTO的优势,第二篇分享如何把具体的撤销过程放到VSTO项目中。 |