ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 效率神器,一键搞定繁琐工作
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
让更多数据处理,一键完成 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
查看: 973|回复: 4

[原创] 在VSTO项目中使用Excel的撤销功能(一)

[复制链接]

TA的精华主题

TA的得分主题

发表于 2022-10-1 17:41 | 显示全部楼层 |阅读模式
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
本帖最后由 iCells 于 2022-10-1 23:28 编辑

在VBA环境下,运行VBA代码后,Excel的撤销按钮是灰色的,这意味着VBA代码导致工作表、工作簿的改变是无法撤销的,其实VBA内置了一个Application.OnUndo 方法 ,能够在运行代码后实现撤销功能,但是具体的撤销过程需要自行实现。


OnUndo(Text,Procedure) 方法有两个参数,第一个是撤销按钮显示是文字信息,第二个是撤销命令具体的过程名称,其实就是在模块中函数的名称。第二个参数通过特殊的构造,可以实现传递参数效果,具体实现过程如下图:

1.png

由于OnUndo方法的第二个参数是模块中函数名称,在VBA中较容易可以实现,那如何在VSTO中实现。想解决这个问题,核心在于如何把撤销代码放入VBA工程,以及如何在VSTO中调用VBA工程模块中的代码。

一、新建一个Excel外接程序

2.png
  
然后在VSTO的debug目录建立一个xlam格式的加载宏,命名为iCells_Undo.xlam,如图:

3.png
在加载宏中的模块中,写入撤销的代码:
  1. <font face="微软雅黑" size="4">Sub undo(str As String)
  2. ActiveSheet.Range("a1").Value = str
  3. End Sub</font>
复制代码


如图:



4.png
二、在VSTO项目中的ThisAddIn中加入以下代码:

  1. <font face="微软雅黑" size="4">Private xlam As Object = Nothing
  2.     Private Sub ThisAddIn_Startup() Handles Me.Startup
  3.         Dim strPath As String = System.AppDomain.CurrentDomain.BaseDirectory
  4.         Dim strXlam As String = System.IO.Path.Combine(strPath, "iCells_Undo.xlam")
  5.         If IO.File.Exists(strXlam) Then
  6.             xlam = Globals.ThisAddIn.Application.Workbooks.Open(strXlam)
  7.         Else
  8.             xlam = Nothing
  9.         End If
  10.     End Sub

  11.     Private Sub ThisAddIn_Shutdown() Handles Me.Shutdown
  12.         Try
  13.             If xlam IsNot Nothing Then
  14.                 xlam.close(False)
  15.             End If
  16.         Catch ex As Exception
  17.         End Try
  18.     End Sub</font>
复制代码

以上代码作用是在加载项开始的时候,就打开iCells_Undo.xlam,打开iCells_Undo.xlam的目的在于之后需要在加载宏中存放撤销的代码,并且调用。

三、在VSTO中添加一个Button,命名Button1,为这个Button添加事件:

  1. <font face="微软雅黑" size="4">Private Sub Button1_Click(sender As Object, e As RibbonControlEventArgs) Handles Button1.Click
  2.         Dim str As String = Nothing
  3.         Dim ExcelApp As Excel.Application = Globals.ThisAddIn.Application
  4.         str = ExcelApp.ActiveSheet.Range("a1").Value
  5.         ExcelApp.ActiveSheet.Range("a1").Value = "iCells"
  6.         ExcelApp.OnUndo("撤销A1单元格赋值", "'undo" & """" & str & """" & "'")
  7. End Sub</font>
复制代码


最后,运行项目就可以实现撤销功能,但是如果每一个撤销过程如果都放入到iCells_Undo.xlam加载项中,已然失去了VSTO的优势,第二篇分享如何把具体的撤销过程放到VSTO项目中。

评分

1

查看全部评分

TA的精华主题

TA的得分主题

发表于 2022-10-17 12:06 | 显示全部楼层
这么好的东西,没人点赞呢

TA的精华主题

TA的得分主题

发表于 2022-10-25 22:18 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2022-11-3 11:05 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
大佬,第二篇分享在哪里?

TA的精华主题

TA的得分主题

发表于 2023-1-18 14:08 | 显示全部楼层

支持一下,谢谢分享。

老师,你第二篇啥时候发出来呢?等得着急啊
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2024-11-21 22:16 , Processed in 0.033579 second(s), 15 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

快速回复 返回顶部 返回列表