ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

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

[求助] 请教VBA代码中断后,全局IRibbonUI变量丢失问题

  [复制链接]

TA的精华主题

TA的得分主题

发表于 2017-11-17 16:07 | 显示全部楼层
本帖已被收录到知识树中,索引项:UI界面定制
完美支持,赞!

TA的精华主题

TA的得分主题

发表于 2019-1-14 23:30 | 显示全部楼层
楼主,按照你的方法改了之后,显示IngRibPointer类型不匹配,使用 @zzyyzzexcel 优化方案则显示“溢出”,是怎么回事呢?
问题都出在这一句上面
lngRibPointer = GetSetting("CustomUI", ThisWorkbook.Name, "RibbonPointer")

这么老的帖子,期待大神们的回复啊。
感谢!!!

TA的精华主题

TA的得分主题

发表于 2019-1-15 09:55 | 显示全部楼层
风转砂 发表于 2019-1-14 23:30
楼主,按照你的方法改了之后,显示IngRibPointer类型不匹配,使用 @zzyyzzexcel 优化方案则显示“溢出”, ...

问题应该出在声明变量lngRibPointer时,请检查。

TA的精华主题

TA的得分主题

发表于 2019-1-20 17:41 | 显示全部楼层
感谢。确实是这个问题,受系统影响,32位系统可以声明IngRibPointer为 long,64位需要声明为longlong,最好是声明为longPtr,不受系统影响。

TA的精华主题

TA的得分主题

发表于 2019-10-24 15:05 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
老帖子很有用,解决我困惑已久的问题,百度很久都没找到,偶然百度才找到

TA的精华主题

TA的得分主题

发表于 2020-4-11 15:09 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
4053005 发表于 2017-3-17 14:55
使用了这个以后,每次一关闭EXCEL就显示失去响应...

使用了这个后,在工作簿的open、beforeclose、Deactivate等事件中都不要放任何触发其响应的语句。否则关闭文件就会失去响应,打开文件就会闪退。

TA的精华主题

TA的得分主题

发表于 2021-7-15 15:39 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
没想到过了这么多年,经好友推荐,找到到了宝藏资源,谢谢。
结合前面各个前辈的回复,我做个终结版汇总:

楼主原版如下:
  1. Option Explicit

  2. '增加32/64位兼容API声明
  3. #If VBA7 And Win64 Then
  4.     Public Declare PtrSafe Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByRef destination As Any, ByRef source As Any, ByVal length As Long)
  5. #Else
  6.     Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByRef destination As Any, ByRef source As Any, ByVal length As Long)
  7. #End If

  8. Public MyRibbon As IRibbonUI

  9. Sub IRibbonUI_onLoad(ribbon As IRibbonUI) '原版楼主估计CustomeUI少写了一个e。这里修正补上。
  10.     SaveSetting "CustomeUI", ThisWorkbook.Name, "RibbonPointer", ObjPtr(ribbon)
  11.     '注册表保存方案;容易受权限影响,如果用户没有注册表操作权限就要保存失败。
  12.     Set MyRibbon = ribbon
  13. End Sub

  14. Function GetRibbon(ByVal lRibbonPointer As LongPtr) As Object '原始版本 将指针lRibbonPointer 定义为LongPtr,提高兼容性
  15.     If Not Rib Is Nothing Then
  16.         Set GetRibbon = Rib
  17.         Exit Function
  18.     End If
  19.    
  20.     Dim objRibbon As Object
  21.     Dim lngRibPointer As LongPtr '32位用long,64位用longlong,大神建议用Longptr,兼容32/64位。
  22.    
  23.     lngRibPointer = GetSetting("CustomeUI", ThisWorkbook.Name, "RibbonPointer")
  24.     CopyMemory objRibbon, lngRibPointer, LenB(lngRibPointer)
  25.    
  26.     Set GetRibbon = objRibbon
  27.     Set objRibbon = Nothing
  28.    
  29. End Function

复制代码

