Office中国论坛/Access中国论坛

标题: TreeView出错,似与MSCOMCTL.OCX版本有关【已解决】 [打印本页]

作者: zww3008    时间: 2013-4-2 17:07
标题: TreeView出错,似与MSCOMCTL.OCX版本有关【已解决】
本帖最后由 zww3008 于 2013-4-3 09:21 编辑

我的ACCESS数据库使用了TreeView,后来各种奇怪问题不断,问题提示五花八门各有不一,例如:
[attach]51526[/attach][attach]51527[/attach][attach]51525[/attach]后来反复研究,原来问题都出在对TreeView控件的引用上,即Windows\system32\MSCOMCTL.OCX的引用上。如图:
[attach]51528[/attach][attach]51529[/attach]
我在十台电脑上(共读一台服务器上的数据)应用对比,反复研究得出以下结论:
1、应该与MSCOMCTL.OCX的版本有关(我在这十台电脑上提取的不同版本如上图)。
2、但又不能通过简单的拷贝替换MSCOMCTL.OCX并重新注册来解决问题,并且与Windows版本和OFFICE版本无关。非常奇怪的是,对Windows版本、OFFICE版本、MSCOMCTL.OCX版本,三者都与我的电脑完全一样的有些电脑,却存在问题,有些不一样电脑,但却没问题,通过替换MSCOMCTL.OCX版本,以及重装OFFICE2003SP2/SP3不同版本,原来有问题的始终有问题,不能解决。
3、我的电脑使用的MSCOMCTL.OCX版本是2012-5-2更新的V6.1.98.34。发现,只要经过我的电脑编辑过的任何mdb文件(有引用MSCOMCTL.OCX的),那么到了原来有问题的电脑上,就打不开,弹出上述错误提示。把我的电脑上的MSCOMCTL.OCX版本替换为低版本的MSCOMCTL.OCX后,再来打开经过我编辑过的mdb,也打不开了,此时在VBA编辑窗口中查看MSCOMCTL.OCX的引用时倒不会提示“丢失.....”,但就是不能显示树的结点。
4、问题的手动解决:到任何一台有问题的电脑上,打开该mdb,并打开VBA代码窗口,“工具--引用”,此时会看到显示
“丢失:Microsoft Windows Common Controls 6.0 (SP6)”
将前面的勾去掉,然后重新手动“浏览”加载引用,保存关闭,这个时候,原来有问题的的电脑就可以打开了。

我不知道“引用”到底是什么原理,是否将MSCOMCTL.OCX打包进mdb文件里面??
一句话,我使用最新版的MSCOMCTL.OCX像病毒一样对mdb文件有污染(当然并不是真的有病毒,MSCOMCTL.OCX文件本身是正确的),只要重新保存过,到另一些电脑上就运行出错,将我的电脑替换回低版本的MSCOMCTL.OCX想重新编辑过,结果文件也打不开,想编辑都不行。如果在原来有问题的电脑上编辑并保存,然后到我电脑上来打开,结果彻底打不开了,文件似乎损坏,如何修复都不行,只好将原来备份的mdb中重新提取该窗体替换掉。

问:
1、这到底是怎么回事?如果是MSCOMCTL.OCX版本引起,看起来应该相当普遍吧?不可能没有人遇到,但百度搜索没任何信息。
2、当“引用”窗口中出现“丢失:Microsoft Windows Common Controls 6.0 (SP6)“提示时,如何用VBA代码自动实现上述手动修复的步骤?即先去掉原来的勾,重新浏览加载引用,这个过程。
试过:   
    Dim ref As Reference
    Set ref = References.AddFromFile("c:\windows\system32\MSCOMCTL.OCX")
无效,原来已经引用过的,执行该命令时反而出错。

给一个样例,原本就来自网上,一个是原版的,一个是经过我的电脑重新保存“污染”过的。两个版本在我的电脑上当然都可以正常打开,但在我这里几台有问题的电脑上,“污染”过的就打不开,原版可以打开。
[attach]51531[/attach]
作者: t小宝    时间: 2013-4-2 17:19
我打开你保存过后数据库直接打开VBA编辑器查看引用,是丢失状态,
该引用在你的电脑上最后保存关闭之前是什么状态?

作者: zww3008    时间: 2013-4-2 17:25
t小宝 发表于 2013-4-2 17:19
我打开你保存过后数据库直接打开VBA编辑器查看引用,是丢失状态,
该引用在你的电脑上最后保存关闭之前是什 ...


