Dutch Gemini's Weblog Pages

April 17, 2012

Excel (VBA) error: Could not load an object because it is not available on this machine

Filed under: Excel,VBA,Windows — dutchgemini @ 10:09 am
Tags: , , , , , , , ,

Update: if you are having problems after installing Security Patch MS12-060 then click here.


Update (Thu Oct 18, 2012): Security Patch MS12-060 also appears to modify the TypeLib information of MSCOMCTL.OCX in the registry. Before the patch, references to MSCOMCTL in the VBA code would resolve to version “2.0″ of the library. With MS12-060, this version has been updated to “2.1″. This was discovered using ProcMon on 2 different PC’s, one patch and one unpatched.

The result is that if in your VBA code you make explicit, early bonded, reference to this library or to components in the library such as in “Dim oListItems As MSComctlLib.ListItems“, Excel stores the newer version of MSCOMCTL.OCX in your project. When you transfer the workbook to a PC without the MS12-060 Security Patch (or even without MS12-027) then your project will inevitable fail.

Currently, the only way I found to recover my work (excluding building up the project from scratch inserting one by one all modules) is to add to the registry the node on the MSCOMCTL typeLib for version “2.1″ (which is exactly the same as the “2.0″ node):

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\TypeLib\{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}\2.1]
@="Microsoft Windows Common Controls 6.0 (SP6)"

[HKEY_CLASSES_ROOT\TypeLib\{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}\2.1]

[HKEY_CLASSES_ROOT\TypeLib\{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}\2.1\win32]
@="C:\\WINDOWS\\system32\\MSCOMCTL.OCX"

[HKEY_CLASSES_ROOT\TypeLib\{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}\2.1\FLAGS]
@="2"

[HKEY_CLASSES_ROOT\TypeLib\{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}\2.1\HELPDIR]
@=""

Remind that this is not a universal solution and it will not allow you to run VBA projects on every PC around, but at least it does allow you to get back to a working system. Hopefully I am able to provide a permanent fix for this issue as well.


Security Patch MS12-027 (Vulnerability in MSCOMCTL.OCX could allow Remote Code Execution) of April 10, 2012 causes a problem that may result in the “Could not load an object because it is not available on this machine” error message when starting Excel with a workbook or an Add-In that uses components from the selected file. Usually a second other error message is also triggered is “Compile error in hidden module: <name of module>“.

To protect your PC, this patch installs an updated version of MSCOMCTL.OCX with the same COM Interface so you can use it without changing one line of code but with a different Class Id (CLSID). Via the Registry all applications seeking the original CLSID are redirected to the new CLSID so that you can continue using it safely. The section of the Registry doing this redirection is “HKLM\SOFTWARE\Microsoft\Internet Explorer\ActiveX Compatibility“.

You may ask yourself: «what does Internet Explorer’s ActiveX Compatibility have to do with Excel?» Well, it does, and it does a lot. Excel scans the same registry section for understanding whether it can safely load a component and what CLSID it should use as an alternative. Try ProcessMonitor and you’ll see.

When you edit an Excel workbook —doesn’t matter the format, XLS/XLA/XLSM/XLAM all have it— on a PC where the patched MSCOMCTL.OCX is installed, then Excel links internally the control to the new CLSID.

In principle the patch integrates flawlessly and you should see no difference when running Excel with a workbook or an Add-In using components from MSCOMCTL.OCX. I heavily rely in my VBA projects on the Microsoft ListView Control 6.0 ActiveX control which is contained in this file and have been able to use it without any trouble.

In the event that opening Excel does trigger the above error message(s), then this link can provide a fix. If you want to read individual info for a specific Office release, click on one of the release numbers: 2003  2007 2010

Office 2000 or 2002 are likely only affected if you have 2003 components installed, for instance when having Outlook 2003 side-by-side with Office 2002.

Wouldn’t it be that if at that point you transfer (or distribute) the Excel workbook or the Excel Add-In to a PC without the Security Patch installed, Excel will look for the new CLSID but cannot find it and that will trigger the above error message. Note that the fix mentioned earlier will not work. As a confirmation of this issue you can open the VBA project, edit a UserForm with such control in design mode and see that the particular control is indeed missing.

My main development environment is based on Windows XP and Excel 2002 and I use various Virtual PC instances running all possible combinations of Windows XP, Vista and 7 with Excel 2000, 2003, 2007 and 2010 32-bit to test the developed applications. Only the main environment is patched with Windows Update but the Virtual PC’s are not.

This week I finished a project and saved the XLS, copied it to the Virtual PC with Excel 2007 and opened it for the transformation in XLSM and to my surprise I got the error. The bad thing is that I can’t open the XLS (nor the XLSM, XLA or XLAM) on any of the mentioned Virtual PC’s because all them give the error.

I even tried to rescue the project starting a blank workbook and importing the UserForms exported from the XLS on the only PC that is working, but nada, niente, nothing, zero success. I deduct from this that in the associated .FRX file there must be a link to the new CLSID but am still unable to find out where. This makes also sense: Excel uses early binding when using ActiveX control at design time, and early binding generally uses CLSID’s and not the component’s class name.

Of course you can redesign the forms by adding the ListView again because on the failing PC there is indeed a valid ListView ActiveX control, but this is quite a PITB and is no guarantee that it will work.

As it looks now, I will need to install the Security Patch everywhere. I am looking if there is a way to bypass this need.

Security Patch MS12-027 cannot be uninstalled, this patch is considered critical and each PC should be updated as soon as possible but this is not always the case.

Update (and temporary solution)

I have found a trick —a Registry hack to be honest— that helps me open and use the failing workbook on un-patched PC’s. This hack consists in telling Excel to use the old interface instead of the new interface.

Note: Excel workbooks or Excel Add-Ins which are edited/saved on a PC with the Registry hack will open/work on both the patched and un-patched PC’s, thus including PC’s having MS12-027 installed.

Keep in mind, and I cannot say this often enough:

Do not change stuff in the Registry unless you are absolutely sure about what you are doing.

For each control you use from MSCOMCTL.OCX you need to add a Key under “HKLM\SOFTWARE\Microsoft\Internet Explorer\ActiveX Compatibility“. The value for each Key is in the following table:

CLSID in new MSCOMCTL.OCX Exposed Component Name
{87DACC48-F1C5-4AF3-84BA-A2A72C2AB959} Microsoft ImageComboBox Control 6.0 (SP6)
{F91CAF91-225B-43A7-BB9E-472F991FC402} Microsoft ImageList Control 6.0 (SP6)
{979127D3-7D01-4FDE-AF65-A698091468AF} Microsoft ListView Control 6.0 (SP6)
{A0E7BF67-8D30-4620-8825-7111714C7CAB} Microsoft ProgressBar Control 6.0 (SP6)
{0B314611-2C19-4AB4-8513-A6EEA569D3C4} Microsoft Slider Control 6.0 (SP6)
{627C8B79-918A-4C5C-9E19-20F66BF30B86} Microsoft StatusBar Control 6.0 (SP6)
{24B224E0-9545-4A2F-ABD5-86AA8A849385} Microsoft TabStrip Control 6.0 (SP6)
{7DC6F291-BF55-4E50-B619-EF672D9DCC58} Microsoft Toolbar Control 6.0 (SP6)
{95F0B3BE-E8AC-4995-9DCA-419849E06410} Microsoft TreeView Control 6.0 (SP6)

