ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

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

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

  [复制链接]

TA的精华主题

TA的得分主题

发表于 2011-5-16 18:55 | 显示全部楼层 |阅读模式
本帖已被收录到知识树中,索引项:UI界面定制
刚刚学习excel2007。理解CustomUI在onload的时候,将ribbon对象捕获并定义给全局变量。这就是写入标准模块的onload宏。譬如
public Rib as IRibbonUI
Sub xxRib_onLoad(ribbon As IRibbonUI)
set Rib=ribbon
End Sub

在代码执行过程中,如果要实现控件的各种回调CallBacks(譬如getVisible, getLabel等),可以通过Rib.Invalidate或Rib.InvalidateControl来重新加载控件,同时触发CallBacks宏,将returnedVal传递给后台,来实现界面的刷新。   --->纯属个人理解,如有误,请指正。

问题来了:因为Rib为定义的全局变量,当代码运行的时候如果有Error出现后,全局变量是会丢失的。丢失Rib后,Invalidate方法就无法实现了,通常会提示“错误91,对象变量未设置”。请教方家:Rib变量是否只有在工作簿打开的时候才加载一次?如果是,在丢失全局变量后,如何再次捕获?谢谢

点评

知识树索引内容:5楼  发表于 2013-9-25 00:46

评分

1

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2011-5-16 22:48 | 显示全部楼层
郁闷。怎么好像最近提的问题都无人问津……

TA的精华主题

TA的得分主题

发表于 2011-5-17 10:01 | 显示全部楼层
public Rib as IRibbonUI
可以这么调用IRibbonUI对象?????,反正我是长见识了.
楼主去搜索下RIBBON相关帖子......

TA的精华主题

TA的得分主题

发表于 2011-5-17 22:44 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
感谢楼主悉心钻研和热情奉献。
做份作业巩固一下。

全局IRibbonUI变量丢失问题.zip

99.15 KB, 下载次数: 572

TA的精华主题

TA的得分主题

 楼主| 发表于 2011-6-4 21:22 | 显示全部楼层
本帖最后由 cooloaky 于 2011-8-31 09:56 编辑

功夫不负有心人。终于找到解决全局变量丢失的问题啦!

解决问题的办法是在加载ribbon的时候,通过ObjPtr函数获得ribbonUI变量的指针,然后通过物理存储该指针(可存于excel单元格、name、注册表等等地方)。在变量丢失后,通过API之copymemory方法,获得之前储存的指针来重新获取对ribbon的引用。够绝了吧?

Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByRef destination As Any, ByRef source As Any, ByVal length As Long)
Public Rib as IRibbonUI
Sub RibX_OnLoad(ribbon As IRibbonUI)
    SaveSetting "CustomUI",ThisWorkbook.name, "RibbonPointer", ObjPtr(ribbon)
    Set Rib=ribbon
End Sub

Function GetRibbon(ByVal lRibbonPointer As Long) As Object
        If not Rib is nothing then set getribbon=rib:exit function
        Dim objRibbon As Object, lngRibPointer as long
        lngRibPointer=getsetting("CustomeUI",thisworkbook.name,"RibbonPointer")
        CopyMemory objRibbon, lngribpointer, LenB(lngribpointer)
        Set GetRibbon = objRibbon
        Set objRibbon = Nothing
End Function

评分

7

查看全部评分

TA的精华主题

TA的得分主题

发表于 2011-12-5 23:15 | 显示全部楼层
cooloaky 发表于 2011-6-4 21:22
功夫不负有心人。终于找到解决全局变量丢失的问题啦!

解决问题的办法是在加载ribbon的时候,通过ObjPtr ...

该方法是够绝的!顶起。

TA的精华主题

TA的得分主题

发表于 2011-12-5 23:33 来自手机 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
这个有点意思,做个标记,以后可能会用得着。

TA的精华主题

TA的得分主题

发表于 2012-1-12 08:49 | 显示全部楼层
Excel2007/2010功能区选项卡、组、控件的显、隐、禁用

http://www.officefans.net/cdb/viewthread.php?tid=173606

TA的精华主题

TA的得分主题

发表于 2014-6-13 15:49 | 显示全部楼层
上面解决方案正确,程序可以优化,完整的程序如下:
1 前面的不变:
Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByRef destination As Any, ByRef source As Any, ByVal length As Long)
Public Rib as IRibbonUI
Sub RibX_OnLoad(ribbon As IRibbonUI)
    SaveSetting "CustomUI",ThisWorkbook.name, "RibbonPointer", ObjPtr(ribbon)
    Set Rib=ribbon
End Sub
2 函数部分优化:
Function GetRibbon() As Object     ''指针已存在注册表中,无需另外传递,其他多余部分删去
        Dim objRibbon As Object, lngRibPointer As Long
        lngRibPointer = GetSetting("CustomUI", ThisWorkbook.Name, "RibbonPointer")
        CopyMemory objRibbon, lngRibPointer, LenB(lngRibPointer)
        Set GetRibbon = objRibbon
End Function
3 调用:
可以在VBA任何程序段中调用,(我是在错误处理部分调用),如
sub a()
.....

    Set Rib = GetRibbon
    Rib.Invalidate
end sub

评分

1

查看全部评分

TA的精华主题

TA的得分主题

发表于 2012-11-11 18:12 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
很牛的方法,这个问题困扰我很久了
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

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

GMT+8, 2024-12-22 17:17 , Processed in 0.041336 second(s), 10 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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