在我的电脑上,两个版本对VBA的引用都显示正常,打开也正常,另外几台以前正常的电脑也能正常打开。但在我这几台有问题的电脑上,就显示“丢失”状态,只要显示“丢失”状态,就打不开。
作者: zww3008    时间: 2013-4-2 17:28
t小宝 发表于 2013-4-2 17:19
我打开你保存过后数据库直接打开VBA编辑器查看引用,是丢失状态,
该引用在你的电脑上最后保存关闭之前是什 ...

你只要按我上面说的手动修复方法,去掉勾,再点“浏览”手动加载重新引用,就可以打开了。问题太诡异了。
作者: zww3008    时间: 2013-4-2 17:49
还有一个问题,MSCOMCTL.OCX本身是哪里来的?通过重装OFFICE,好像即不能改变也不能增加这个文件。好像也与WINDOWS版本无关,有些WINDOWS7中反而是低版本,有些XP(SP2/SP3)中反而是高版本甚至是最新的2012-5-2的版本。
作者: zww3008    时间: 2013-4-2 18:20
zww3008 发表于 2013-4-2 17:49
还有一个问题,MSCOMCTL.OCX本身是哪里来的?通过重装OFFICE,好像即不能改变也不能增加这个文件。好像也与 ...

突然想到一个问题,我们大多使用的是OFFICE2003,为了能打开2007的文件,我的电脑包括有些电脑上安装了“2007 OFFICE system 兼容包”,不知一切问题是否出自这里?明天测试一下。
作者: t小宝    时间: 2013-4-2 18:41
zww3008 发表于 2013-4-2 17:49
还有一个问题,MSCOMCTL.OCX本身是哪里来的?通过重装OFFICE,好像即不能改变也不能增加这个文件。好像也与 ...

MSCOMCTL.OCX 是一个微软通用控件,OFFICE2003安装包里面也有。
这个控件可能问题比较多,微软经常会更新它的,很多系统或OFFICE的安全更新或补丁都会更新它,所以WIN7上的该控件版本不一定是最新的,关键看电脑什么时候升级了哪个安全更新或补丁。一些新版本也会出现新问题,于是又出更新的版本,由于版本太多,搞得不知哪个能用,不同环境都有不同的问题。
之前我在网上搜索过有关内容,也有人遇到到过,现在懒得用这个控件了,太麻烦
作者: zhuyiwen    时间: 2013-4-2 19:05
呵呵,恭喜发财。

使用ActiveX控件,就是烦。可是Access又没有表示树的控件,呵呵。
真不知如何解决好。

要不用WebBrowse控件模拟?呵呵,有意思的课题。
作者: roych    时间: 2013-4-2 22:34
zhuyiwen 发表于 2013-4-2 19:05
呵呵,恭喜发财。

使用ActiveX控件,就是烦。可是Access又没有表示树的控件,呵呵。

严重同意。包括之前做的“季度奖管理系统”,有版友反映有问题,查实是日期控件出的故障,跟这个控件也有直接关系。
作者: zww3008    时间: 2013-4-2 23:48
本帖最后由 zww3008 于 2013-4-2 23:52 编辑
zhuyiwen 发表于 2013-4-2 19:05
呵呵,恭喜发财。

使用ActiveX控件,就是烦。可是Access又没有表示树的控件,呵呵。


我大量采用TreeView,我见过版主todaynew也有用列表框模拟树的实例,很好。但我感觉在速度上还是用MSCOMCTL.OCX这个控件反应快很多。
更主要的是,我建的树有随意性,也就是级数不固定也无规率,不像严格按照“省-市-县....”等等这样有固定级数的树。
作者: zww3008    时间: 2013-4-3 09:28
问题解决了!
原来就是这么简单,主要是我疏忽了。
方法是,将新版MSCOMCTL.OCX拷贝到有问题的电脑上,然后再进行注册(运行regsvr32 MSCOMCTL.OCX),就这么简单。
我上面说过我也注册过,是我疏忽了,由于不方便在其他电脑上测试,我只是在我自己的电脑上,换成了低版本的MSCOMCTL.OCX,再注册,当然问题解决不了,今天在有问题的电脑上拷贝最新版MSCOMCTL.OCX文件后,再运行regsvr32 MSCOMCTL.OCX注册,问题就解决了!
为了方便,我制成了一个工具,有需要的可看看,尽量选择最新版。
[attach]51532[/attach]
作者: aslxt    时间: 2013-4-3 09:49
试用一下,谢谢
作者: zww3008    时间: 2013-4-3 11:33
本帖最后由 zww3008 于 2013-4-3 11:35 编辑