大神修改精简版的版本:

  1. Option Explicit

  2. #If VBA7 And Win64 Then
  3.     Public Declare PtrSafe Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByRef destination As Any, ByRef source As Any, ByVal length As Long)
  4. #Else
  5.     Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByRef destination As Any, ByRef source As Any, ByVal length As Long)
  6. #End If

  7. Public MyRibbon As IRibbonUI
  8. Sub IRibbonUI_onLoad(ribbon As IRibbonUI)
  9.     SaveSetting "CustomeUI", ThisWorkbook.Name, "RibbonPointer", ObjPtr(ribbon)
  10.     '注册表保存方案;容易受权限影响,如果用户没有注册表操作权限就要保存失败。
  11.     Set MyRibbon = ribbon
  12. End Sub


  13. Function GetRibbon_V2() As Object   '修改版V2  ''指针已存在注册表中,无需另外传递,其他多余部分删去,根据某位贴友建议将long修改为longptr
  14.    
  15.     Dim objRibbon As Object, lngRibPointer As LongPtr
  16.    
  17.     lngRibPointer = GetSetting("CustomeUI", ThisWorkbook.Name, "RibbonPointer")
  18.    
  19.     CopyMemory objRibbon, lngRibPointer, LenB(lngRibPointer)
  20.    
  21.     Set GetRibbon = objRibbon
  22.    
  23. End Function


  24. '
  25. '3 调用:
  26. '可以在VBA任何程序段中调用,(我是在错误处理部分调用),如
  27. Sub a()
  28.     '.....
  29.    
  30.     On Error GoTo herr
  31.    
  32. herr:
  33.     Set MyRibbon = GetRibbon
  34.     MyRibbon.Invalidate
  35. End Sub

复制代码


我再各位前辈的基础上,用Excel系统级隐藏名称来做系统级变量,代替注册表保存指针地址的方法。可以提高整个程序的兼容性:

  1. Option Explicit
  2. '增加 32/64位兼容性API声明
  3. #If VBA7 And Win64 Then
  4.     Public Declare PtrSafe Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByRef destination As Any, ByRef source As Any, ByVal length As Long)
  5. #Else
  6.     Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByRef destination As Any, ByRef source As Any, ByVal length As Long)
  7. #End If

  8. Public MyRibbon As IRibbonUI

  9. Sub IRibbonUI_onLoad(ribbon As IRibbonUI)   
  10.     'SaveSetting "CustomeUI", ThisWorkbook.Name, "RibbonPointer", ObjPtr(ribbon)
  11.     '注册表保存方案;容易受权限影响,如果用户没有注册表操作权限就要保存失败。   
  12.     'SetHideName "RibbonPointer", ObjPtr(ribbon)  '这个是封装好的给Excel系统级变量赋值的方法。
  13.     'Excel Application 级别变量,只要Excel程序不关闭,变量一直有效;    '不受任何环境影响。

  14.     Application.ExecuteExcel4Macro "SET.NAME(""RibbonPointer""," & ObjPtr(ribbon) & ")"     '这个仅限整数型的,如果是文本型变量需要在value上再加一层嵌套""""
  15.    
  16.     Set MyRibbon = ribbon
  17.    
  18. End Sub




  19. Function GetRibbon() As Object   '修改版V3  '指针存到隐藏Name中
  20.    
  21.     Dim objRibbon As Object, lngRibPointer As LongPtr
  22.   
  23.     lngRibPointer = Application.ExecuteExcel4Macro("RibbonPointer")
  24.     CopyMemory objRibbon, lngRibPointer, LenB(lngRibPointer)
  25.    
  26.     Set GetRibbon = objRibbon
  27.    
  28. End Function

  29. '
  30. '3 调用:
  31. '可以在VBA任何程序段中调用,(我是在错误处理部分调用),如
  32. Sub a()
  33.     '.....
  34.    
  35.     On Error GoTo herr
  36.    
  37. herr:
  38.     Set MyRibbon = GetRibbon
  39.     MyRibbon.Invalidate
  40. End Sub

  41. '再来一个例子,激活某个Tab
  42. Sub 激活某个Tab()
  43.     Set MyRibbon = GetRibbon()
  44.     MyRibbon.ActivateTabMso "TabData"
  45.     'MyRibbon.ActivateTab "方方格子"
  46. End Sub

  47. '再来个例子,需要用MyRibbon的时候提前赋值一次就可以
  48. Sub PageBreaks_clicked(control As IRibbonControl, pressed As Boolean)
  49.     ActiveSheet.DisplayPageBreaks = pressed
  50.     Set MyRibbon = GetRibbon()
  51.     MyRibbon.InvalidateControl ("StyleInsp")
  52. End Sub



复制代码





TA的精华主题

TA的得分主题

发表于 2021-10-28 21:06 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
学习学习,谢谢谢谢!
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

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

GMT+8, 2024-11-22 08:53 , Processed in 0.035890 second(s), 7 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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