Inside each newly created key you must add 2 values, a REG_SZ named AlternateCLSID and a DWORD (32bit) value named Compatibility Flags (remember to includes the space between the 2 words). For convenience (and for finding my hack back quickly) I have added a third REG_SZ value using my name.

Value Name Value Type Value
AlternateCLSID REG_SZ {CLSID of the “old” component including braces}
Compatibility Flags DWORD 0×00000400 (1024)
Dutch.Gemini REG_SZ Backwards compatibility for component ‘whatever’ following MS012-027 (MSCOMCTL.OCX)

To find the old CLSID values, search for the control’s name (2nd column in 1st table) under the Registry branch “HKEY_CLASSES_ROOT\CLSID“. Watch out: the same component may have been registered multiple times with different CLSID’s, which occurs when you install updated versions of MSCOMCTL.OCX on the PC. For instance this is the case on my PC with the ListView component . So you may have to make a few attempts before you get it all back working.

Tip: the quickest way to understand what CLSID your system is using is looking for the component’s class name (e.g. MSComctlLib.ListViewCtrl) under “HKEY_CLASSES_ROOT“, read its CurVer key value, locate that key value under the same branch and from that one take the CLSID Key value:

The following registry script redirects the CLSID’s of the patched MSCOMCTL.OCX v6.1.98.33 of November 3, 2011 back to those exposed by v6.1.95.45 of December 20, 2002:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\ActiveX Compatibility\{0B314611-2C19-4AB4-8513-A6EEA569D3C4}]
"AlternateCLSID"="{F08DF954-8592-11D1-B16A-00C0F0283628}"
"Compatibility Flags"=dword:00000400
"Dutch.Gemini"="Backwards compatibility for Microsoft Slider Control 6.0 (SP6) component following MS012-027 (MSCOMCTL.OCX)"

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\ActiveX Compatibility\{24B224E0-9545-4A2F-ABD5-86AA8A849385}]
"AlternateCLSID"="{1EFB6596-857C-11D1-B16A-00C0F0283628}"
"Compatibility Flags"=dword:00000400
"Dutch.Gemini"="Backwards compatibility for Microsoft TabStrip Control 6.0 (SP6) component following MS012-027 (MSCOMCTL.OCX)"

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\ActiveX Compatibility\{627C8B79-918A-4C5C-9E19-20F66BF30B86}]
"AlternateCLSID"="{8E3867A3-8586-11D1-B16A-00C0F0283628}"
"Compatibility Flags"=dword:00000400
"Dutch.Gemini"="Backwards compatibility for Microsoft StatusBar Control 6.0 (SP6) component following MS012-027 (MSCOMCTL.OCX)"

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\ActiveX Compatibility\{7DC6F291-BF55-4E50-B619-EF672D9DCC58}]
"AlternateCLSID"="{66833FE6-8583-11D1-B16A-00C0F0283628}"
"Compatibility Flags"=dword:00000400
"Dutch.Gemini"="Backwards compatibility for Microsoft Toolbar Control 6.0 (SP6) component following MS012-027 (MSCOMCTL.OCX)"

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\ActiveX Compatibility\{87DACC48-F1C5-4AF3-84BA-A2A72C2AB959}]
"AlternateCLSID"="{DD9DA666-8594-11D1-B16A-00C0F0283628}"
"Compatibility Flags"=dword:00000400
"Dutch.Gemini"="Backwards compatibility for Microsoft ImageComboBox Control 6.0 (SP6) component following MS012-027 (MSCOMCTL.OCX)"

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\ActiveX Compatibility\{95F0B3BE-E8AC-4995-9DCA-419849E06410}]
"AlternateCLSID"="{C74190B6-8589-11D1-B16A-00C0F0283628}"
"Compatibility Flags"=dword:00000400
"Dutch.Gemini"="Backwards compatibility for Microsoft TreeView Control 6.0 (SP6) component following MS012-027 (MSCOMCTL.OCX)"

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\ActiveX Compatibility\{979127D3-7D01-4FDE-AF65-A698091468AF}]
"AlternateCLSID"="{BDD1F04B-858B-11D1-B16A-00C0F0283628}"
"Compatibility Flags"=dword:00000400
"Dutch.Gemini"="Backwards compatibility for Microsoft ListView Control 6.0 (SP6) component following MS012-027 (MSCOMCTL.OCX)"

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\ActiveX Compatibility\{A0E7BF67-8D30-4620-8825-7111714C7CAB}]
"AlternateCLSID"="{35053A22-8589-11D1-B16A-00C0F0283628}"
"Compatibility Flags"=dword:00000400
"Dutch.Gemini"="Backwards compatibility for Microsoft ProgressBar Control 6.0 (SP6) component following MS012-027 (MSCOMCTL.OCX)"

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\ActiveX Compatibility\{F91CAF91-225B-43A7-BB9E-472F991FC402}]
"AlternateCLSID"="{2C247F23-8591-11D1-B16A-00C0F0283628}"
"Compatibility Flags"=dword:00000400
"Dutch.Gemini"="Backwards compatibility for Microsoft ImageList Control 6.0 (SP6) component following MS012-027 (MSCOMCTL.OCX)"

The following script removes the above keys and values:

Windows Registry Editor Version 5.00

[-HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\ActiveX Compatibility\{0B314611-2C19-4AB4-8513-A6EEA569D3C4}]
[-HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\ActiveX Compatibility\{24B224E0-9545-4A2F-ABD5-86AA8A849385}]
[-HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\ActiveX Compatibility\{627C8B79-918A-4C5C-9E19-20F66BF30B86}]
[-HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\ActiveX Compatibility\{7DC6F291-BF55-4E50-B619-EF672D9DCC58}]
[-HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\ActiveX Compatibility\{87DACC48-F1C5-4AF3-84BA-A2A72C2AB959}]
[-HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\ActiveX Compatibility\{95F0B3BE-E8AC-4995-9DCA-419849E06410}]
[-HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\ActiveX Compatibility\{979127D3-7D01-4FDE-AF65-A698091468AF}]
[-HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\ActiveX Compatibility\{A0E7BF67-8D30-4620-8825-7111714C7CAB}]
[-HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\ActiveX Compatibility\{F91CAF91-225B-43A7-BB9E-472F991FC402}]

Just a last reminder: the above instructions only help you out of a quirky situation. You should patch your PC to the latest versions available as soon as you can.

How does ActiveX redirect on my PC?

The following code for Excel/VBA can be used to understand how ActiveX redirection is on set on your PC. Copy it in a module of your document (Thisworkbook is ok) and let it run.

Option Explicit

Sub Main()
Dim strComputer As String
Dim oReg As Object
Dim strKeyPath As String
Dim strCompName As String
Dim arrSubKeys As Variant
Dim subkey As Variant
Dim strAltClsId As String
Dim strValue As String
Dim rownum As Long

Const HKEY_CLASSES_ROOT = &H80000000
Const HKEY_LOCAL_MACHINE = &H80000002

Application.Cursor = xlWait

strComputer = "."

Set oReg = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\default:StdRegProv")

strKeyPath = "SOFTWARE\Microsoft\Internet Explorer\ActiveX Compatibility"

oReg.EnumKey HKEY_LOCAL_MACHINE, strKeyPath, arrSubKeys