我试过以下方法,现在才搞清楚,由于不是MSCOMCTL.OCX文件真的损坏或丢失,只是因旧版本不匹配。导致对控件MSComctlLib的操作,无法识别,不能识别,也就没有对象,也就不能进行引用删除、引用添加等等操作!
原来是我把问题搞复杂了,只需更新MSCOMCTL.OCX文件并注册即可。不过从中也学到不少知识。我把MSCOMCTL.OCX剪切到其他目录,mdb会自动满世界地找到他{:soso_e113:}自动重新建立引用。
真正是由于MSCOMCTL.OCX版本引起的错误时,以下代码无效,但还是共享一下:
==================================
Private Sub Cmd查看_Click()
On Error Resume Next
     Dim r As Reference
    For Each r In References
    '  r.Name = "MSComctlLib"
    MsgBox "类库名:" & r.Name & " GUID:" & r.Guid & " 版本" & r.Major & "." & r.Minor, , "信息"
  '  MsgBox "r.Guid:" & r.Guid
        '    MsgBox "类库名:" & r.Name & _
            Chr(13) + Chr(13) + "类库文件绝对路径:" & r.FullPath & _
        Chr(13) + Chr(13) + "是否内建:" & r.BuiltIn & _
        Chr(13) + Chr(13) + "类库版本号Major=" & r.Major & "    Minor=" & r.Minor & _
        Chr(13) + Chr(13) + "r.Guid=" & r.Guid
   Next
End Sub
Private Sub Cmd删除错误引用_Click()
     Dim r As Reference
On Error Resume Next
'
    For Each r In References
'        If err = 48 Then
           If r.IsBroken Then
              
              Application.References.Remove r '如引用已损坏,删除
              MsgBox r.Name & "引用已损坏,已被取消引用。", , ""
           Else
              MsgBox "未发现错误引用", , ""
              Exit For
           End If
'        End If
    Next
End Sub
Private Sub Cmd修复_Click()
   
On Error GoTo Err_Cmd修复_Click
'On Error Resume Next
     Dim r As Reference
'首先检查CTL引用正常否
    Dim bolFindAdo As Boolean
   
  '  取消错误引用(方法一):
'   For Each r In References
'        If r.Name = "MSComctlLib" Or r.Guid = "{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}" Then
'          If r.IsBroken Then
'             MsgBox "引用已损坏,删除", , ""
'             References.Remove r '如引用已损坏,删除
'          Else
'             bolFindAdo = True
'             MsgBox "不需要修复!", , ""
'             Exit For
'          End If
'       End If
'   Next
   
  '  取消错误引用(方法二):
   
    Set r = Application.References!MSComctlLib
    If r.IsBroken Then
        Application.References.Remove r '如引用已损坏,删除
        MsgBox r.Name & "引用已损坏,已被取消引用。", , ""
    Else
        bolFindAdo = True
        MsgBox "不需要修复!", , ""
    End If
  '修复MSComctlLib引用
    If bolFindAdo = False Then
       MsgBox "还没引用,现在引用MSCOMCTL.OCX控件。"
       Set r = Application.References.AddFromFile("c:\windows\system32\MSCOMCTL.OCX")
       References.AddFromGuid _
       Guid:="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}", Major:=2, Minor:=1
     '  References.AddFromGuid _
       Guid:="{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}"
    End If
    '下面重新搜索后确认
'   For Each r In References
'        If r.Name = "MSComctlLib" Or r.Guid = "{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}" Then
           If r.IsBroken Then
              MsgBox "引用失败!请检查是否存在文件C:\Windows\system32\MSCOMCTL.OCX", , ""
           Else
              If bolFindAdo = False Then MsgBox "修复MSCOMCTL.OCX的引用成功!", , ""
             ' bolFindAdo = True
            '  Exit For
           End If
'        End If
'    Next
     
Exit_Cmd修复_Click:
    Exit Sub
Err_Cmd修复_Click:
    MsgBox err.Description & "加载失败,请联系管理员!", vbInformation, "提示"
Resume Exit_Cmd修复_Click
End Sub


作者: ycxchen    时间: 2013-4-3 15:28
楼主的钻研精神值得学习!
作者: ぷ杯具啊    时间: 2016-8-2 11:44
感谢楼主大人,问题终于解决
作者: fxbianxiu    时间: 2017-7-25 10:18
没有树控件实在是不方便,一直被这个问题纠结,非常感谢楼主,我回去试试这个方法






欢迎光临 Office中国论坛/Access中国论坛 (http://www.office-cn.net/) Powered by Discuz! X3.3