Class doesn’t support Automation: ‘CreateObject’ when creating a Scripting.Dictionary object.

huangapple go评论82阅读模式
英文:

Class doesn't support Automation: 'CreateObject" when creating a Scripting.Dictionary object

问题

I'm writing a VBScript in Enterprise Architect in order to generate an output of the message definitions in my model to Excel.

This script works just fine in most cases, but for one, rather large set of messages, it fails on creating a Scripting.Dictionary object.

One time if failed on

set m_properties = CreateObject("Scripting.Dictionary")

the second time a couple of lines further

set attributesDictionary = CreateObject("Scripting.Dictionary")

The error I'm getting is:

EAWrappers.EATaggedValue error: Class doesn't support Automation: 'CreateObject', Line: 62

The weird thing is that these lines have executed perfectly for thousands of times prior to failing.

Both times the error occurred on the same message object, but when I tried to run the script for this message alone, it ran without problems.

It makes me think there is some kind of limit on the number of Dictionary Objects I'm allowed to create or something like that so I only get the error with a large enough set of messages.

The complete script that fails below. For some reason it always fails in this part, although I don't think there is anything weird or specific about this particular script.

!INC Utils.Include
!INC Local Scripts.EAConstants-VBScript
' Author: Geert Bellekens
' Purpose: A wrapper class for a all EATaggedValues
' Date: 2023-05-09

'"static" property propertyNames
dim EATaggedValuePropertyNames
set EATaggedValuePropertyNames = nothing

'initializes the metadata for EA elements (containing all columnNames of t_object
function initializeEATaggedValuePropertyNames()
    dim result
    set result = getArrayListFromQueryWithHeaders("select top 1 * from t_attributetag")
    set EATaggedValuePropertyNames = result(0) 'get the headers
    dim i
    for i = 0 to EATaggedValuePropertyNames.Count -1
        EATaggedValuePropertyNames(i) = lcase(EATaggedValuePropertyNames(i))
    next
end function

Class EATaggedValue
    Private m_properties
    
    'constructor
    Private Sub Class_Initialize
        set m_properties = Nothing
        if EATaggedValuePropertyNames is nothing then
            initializeEATaggedValuePropertyNames
        end if
    end sub
    
    public default function Item (propertyName)
        Item = me.Properties.Item(lcase(propertyName))
    end function
    
    Public Property Get Properties
        set Properties = m_properties
    End Property
    
    Public Property Get ObjectType
        ObjectType = "EATaggedValue"
    End Property
    
    Public Property Get Name
        Name = me("Property")
    End Property
    
    Public Property Get Value
        Value = me("Value")
    End Property
    
    Public Property Get Notes
        Notes = me("Notes")
    End Property

    Public function initializeProperties(propertyList)
        'initialize with new Dictionary
        set m_properties = CreateObject("Scripting.Dictionary") '<= once it failed here
        dim i
        i = 0
        dim propertyName
        for each propertyName in EATaggedValuePropertyNames
            'fill the dictionary
            m_properties.Add propertyName, propertyList(i)
            'add the counter
            i =  i + 1
        next
    end function
end class

function getEATaggedValuesForElementID(elementID, ownerType)
    dim attributesDictionary
    set attributesDictionary = CreateObject("Scripting.Dictionary") '<= the other time here
    dim sqlGetdata
    select case ownerType
        case otElement
            sqlGetdata = "select * from t_objectProperties tv where tv.Object_ID = " & elementID
        case otAttribute
            sqlGetdata = "select * from t_attributeTag tv where tv.ElementID = " & elementID
        case otConnector
            sqlGetdata = "select * from t_connectorTag tv where tv.ElementID = " & elementID
        case otMethod
            sqlGetdata = "select * from t_operationTag tv where tv.ElementID = " & elementID
    end select
    dim queryResults
    set queryResults = getArrayListFromQuery(sqlGetdata)
    dim row
    for each row in queryResults
        dim newTaggedValue
        set newTaggedValue = New EATaggedValue
        newTaggedValue.initializeProperties row
        'add to dictionary based on ID
        attributesDictionary.Add newTaggedValue("ea_guid"), newTaggedValue
    next
    'return
    set getEATaggedValuesForElementID = attributesDictionary
end function
英文:

I'm writing a VBScript in Enterprise Architect in order to generate an output of the message definitions in my model to Excel.

This script works just fine in most cases, but for one, rather large set of messages, it fails on creating a Scripting.Dictionary object.

One time if failed on

set m_properties = CreateObject(&quot;Scripting.Dictionary&quot;)

the second time a couple of lines futher

set attributesDictionary = CreateObject(&quot;Scripting.Dictionary&quot;)

The error I'm getting is:

EAWrappers.EATaggedValue error: Class doesn't support Automation: 'CreateObject', Line:62

The weird thing is that these lines have executed perfectly for thousands of times prior to failing.

Both times the error occurred on the same message object, but when I tried to run the script for this message alone, it ran without problems.

It makes me think there is some kind of limit on the number of Dictionary Objects I'm allowed to create or something like that so I only get the error with a large enough set of messages.

The complete script that fails below. For some reason it always fails in this part, although I don't think there is anything weird or specific about this particular script.

!INC Utils.Include
!INC Local Scripts.EAConstants-VBScript
&#39; Author: Geert Bellekens
&#39; Purpose: A wrapper class for a all EATaggedValues
&#39; Date: 2023-05-09

&#39;&quot;static&quot; property propertyNames
dim EATaggedValuePropertyNames
set EATaggedValuePropertyNames = nothing

&#39;initializes the metadata for EA elements (containing all columnNames of t_object
function initializeEATaggedValuePropertyNames()
	dim result
	set result = getArrayListFromQueryWithHeaders(&quot;select top 1 * from t_attributetag&quot;)
	set EATaggedValuePropertyNames = result(0) &#39;get the headers
	dim i
	for i = 0 to EATaggedValuePropertyNames.Count -1
		EATaggedValuePropertyNames(i) = lcase(EATaggedValuePropertyNames(i))
	next
end function

Class EATaggedValue
	Private m_properties
	
	&#39;constructor
	Private Sub Class_Initialize
		set m_properties = Nothing
		if EATaggedValuePropertyNames is nothing then
			initializeEATaggedValuePropertyNames
		end if
	end sub
	
	public default function Item (propertyName)
		Item = me.Properties.Item(lcase(propertyName))
	end function
	
	Public Property Get Properties
		set Properties = m_properties
	End Property
	
	Public Property Get ObjectType
		ObjectType = &quot;EATaggedValue&quot;
	End Property
	
	Public Property Get Name
		Name = me(&quot;Property&quot;)
	End Property
	
	Public Property Get Value
		Value = me(&quot;Value&quot;)
	End Property
	
	Public Property Get Notes
		Notes = me(&quot;Notes&quot;)
	End Property

	Public function initializeProperties(propertyList)
		&#39;initialize with new Dictionary
		set m_properties = CreateObject(&quot;Scripting.Dictionary&quot;) &#39;&lt;= once it failed here
		dim i
		i = 0
		dim propertyName
		for each propertyName in EATaggedValuePropertyNames
			&#39;fill the dictionary
			m_properties.Add propertyName, propertyList(i)
			&#39;add the counter
			i =  i + 1
		next
	end function
end class

function getEATaggedValuesForElementID(elementID, ownerType)
	dim attributesDictionary
	set attributesDictionary = CreateObject(&quot;Scripting.Dictionary&quot;) &#39;&lt;= the other time here
	dim sqlGetdata
	select case ownerType
		case otElement
			sqlGetdata = &quot;select * from t_objectProperties tv where tv.Object_ID = &quot; &amp; elementID
		case otAttribute
			sqlGetdata = &quot;select * from t_attributeTag tv where tv.ElementID = &quot; &amp; elementID
		case otConnector
			sqlGetdata = &quot;select * from t_connectorTag tv where tv.ElementID = &quot; &amp; elementID
		case otMethod
			sqlGetdata = &quot;select * from t_operationTag tv where tv.ElementID = &quot; &amp; elementID
	end select
	dim queryResults
	set queryResults = getArrayListFromQuery(sqlGetdata)
	dim row
	for each row in queryResults
		dim newTaggedValue
		set newTaggedValue = New EATaggedValue
		newTaggedValue.initializeProperties row
		&#39;add to dictionary based on ID
		attributesDictionary.Add newTaggedValue(&quot;ea_guid&quot;), newTaggedValue
	next
	&#39;return
	set getEATaggedValuesForElementID = attributesDictionary
end function

答案1

得分: 0

那个特定的错误相当具有误导性。

可能的原因是内存泄漏,影响了COM实例化Scripting.Dictionary对象的能力。

显然,COM对于内存泄漏会报告此错误,这本身就相当令人困惑(无法确认,因为没有官方来源支持此说法)。

有时,COM会引发自动化错误或接口错误,而不是内存不足错误。

至于如何修复这个问题,不幸的是,如果是内存泄漏,唯一的解决方法就是为其提供更多资源(例如RAM等)。

英文:

That particular error is quite misleading.

The likely cause is a memory leak that is affecting COMs ability to instantiate a new instance of the Scripting.Dictionary object.

Apparently, COM does report this error for memory leaks, which in itself is quite confusing (cannot confirm this as there is no official source for this claim).

>Sometimes, instead of out-of-memory errors, COM raises automation errors or interface errors.

As for what to do to fix this, unfortunately, if it is a memory leak the only solution is to chuck more resources at it (RAM etc).

huangapple
  • 本文由 发表于 2023年6月13日 17:41:44
  • 转载请务必保留本文链接:https://go.coder-hub.com/76463590.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定