ActiveSheet.Cells.Clear
ActiveSheet.Range("A1").Value = "CLSID"
ActiveSheet.Range("B1").Value = "Component"
ActiveSheet.Range("C1").Value = "Path"
ActiveSheet.Range("D1").Value = "AlternateCLSID"
ActiveSheet.Range("E1").Value = "Component"
ActiveSheet.Range("F1").Value = "Path"
ActiveSheet.Range("G1").Value = "AlternateCLSID"
ActiveSheet.Range("H1").Value = "Component"
ActiveSheet.Range("I1").Value = "Path"
ActiveSheet.Range("J1").Value = "AlternateCLSID"

rownum = 2

On Error Resume Next

For Each subkey In arrSubKeys
    ' get component name and file
    strCompName = vbNullString
    strValue = vbNullString
    oReg.GetStringValue HKEY_CLASSES_ROOT, "CLSID\" & subkey, "", strCompName
    oReg.GetStringValue HKEY_CLASSES_ROOT, "CLSID\" & subkey & "\InprocServer32", "", strValue
    If (strCompName = "") Then GoTo NextSubKey ' class does not exist

    ActiveSheet.Range("A" & rownum).Value = subkey
    ActiveSheet.Range("B" & rownum).Value = strCompName
    ActiveSheet.Range("C" & rownum).Value = strValue

    ' get alternate CLSID.
    strAltClsId = vbNullString
    oReg.GetStringValue HKEY_LOCAL_MACHINE, strKeyPath & "\" & subkey, "AlternateCLSID", strAltClsId
    If (strAltClsId = "") Then GoTo NextValue ' alternate does not exist

    ActiveSheet.Range("D" & rownum).Value = strAltClsId

    ' get component name and file
    strCompName = vbNullString
    oReg.GetStringValue HKEY_CLASSES_ROOT, "CLSID\" & strAltClsId, "", strCompName
    oReg.GetStringValue HKEY_CLASSES_ROOT, "CLSID\" & strAltClsId & "\InprocServer32", "", strValue
    If (strCompName = "") Then GoTo NextValue ' alternate does not exist

    ActiveSheet.Range("E" & rownum).Value = strCompName
    ActiveSheet.Range("F" & rownum).Value = strValue

    ' this one also remapped?
    strValue = vbNullString
    oReg.GetStringValue HKEY_LOCAL_MACHINE, strKeyPath & "\" & strAltClsId, "AlternateCLSID", strValue
    If (strValue = "") Then GoTo NextValue ' alternate of alternate does not exist
    ActiveSheet.Range("G" & rownum).Value = strValue

    ' get component name and file
    strAltClsId = strValue
    strCompName = vbNullString
    strValue = vbNullString
    oReg.GetStringValue HKEY_CLASSES_ROOT, "CLSID\" & strAltClsId, "", strCompName
    oReg.GetStringValue HKEY_CLASSES_ROOT, "CLSID\" & strAltClsId & "\InprocServer32", "", strValue
    If (strCompName = "") Then GoTo NextValue ' alternate of alternate does not exist

    ActiveSheet.Range("H" & rownum).Value = strCompName
    ActiveSheet.Range("I" & rownum).Value = strValue

    ' this one also remapped?
    strValue = vbNullString
    oReg.GetStringValue HKEY_LOCAL_MACHINE, strKeyPath & "\" & strAltClsId, "AlternateCLSID", strValue
    If (strValue = "") Then GoTo NextValue ' alternate of alternate does not exist
    ActiveSheet.Range("J" & rownum).Value = strValue

NextValue:
    rownum = rownum + 1

NextSubKey:
Next

ActiveSheet.Range("A1").Sort Header:=xlYes, _
                             Key1:=ActiveSheet.Columns("C"), Order1:=xlAscending, _
                             Key2:=ActiveSheet.Columns("B"), Order2:=xlAscending
ActiveSheet.Columns.AutoFit

Application.Cursor = xlDefault
End Sub

Click this link to download an Excel 97-2003 compatible XLS file with the same code. Open and enable macros, press Alt-F8, select ThisWorkbook.Main and click Run.

About these ads

50 Comments »

  1. Excellent information, and the only resource I found that fully describes the problem, and attempts to offer a solution. I found the Registry edit approach undesireable, as I do not have control of the distribution of my VBA App (and therefore cannot edit the registries on teh client machines), so I looked deeper, based on the info here. I doscovered that removing all Control Objects from the Common Controls library was enough to prevent the SP Version disconnect, even with a Design Time reference to the library still in the Project. I took this a step further and moved my code from Design-Time control creation to RunTime Control creation, with Class Modules to handle the events I needed to deal with. Even with limitation of not having a Generic Withevents definition allowed, nor support of the VBControlExtender interface that is a part of VB 6.0, I found that explicit refwerencing of the common controls library within the Class Module did not trigger the problem. Anyway, I have a more detailed outline of the solution in this thread at MrExcel: http://www.mrexcel.com/forum/showthread.php?p=3159732.

    Comment by Paul Sasur — May 22, 2012 @ 1:34 am | Reply

    • I recon that using late binding (and I do this a lot) and adding controls at run-time in VBA is a solution for becoming less version dependent with all kind of DLL’s and controls, but it also requires a complete review of the code and the process logic.

      I do understand that making registry patches on PC’s is not always possible nor is it desired, since you need to maintain such a patch and may need to void it in the future when the very particular situation stops existing.

      Please note, and I apologise if this has not come out clear of the text, that the very big advantage of this registry patch is only needed on the development PC and not on any other one. This is because the Add-Ins map via the registry patch internally to the “old” interface and it is the target PC that eventually remaps to the “new” interface. Thus it becomes totally irrelevant if the PC has been updated with the new ActiveX.

      This solution allows me to create, maintain and distribute Excel Add-Ins that work on any PC’s, with or without the MS Security Patch installed.

      Comment by dutchgemini — May 22, 2012 @ 9:03 am | Reply

  2. To repeat Paul Sasurs Comment: Excellent information and definitely the only resource up to now to get more understanding how Security Patch MS12-027 works. However, after applying the registry patch you offered, starting an affected Excel-file on my developing machine running XP-SP3 with MS 12-027 already applied, Excel runs into a deadlock.

    Checking [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\ActiveX Compatibility\ I found for each CLSID key being the CurVer key value for the components you access with the redirection in your script an AlternateCLSID key pointing again to the CLSIDs of new MSCOMCTL.OCX which would explain the deadlock being caused by an infinite AlternateCLSIDs loop.

    So I assume, if MSCOMCTL.OCX v6.1.95.45 of December 20, 2002 offering CLSIDs registered as current version on the machine to be patched as appearently being the case on my machine, additional action must be taken to break the loop.

    Any idea how to do this? Revert back to a MSCOMCTL.OCX version not being registered yet?

    Comment by Bernd Birkicht — May 26, 2012 @ 7:04 am | Reply

    • Ciao Bernd,

      Allow me a few days (it’s on another Pc) to make available a script for Excel/VBA that scans the ActiveX redirection and produces a report listing multiple redirections on a worksheet. From that list you can check at what point you should stop the redirection and assemble a personalised registry patch.

      Grüße an Deutschland.

      Comment by dutchgemini — May 27, 2012 @ 4:58 pm | Reply

    • As promised, see at the bottom of the post.

      Comment by dutchgemini — May 29, 2012 @ 11:16 am | Reply

      • Hi Dutch,
        Thank you very much for providing the script. Running it on my machine it shows 2 entries for Microsoft ListView Control 6.0 (SP6) with CSLIDs {996BF5E0-8044-4650-ADEB-0B013914E99C} and {BDD1F04B-858B-11D1-B16A-00C0F0283628} both pointing to AlternateCLSID {979127D3-7D01-4FDE-AF65-A698091468AF} (Actual for MSCOMCTL.OCX v6.1.98.33 ?).
        Appearently applying your patch on my machine then caused an infinite loop for the Listview Control redirection.
        Similar behaviour also for Treeview, for the other controls within MSCOMCTL.OCX onyl one redirection:

        {DD9DA666-8594-11D1-B16A-00C0F0283628} Microsoft ImageComboBox Control 6.0 (SP6) H:\WINDOWS\system32\MSCOMCTL.OCX {87DACC48-F1C5-4AF3-84BA-A2A72C2AB959} Microsoft ImageComboBox Control 6.0 (SP6)
        {2C247F23-8591-11D1-B16A-00C0F0283628} Microsoft ImageList Control 6.0 (SP6) H:\WINDOWS\system32\MSCOMCTL.OCX {F91CAF91-225B-43A7-BB9E-472F991FC402} Microsoft ImageList Control 6.0 (SP6)
        {996BF5E0-8044-4650-ADEB-0B013914E99C} Microsoft ListView Control 6.0 (SP6) H:\WINDOWS\system32\MSCOMCTL.OCX {979127D3-7D01-4FDE-AF65-A698091468AF} Microsoft ListView Control 6.0 (SP6)
        {BDD1F04B-858B-11D1-B16A-00C0F0283628} Microsoft ListView Control 6.0 (SP6) H:\WINDOWS\system32\MSCOMCTL.OCX {979127D3-7D01-4FDE-AF65-A698091468AF} Microsoft ListView Control 6.0 (SP6)
        {35053A22-8589-11D1-B16A-00C0F0283628} Microsoft ProgressBar Control 6.0 (SP6) H:\WINDOWS\system32\MSCOMCTL.OCX {A0E7BF67-8D30-4620-8825-7111714C7CAB} Microsoft ProgressBar Control 6.0 (SP6)
        {F08DF954-8592-11D1-B16A-00C0F0283628} Microsoft Slider Control 6.0 (SP6) H:\WINDOWS\system32\MSCOMCTL.OCX {0B314611-2C19-4AB4-8513-A6EEA569D3C4} Microsoft Slider Control 6.0 (SP6)
        {8E3867A3-8586-11D1-B16A-00C0F0283628} Microsoft StatusBar Control 6.0 (SP6) H:\WINDOWS\system32\MSCOMCTL.OCX {627C8B79-918A-4C5C-9E19-20F66BF30B86} Microsoft StatusBar Control 6.0 (SP6)
        {1EFB6596-857C-11D1-B16A-00C0F0283628} Microsoft TabStrip Control 6.0 (SP6) H:\WINDOWS\system32\MSCOMCTL.OCX {24B224E0-9545-4A2F-ABD5-86AA8A849385} Microsoft TabStrip Control 6.0 (SP6)
        {66833FE6-8583-11D1-B16A-00C0F0283628} Microsoft Toolbar Control 6.0 (SP6) H:\WINDOWS\system32\MSCOMCTL.OCX {7DC6F291-BF55-4E50-B619-EF672D9DCC58} Microsoft Toolbar Control 6.0 (SP6)
        {9181DC5F-E07D-418A-ACA6-8EEA1ECB8E9E} Microsoft TreeView Control 6.0 (SP6) H:\WINDOWS\system32\MSCOMCTL.OCX {95F0B3BE-E8AC-4995-9DCA-419849E06410} Microsoft TreeView Control 6.0 (SP6)
        {C74190B6-8589-11D1-B16A-00C0F0283628} Microsoft TreeView Control 6.0 (SP6) H:\WINDOWS\system32\MSCOMCTL.OCX {95F0B3BE-E8AC-4995-9DCA-419849E06410} Microsoft TreeView Control 6.0 (SP6)

        To be honest, I still do not have an idea how to patch the registry, that Excel Workbooks/Addons may open/work on both patched and un-patched other PC’s, thus including PC’s having MS12-027 installed.

        Greetings from Germany

        Bernd

        Comment by Bernd Birkicht — May 29, 2012 @ 12:59 pm

      • This result from the registry is consistent with what I have.

        Just to summarize:

        (a) CLSID ‘{BDD1F04B-858B-11D1-B16A-00C0F0283628}’ belongs to the old MSCOMCTL.OCX v6.1.95.45, the pre MS12-027 version so to speak
        (b) CLSID ‘{979127D3-7D01-4FDE-AF65-A698091468AF}’ belongs to the new MSCOMCTL.OCX v6.1.98.33, the post MS12-027 version.
        (c) If you develop/edit your add-in on a pre-MS12 system, your old MSCOMCTL.OCX will be referenced in the project and you can use this project on *ANY* PC.
        (d) If you develop/edit your add-in on a post-MS12 system, your new MSCOMCTL.OCX will be referenced in the project and you can use this project *ONLY* on PCs with MS12-027.

        If you scan your registry you will note, under HKCR\CLSID, that you have both CLSID’s from (a) and (b) on a post-MS12 system and only one CLSID (a) on a pre-MS12 system.

        Point (c) guarantees that your projects works everywhere, so you need to make sure that whatever you develop references the old MSCOMCTL.OCX and not the new one.

        To obtain this, make sure
        (1) the development PC is running and has registered the old MSCOMCTL.OCX v6.1.95.45, the pre MS12-027 version so to speak
        (2) it has the given patch installed, which remaps the NEW CLSID to the old CLSID, i.e. from (b) to (a) – see above

        At (1) – goto C:\WINDOWS\System32, make a copy of the new MSCOMCTL.OCX (or rename it, I suggest MSCOMCTL.OCX.NEW, no need to unregister this file), install and do not forget to register the old MSCOMCTL.OCX in the same folder.

        At (2) – this does the trick: new maps to old but old continues to map to old.

        Hope this helps

        Dutch

        Comment by dutchgemini — May 29, 2012 @ 3:45 pm

      • Hi Dutch,
        Thank you very much for explaining the redirection in detail. Registering MSCOMCTL.OCX v6.1.95.45 was the missing bit. Now also your recommendation to patch the PC to the latest versions available as soon as possible makes sense, due to the PC becomes vulnerable again by reverting to the old MSCOMCTL version.

        I will give it a try asap

        Many Thanks

        Bernd

        Comment by Bernd Birkicht — May 29, 2012 @ 3:58 pm

      • You are more than welcome.

        Comment by dutchgemini — May 29, 2012 @ 4:02 pm

      • Hi Dutch,
        I now tried to apply your patch to my system. I renamed the MS12-027-MSCOMCTL.OCX to MSCOMCTL.OCX.NEW, installed and registered MSCOMCTL.OCX v6.1.95.45 and merged your patch to the registry. Unfortunately still the deadlock appears after starting an affected Excel file. I assume that as long as an Excel file was already compiled with MS12-027 installed, it will try to access the new MSCOMCTL.OCX CSLIDs and will be trapped in the circular redirection setup by the patch not taking care of whatever version of MSCOMCTL.OCX is registered.

        The only way to make the affected Excelfile work on a none MS12-027 computer was to setup a virtual computer with MS12-027 not applied, then applying your patch on it and save the file. This newly saved Excel-file works now on none MS12-027 computers as requested.

        Hope this helps others being in a similar situation.

        Best Regards

        Bernd

        Comment by Bernd Birkicht — May 31, 2012 @ 10:43 am

      • I have replaced the XLS file with a modified script that lists all CLSID’s it finds under ActiveX compatibility. The original script ignored non existing CLSID’s (see lines 49, 66 & 83) but this new will drop an extra the line saying “No object registered with this CLSID”. You may want to try and see what comes up.

        Comment by dutchgemini — May 31, 2012 @ 11:04 am

      • It came into my mind that by unregistering the new OCX and reregistring the old one only the “standard” registry settings were removed but not the ones under ActiveX Compatibility section. This is likely to occur only if you would, and could, uninstall the related security patch (in this case not possible).

        You can, nevertheless, “disable” these entries by adding some characters to the registry key, for example by adding “Disabled” in front of the CLSID key, like “{aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee}” -> “Disabled {aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee}”

        Comment by dutchgemini — May 31, 2012 @ 11:17 am

      • Hi Dutch,
        you may be right, this would break the redirection loop.

        I did some further tests with your patch applied on a none MS12-027 PC. When installing AlternateCLSIDs for components other than Treeview and Listview, Excel came up with ‘Compiler Error in hidden Module’. I am using an Imagelist component side by side to a Treewiew and a Listview component, checking the file shows the Imagelist being disappeared from the form, whilst Treeview and Listview being still available.

        I then modified your patch patching the ActiveX Compatibility entries only for Treview and Listview, which appeared anyhow the only components being modified by MS12-027, and voilá: no further Compiler Error!

        So it might be helpful to apply the patches only for Treeview and Listview as long as the other components seem to be not modified by MS12-027.

        Cheers – Bernd

        Comment by Bernd Birkicht — May 31, 2012 @ 12:12 pm

      • Germany, 12 points.

        No idea why this happens. AFAIK, all control in MSCOMCTL have a different CLSID, but I could be wrong.

        I have projects where I use almost all of the controls in MSCOMCTL.OCX, that is TabStrip, Toolbar, StatusBar, ProgressBar, TreeView, ListViews and ImageList, with the exception of the Slider and ImageComboBox, but can confirm that without the patch, none worked and all disappeared from UserForms but also from the worksheet (I use an ImageList here to store icons for the XP/2003-style CommandBars).

        I came to the patch after having to disable each control individually, opening my project time after time until no compiler errors popped up.

        I have tested again creating a workbook with all possible controls on an PC with MS12-027 and going to an ‘clean’ PC patching the registry until it worked.

        More than happy to share your findings with other people.

        Comment by dutchgemini — May 31, 2012 @ 1:00 pm

  3. I face the same issue: my VBA macros was no more working since several days. I finally found the solution here:http://social.technet.microsoft.com/Forums/en-US/winservergen/thread/e5962316-c515-4603-a531-a8479a9edaae

    It would seem that the MSCOMCTL.OCX file was deregistered by one of the recent updates.

    Please try reregistering the two .OCX files:

    Go to – C:\windows\system32\ and run “regsvr32 mscomctl.ocx” (for 32 bit Win7)

    Go to – C:\windows\syswow64\ and run “regsvr32 mscomctl.ocx” (for 64 bit Win7)

    Do the same for comctl32.ocx where ever you find it.

    Comment by Yohann Monniette — June 5, 2012 @ 11:49 am | Reply

    • Thx for the tip, though it stands in no relation with my situation where all the components have been registered as expected, I hope you can see that.

      Nevertheless, let me remind it is quite unusual that components get de-registered by an update, and I can most certainly say that Windows updates do not do this.

      More likely the registration of the updated component may have failed because the registry keys were not properly released from an earlier lock, which does occur and is not so infrequent either.

      Comment by dutchgemini — June 5, 2012 @ 11:56 am | Reply

  4. I faced the same issue and as I distribute my excel application globally and to no have control on the patches the other machines are on, I found another way to get around it.
    I packaged the new ActiveX control ( MSCOMCTL.OCX) and registered the users machines with this control and that has helped.

    However I am not sure if this approach could break other Office applications and cause office to become unstable

    Comment by Shraddha N — June 20, 2012 @ 3:26 pm | Reply

    • In principle you should NOT distribute the given MSCOMCTL.OCX but I admit doing this myself and so far I have not seen any Office application crash or misbehave. It goes without doubt that you should never install on top of a more recent version, but most installers handle this correctly.

      Comment by dutchgemini — June 20, 2012 @ 4:06 pm | Reply

  5. I have faced tihs same issue, and followed the registry hack to solve it.
    But there is another solution (as the CLSID does exist in the XLA/FRX) but some of it is mangled up.
    So if you open your XLA with a HEX Editor (e.g Ultraedit) you can find the mangled CLSID in there.
    The way it appears is like this:

    For “Microsoft TreeView Control 6.0 (SP6)” the original CLSID “{95F0B3BE-E8AC-4995-9DCA-419849E06410}” will appear as such:
    BEB3F095-ACE8-9549-9DCA-419849E06410 (without the dash’s)

    The OLD CSID “{C74190B6-8589-11D1-B16A-00C0F0283628}” will appear as such:
    B69041C7-8985-D111-B16A-00C0F0283628

    So you can do a Search and Replace with Search value “BEB3F095ACE895499DCA419849E06410″ and replace with “B69041C78985D111B16A00C0F0283628″

    I have tried this by opening a XLA that doesn’t work, and then modifying the file with above method and it works.

    So in general it seems like the rule that can be used to find the CLSID in the binary is such:
    The first 8 characters are reveresed (in pairs)
    the next 4 characters are reveresed (in pairs)
    the next 4 characters are reveresed (in pairs)
    the next 4 characters remain the same
    the next 12 characters remain the same

    For a given CLSID “ABCDEFGH-IJKL-MNOP-QRST-EVQXYZ123456″
    it is replaced with “GHEFCDAB-KLIJ-OPMN-QRST-EVQXYZ123456″

    Comment by Manish — June 25, 2012 @ 2:38 pm | Reply

  6. Hi Dutch

    Thanks for your excellent explanations on this topic. I also develop and distribute VBA programs for 3rd parties. Irrespective of the theory, i.e. the fact that security updates should be applied by 3rd parties as soon as they come out, the reality is often that they haven’t applied them or won’t be in a position to before a while and reality is what we’ve got to deal with. I wish Microsoft showed the same understanding of this VBA distribution issue as your blog does.

    Wishful thinking aside, I have one question: if I have no copy of my old MSCOMCTL.OCX v6.1.95.45 left on my computer, where can I find of a copy of it?

    Mic

    Comment by Mic — June 28, 2012 @ 11:28 am | Reply

    • Apart from searching for ‘download MSCOMCTL.OCX’ on Google I have no other idea. I have a v6.1.97.86 obtained using the VB Run-times SP6 which is already “old” and dated back to 2005. Are you sure you want one that is even older?

      Comment by dutchgemini — June 28, 2012 @ 11:59 am | Reply

      • Not necessarily, I simply want a version of MSCOMCTL.OCX which is pre-MS12-027. Are you saying that v6.1.97.86 will work? If so, I have a copy of that one which I can play with.

        Comment by Mic — June 28, 2012 @ 12:04 pm

      • For me and for my customers that version works like a Swiss watch.

        Comment by dutchgemini — June 28, 2012 @ 2:17 pm

      • I’ve followed your procedure but I’m hitting the same problem as Bernd Birkicht, which is that Excel enters an infinite loop as soon as I run a macro which uses ListView. See copy/paste below obtained with your registry-checking XLS macro:

        {979127D3-7D01-4FDE-AF65-A698091468AF} Microsoft ListView Control 6.0 (SP6) C:\Windows\system32\MSCOMCTL.OCX {BDD1F04B-858B-11D1-B16A-00C0F0283628} Microsoft ListView Control 6.0 (SP6) C:\Windows\System32\mscomctl.ocx {979127D3-7D01-4FDE-AF65-A698091468AF} Microsoft ListView Control 6.0 (SP6) C:\Windows\system32\MSCOMCTL.OCX {BDD1F04B-858B-11D1-B16A-00C0F0283628}
        {BDD1F04B-858B-11D1-B16A-00C0F0283628} Microsoft ListView Control 6.0 (SP6) C:\Windows\System32\mscomctl.ocx {979127D3-7D01-4FDE-AF65-A698091468AF} Microsoft ListView Control 6.0 (SP6) C:\Windows\system32\MSCOMCTL.OCX {BDD1F04B-858B-11D1-B16A-00C0F0283628} Microsoft ListView Control 6.0 (SP6) C:\Windows\System32\mscomctl.ocx {979127D3-7D01-4FDE-AF65-A698091468AF}
        {996BF5E0-8044-4650-ADEB-0B013914E99C} Microsoft ListView Control, version 6.0 C:\Windows\system32\MSCOMCTL.OCX {979127D3-7D01-4FDE-AF65-A698091468AF} Microsoft ListView Control 6.0 (SP6) C:\Windows\system32\MSCOMCTL.OCX {BDD1F04B-858B-11D1-B16A-00C0F0283628} Microsoft ListView Control 6.0 (SP6) C:\Windows\System32\mscomctl.ocx {979127D3-7D01-4FDE-AF65-A698091468AF}

        I have checked that MSCOMCTL.OCX v6.1.97.86 was copied in my C:\Windows\System32, registered the file and renamed the newer MSCOMCTL.OCX to a different file extension. I’m don’t know how to break the loop though: I thought deleting the Alternate CLSID from {BDD1F04B-858B-11D1-B16A-00C0F0283628} and {996BF5E0-8044-4650-ADEB-0B013914E99C} was the obvious thing to do but this didn’t seem to change anything so I reverted the change. I’m lost for clues!

        Do you have any suggestion?

        Comment by Mic — June 28, 2012 @ 6:59 pm

      • Mic,
        the only way that worked for me was to setup a virtual machine having the MS12-027 patch not applied and the make a Registry patch within that virtual machine:
        Windows Registry Editor Version 5.00

        [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\ActiveX Compatibility\{95F0B3BE-E8AC-4995-9DCA-419849E06410}]
        “AlternateCLSID”=”{C74190B6-8589-11D1-B16A-00C0F0283628}”
        “Compatibility Flags”=dword:00000400
        “Dutch.Gemini”=”Backwards compatibility for Microsoft TreeView Control 6.0 (SP6) component following MS012-027 (MSCOMCTL.OCX)”

        [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\ActiveX Compatibility\{979127D3-7D01-4FDE-AF65-A698091468AF}]
        “AlternateCLSID”=”{BDD1F04B-858B-11D1-B16A-00C0F0283628}”
        “Compatibility Flags”=dword:00000400
        “Dutch.Gemini”=”Backwards compatibility for Microsoft ListView Control 6.0 (SP6) component following MS012-027 (MSCOMCTL.OCX)”

        This redirects the CSLIDs pointing to the new MSCOMCTL.OXC back to the old one.

        After saving your application within the virtual machine it will run afterwards und machines having MS12-27 patch applied or not

        Hope that hepls

        Bernd

        Comment by Bernd Birkicht — June 28, 2012 @ 7:11 pm

      • The loop occurs because one interface ID is redirected to another and then back to the initial one. This loop must be interrupted unpatching the registry.

        The issue is all concentrated about this problem: Excel saves the currently active interface ID inside the XLS/XLA/XLSM/XLAM (the workbook as well as the UserForms). This interface ID is used to activate the controls.

        So, Excel stores the NEW interface ID as soon as you edit such workbook on a post-MS12-027. At that point you cannot use it anymore on a pre-MS12-027 system.

        To make your workbook again editable on a pre-MS12-027 system you need to make sure that the NEW interface ID (which does not exist, hence the error) gets mapped back to the OLD interface ID because this one is indeed known to the system. At that point Excel can find the required control in the registry, let you edit the workbook and finally save the OLD interface ID in the workbook.

        With the OLD interface ID inside the file you can open the workbook on both pre-MS12-027 and post-MS12-027 systems.

        Comment by dutchgemini — June 29, 2012 @ 8:36 am

      • Hi Bernd

        Thanks for your post. As I understand it, as long as the VBA is written and saved on a machine without MS12-27 applied, then the application will work on all machines without any registry patch. This is precisely what we’re doing at the moment with a colleague’s machine which doesn’t have MS12-27 applied. Trouble is: that makes any development very dependent on his machine, hence on him, making it impossible to share the workload (in our case, virtualisation is impractical).

        I would precislely need to be able to save the VBA on my machine.

        Mic

        Comment by Mic — June 28, 2012 @ 7:33 pm

      • Register the OLD pre-MS12-027 component on your PC and apply the patch.

        Apart from the different interface ID, the pre- and post-MS12-027 are (from the programmer’s point of view) practically the same and do not represent a problem.

        Microsoft has changed the interface ID so that malware cannot exploit it anymore, with the vicious side effect that healthy applications also fail.

        Comment by dutchgemini — June 29, 2012 @ 8:41 am

      • Your comments only confirm me in my understanding of the problem. Abbreviated summary of what I’ve done, in this order:
        1. Renamed the new (post-MS12-027) MSCOMCTL.OCX to a different file extension in C:\Windows\System32
        2. Copied the old (pre-MS12-027) MSCOMCTL.OCX in C:\Windows\System32
        3. Registered C:\Windows\System32\MSCOMCTL.OCX
        4. Applied the suggested registry re-direction of NEW interface ID to OLD interface ID by adding Alternate CLSIDs
        5. Attempted to break the re-direction loop by deleting Alternate CLSIDs for OLD interface IDs (as below)

        {979127D3-7D01-4FDE-AF65-A698091468AF} Microsoft ListView Control 6.0 (SP6) c:\windows\system32\mscomctl.ocx {BDD1F04B-858B-11D1-B16A-00C0F0283628} Microsoft ListView Control 6.0 (SP6) c:\windows\system32\mscomctl.ocx
        {996BF5E0-8044-4650-ADEB-0B013914E99C} Microsoft ListView Control 6.0 (SP6) c:\windows\system32\mscomctl.ocx {BDD1F04B-858B-11D1-B16A-00C0F0283628} Microsoft ListView Control 6.0 (SP6) c:\windows\system32\mscomctl.ocx
        {BDD1F04B-858B-11D1-B16A-00C0F0283628} Microsoft ListView Control 6.0 (SP6) c:\windows\system32\mscomctl.ocx

        6. Tried to open VBA code developed on a pre-MS12-027 machine: it can’t find ListView items (so it deletes them from the form) and it keeps looping so badly that my only way to close Excel is to use the task manager.

        Comment by Mic — June 29, 2012 @ 10:14 am

      • Hi Mic,
        exact the same happened to me when I tried this method. I could not find a way round. So to setup a virtual machine on my developper machine was the only way that does the trick.

        Cheers – Bernd

        Comment by Bernd Birkicht — June 29, 2012 @ 10:39 am

      • Steps 1, 2, 3, and 4 are sufficient to make it work. Point 5 is not necessary unless your registry is a little messed up. Try running the ActiveX redirection checker (link is at the end of the original post) to see what is actually being redirected.

        Comment by dutchgemini — June 29, 2012 @ 10:39 am

      • Looking at your info, you should stop redirecting {BDD1F04B-858B-11D1-B16A-00C0F0283628} which represents the OLD CLSID and thus the end node of the chain. Actually, the NEW is being redirected to the OLD which is redirecting to the NEW one, an so on.

        Search the registry for the actual CLSID associated to “MSComctlLib.ListViewCtrl” i.e. the one from the current MSCOMCTL.OCX. This is the end node CLSID and that one needs to be disabled, renaming the key is fine, like “{BDD1F04B-858B-11D1-B16A-00C0F0283628}” to “Mic {BDD1F04B-858B-11D1-B16A-00C0F0283628}”. Redirection stops as soon as a given “AlternateCLSDID” is not found.

        Comment by dutchgemini — June 29, 2012 @ 11:37 am

      • Still the same error: it lets me open the file with ListView forms in, but it can’t find the ListViews when I launch the VBA program and throws a “Variable not defined” error. From that point onward, Excel won’t be able to close unless I end the task in the task manager. If I try to re-add the ListViews to the forms in the VBA editor, it throws a “the subject is not trusted to the specified action”. Anyway, not to worry: I’m aware that this your spare time I’m using and I don’t want to keep this thread going for ever. Thanks for trying to help, though!

        Comment by Mic — July 2, 2012 @ 3:31 pm

      • More than welcome to seek for help, even in my spare time. I presume the problem sits in another component. The only thing that I can suggest is to scan the redirection branch in the Registry for all items that have as AlternateCLSDID one of the CLSID’s of the *NEW* interface of the post-MS12-027 component and remove all of them, at least this avoids getting redirected back to the post-MS12-027 component that -I presume- you have in the meanwhile removed (or renamed) from your system in favor of the [registered] pre-MS12-027 component.

        Comment by dutchgemini — July 2, 2012 @ 4:37 pm

      • Mic … Try this code and see what CLSID is causing the circular redirection:

        Sub Main()
        Dim oReg As Object
        Dim strComputer As String
        Dim strKeyPath As String
        Dim strCompName As String
        Dim arrSubKeys As Variant
        Dim subKey As Variant
        Dim strCLSIDchain As String
        Dim strAltClsId As String
        Dim strValue As String

        Const HKEY_CLASSES_ROOT = &H80000000
        Const HKEY_LOCAL_MACHINE = &H80000002

        On Error Resume Next

        strComputer = "." ' Means "this PC"

        ' Hook to Registry
        '
        Set oReg = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\default:StdRegProv")

        ' Component from MSCOMCTL.OCX ("MSComctlLib.xxxxx")
        '
        strCompName = "MSComctlLib."

        ' Path for ActiveX redirection.
        '
        strKeyPath = "SOFTWARE\Microsoft\Internet Explorer\ActiveX Compatibility"

        ' Load all keys under HKCR. This is where the ActiveX components are located.
        '
        oReg.EnumKey HKEY_CLASSES_ROOT, "", arrSubKeys

        For Each subKey In arrSubKeys
        If (VBA.UCase(VBA.Left(subKey, VBA.Len(strCompName))) = VBA.UCase(strCompName)) _
        Then
        ' A component we are looking for. Get the Current Version of this component.
        '
        strValue = vbNullString
        strAltClsId = vbNullString

        Err.Clear
        oReg.GetStringValue HKEY_CLASSES_ROOT, subKey + "\CurVer", "", strValue
        If (Err.Number = 0) And (strValue vbNullString) _
        Then
        ' Fetch the CLSID of the current component.
        '
        Err.Clear
        oReg.GetStringValue HKEY_CLASSES_ROOT, strValue + "\CLSID", "", strAltClsId
        If (Err.Number = 0) And (strAltClsId "") _
        Then
        Debug.Print subKey + " -> " + strValue + " -> " + strAltClsId

        strCLSIDchain = vbNullString
        Do
        ' Load this ID in the chain.
        '
        strCLSIDchain = strCLSIDchain + "|" + strAltClsId

        ' Does redirection occur? Get alternate CLSID.
        '
        Err.Clear
        oReg.GetStringValue HKEY_LOCAL_MACHINE, strKeyPath & "\" & strAltClsId, "AlternateCLSID", strAltClsId
        If (Err.Number = 0) And (strAltClsId vbNullString) _
        Then
        ' Alternate does exist, this one is being redirected.
        '
        Debug.Print vbTab + "Redirected to CLSID '" + strAltClsId + "'"

        If (VBA.InStr(1, strCLSIDchain, strAltClsId, vbTextCompare) 0) _
        Then
        ' Oops, there seems to be circular redirection.
        '
        Debug.Print vbTab + "Oops! Circular redirection to CLSID '" + strAltClsId + "'"
        End If
        End If
        Loop Until (strAltClsId = vbNullString) Or (VBA.InStr(1, strCLSIDchain, strAltClsId, vbTextCompare) 0)
        End If
        End If
        End If
        Next

        Set oReg = Nothing
        End Sub

        Comment by dutchgemini — July 5, 2012 @ 3:39 pm

      • Hi Dutch

        Sorry for not getting back to you earlier. I now have got it working on my machine. The only thing I’ve done differently to what I’d done before is that both libraries now co-exist on my machine as MSCOMCTL.OCX (post-MS12-027 version) and MSCOMCTL2.OCX (pre-MS12-027 version): Excel uses the old version for ListView (the only affected component I use) and the new version for anything else.

        Mic

        Comment by Mic — July 12, 2012 @ 4:52 pm

      • No problem, was on holiday myself so away also. Happy you made it work!

        Comment by dutchgemini — August 1, 2012 @ 10:48 am

  7. [...] [...]

    Pingback by 'Object niet beschikbaar op deze machine' - Worksheet.nl — July 4, 2012 @ 7:19 pm | Reply

  8. i found a solution in here: http://social.technet.microsoft.com/Forums/pl-PL/officeappcompat/thread/3239a28a-7482-40e0-88e9-9d17c8e3c4c5

    “After installing the update you may need to follow the following steps to get rid of the error message listed above.
    You install this security update on a computer that has a third-party software solution installed. The software solution is based on Microsoft Visual Basic for Applications (VBA). The software solution creates an instance of the control directly through Microsoft Office. In this scenario, the control may not load in your solution.
    To resolve this issue, you must delete the cached versions of the control type libraries (extender files) on the client computer. To do this, you must search your hard disk for files that have the “.exd” file name extension and delete all the .exd files that you find. These .exd files will be re-created automatically when you use the new controls the next time that you use VBA. These extender files will be under the user’s profile and may also be in other locations, such as the following:
    %appdata%\Microsoft\forms
    %temp%\Excel8.0
    %temp%\VBE”

    Comment by Lucas H — September 4, 2012 @ 2:44 am | Reply

    • I appreciate your contribution. Deleting the “*.exd” files is mentioned in the link given at this paragraph, halfway my post:

      In the event that opening Excel does trigger the above error message(s), then this link can provide a fix.

      Mind that this solution may not always work.

      Comment by dutchgemini — September 4, 2012 @ 8:34 am | Reply

  9. Getting similar problem.
    I have installed the MS12-027 patch (Dev machine) and if I try to open the excel file which is saved in post MS12-060 patch environment.(Users Machine)

    Giving me error “Could not load an object because…..”. I don’t have control on users machine to check which version of OCX they have.
    So registry trick will not do for me which allow only Current and Previous version of MSCOMCTL.

    Thinking of removing the MSCOMCTL.ocx dependency. but it would take ages to me to re-build whole system again.
    Please suggest what could be the best solution for this. As I need to deliver this very urgent.

    Comment by Shrinath — September 30, 2012 @ 7:22 am | Reply

    • A project made on a MS12-027 system should work fine on an MS12-060 system. The problem on the MS12-060 is, as far as I could understand, related almost exclusively to the failed registration of MSCOMCTL, and for this the only tip I have is re-registering this component. You could do this by script or by using an installer, like InnoSetup.

      Comment by dutchgemini — October 1, 2012 @ 8:35 am | Reply

      • Thanks dutchgemini for prompt response.

        I have found one solution by adding and removing mscomctl.ocx reference at runtime. This will work irrespective of which version of mscomctl.ocx. and VBA code I have used late bindings so no need to add mscomctl.ocx manually.

        Private Sub Workbook_Open()
        On Error Resume Next
        Set ID = thisWorkBook.VBProject.References
        ”Add reference runtime
        If Application.Version = 14 Then ”For Office 2010 – Win 7
        Application.VBE.ActiveVBProject.References.AddFromFile (“C:\Windows\SysWOW64\MSCOMCTL.OCX”)
        Else ” For Office 2003 – WinXp
        Application.VBE.ActiveVBProject.References.AddFromFile (“C:\WINDOWS\system32\MSCOMCTL.OCX”)
        End If
        End Sub

        Private Sub Workbook_BeforeClose(Cancel As Boolean)
        ‘Remove ADO reference while closing this book
        Dim x As Object
        n = Application.VBE.ActiveVBProject.References.count

        Do While Application.VBE.ActiveVBProject.References.count > 0 And n > 0
        On Error Resume Next
        Set x = Application.VBE.ActiveVBProject.References.Item(n)
        y = x.Name
        If y = “MSComctlLib” Then
        ”Remove reference runtime
        Application.VBE.ActiveVBProject.References.Remove x
        End If
        n = n – 1
        Loop
        End Sub

        Hope this will help who don’t have access to registry and mscomctl version control.
        Let me know your thoughts on this.

        Comment by Shrinath Divase — October 1, 2012 @ 9:15 am

      • This works as long as you do not instantiate MSCOMCTL objects before running your code. Unfortunately, when you load objects from MSCOMCTL on for example UserForms, Excel already stores the ClassIds of these components in the workbook and tends to compile and resolve them at run-time even before executing a line of code. In that respect, you may still get the error message if the target system has faulty registration of MSCOMCTL.

        I have seen a solution that sub-classed the UserForm using a class module. In this case the compilation and resolution of the MSCOMCTL components was delayed until the form was instantiated for the first time when creating the class. At that point the proper MSCOMCTL had been re-registered to the project and the application ran without problems. However, I do not have a link or VBA code for this, I’m sorry.

        Comment by dutchgemini — October 1, 2012 @ 9:29 am

      • Please correct this

        If Application.Version = 14 Then ”For Office 2010 – Win 7
        Application.VBE.ActiveVBProject.References.AddFromFile (“C:\Windows\SysWOW64\MSCOMCTL.OCX”)
        Else ” For Office 2003 – WinXp
        Application.VBE.ActiveVBProject.References.AddFromFile (“C:\WINDOWS\system32\MSCOMCTL.OCX”)
        End If

        This will not work on Office 2010 and Windows 32-bit. Better use:

        If Dir(“C:\Windows\SysWOW64\MSCOMCTL.OCX”) <> "" Then ' 64-bit operating system
        Application.VBE.ActiveVBProject.References.AddFromFile (“C:\Windows\SysWOW64\MSCOMCTL.OCX”)
        Else
        Application.VBE.ActiveVBProject.References.AddFromFile (“C:\WINDOWS\system32\MSCOMCTL.OCX”)
        End If

        Comment by dutchgemini — October 1, 2012 @ 9:41 am

  10. Hello,

    After applying register patch ”Could not load an object because it is not available on this machine” error disappeared. But now I have another one in some project: “Runtime error ’424′ Object required”. Restoring the register did’t help. Any idea?

    Thank you,
    M

    Comment by M — October 10, 2012 @ 9:17 am | Reply

    • Did you patch your PC with a Microsoft Security patch on that one recently?

      Comment by dutchgemini — October 10, 2012 @ 9:30 am | Reply

  11. Hi Dutch,

    Can you please give me some explanations on how to sub-class the UserForm using a class module? I never do that before. You’ll save my day :) Thanks.

    Thierry

    Comment by Thierry — October 12, 2012 @ 10:05 pm | Reply

    • Normally, when you use a defined form, you would use a “Set myUserForm = New frmUserForm” in your code to create a new instance of a UserForm. This implies that you define a form during design time and Excel will compile it when booting your application, trapping all errors that may occur at this stage, including the inability to load ActiveX controls by means of their CLSID (for the early binding).

      Different is the behavior with user defined Classes. These are usually compiled when instantiated in the code, somewhere during run-time and not straight at boot time.

      So if you “embed” the UserForm in a class (“Private privateUserForm As New UserForm”), having declared the controls that you need to trap triggers for using “WithEvents” ((“Private WithEvents privateActiveX As New ActiveXClass.ActiveXControl”)), and populate the form with the controls at run-time (using “Set Control = object.Add( ProgID [, Name [, Visible]])” (from Excel Help F1).

      The nice thing at this point is that you are actually using Late Binding with a ProgId (“). As you know, Late Binding resolves at run-time and a ProgId is resolved to the latest version of the control available on the PC, which can be an older release than the one on the PC you are developing on.

      The bonus is that having defined the controls in the class module as explicit objects, at design time you can still work with IntelliSense.

      The bottom-line however is that this requires a re-design of the application and may cost you quite some pennies to achieve this, so you need to carefully balance the advantages and the disadvantages before making the switch.

      Comment by dutchgemini — October 15, 2012 @ 9:03 am | Reply

  12. Thanks for your detailed explanations. Very instructive. As you said, there is a cost here for re-designing the application.

    Comment by Thierry — October 15, 2012 @ 9:35 am | Reply


RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

The Rubric Theme Blog at WordPress.com.

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: