Exception when trying to edit attribute

Hi,

I am using a script to create entities/attributes from csv files. The entities are getting created with appropriate attributes. But on clicking edit attribute exception is thrown “Access violation at address 00F38D40 in module ‘TDM.exe’. Read of address 00000000.” . This happens with any other attribute which does not have the same datatype as the first attribute. The problem does not come up for the first attribute.
The code used to add attributes is as follows
function AddAttributes(datastr,ename)
{
var Entity, Attribute, Datatype,param1,param2,AttrCheck;
var DataType_Bigint = Model.ModelDef.DataTypes.GetObjectByName(“Bigint”);
var DataType_Char = Model.ModelDef.DataTypes.GetObjectByName(“VarChar(%p1)”);
var DataType_Boolean = Model.ModelDef.DataTypes.GetObjectByName(“Boolean”);
var DataType_Number = Model.ModelDef.DataTypes.GetObjectByName(“Decimal(%p1, %p2)”);
var DataType_DateTime = Model.ModelDef.DataTypes.GetObjectByName(“DateTime”);
var DataType_Integer = Model.ModelDef.DataTypes.GetObjectByName(“Integer”);
var DataType_SmallInt = Model.ModelDef.DataTypes.GetObjectByName(“SmallInt”);

if(datastr[1]=="") return;

Datatype=null;
param1=null;
param2=null;
if(datastr[3].toUpperCase()==“UNIQUEIDENTIFIER”) Datatype=DataType_Bigint;
if(datastr[3].toUpperCase()==“BIGINT” || datastr[3].toUpperCase()==“INT”) Datatype=DataType_Integer;
if(datastr[3].toUpperCase()==“BIT”) Datatype=DataType_Boolean;
if(datastr[3].toUpperCase()==“SMALLINT”) Datatype=DataType_SmallInt;
if(datastr[3].toUpperCase()==“DATE” || datastr[3].toUpperCase()==“DATETIME”) Datatype=DataType_DateTime;
if(datastr[3].substring(0,8).toUpperCase()==“NVARCHAR” || datastr[3].substring(0,7).toUpperCase()==“VARCHAR” || datastr[3].substring(0,4).toUpperCase()==“CHAR”)
{
Datatype=DataType_Char;
param1= datastr[3].substring((datastr[3].indexOf(’(’))+1,(datastr[3].indexOf(’)’)));
}
if(datastr[3].substring(0,7).toUpperCase()==“DECIMAL” || datastr[3].substring(0,7).toUpperCase()==“NUMERIC” || datastr[3].substring(0,6).toUpperCase()==“NUMBER”)
{
Datatype=DataType_Number;
param1= datastr[3].substring((datastr[3].indexOf(’(’))+1,(datastr[3].indexOf(’,’)));
param2= datastr[3].substring((datastr[3].indexOf(’,’))+1,(datastr[3].indexOf(’)’)));
}

Entity = Model.Entities.GetObjectByName(ename);     
Attribute=Entity.Attributes.GetObjectByName(datastr[1]);

if(Attribute==null)
{
Attribute = Entity.CreateNewObject( 4007 );
Attribute.Name = datastr[1];
Attribute.Caption = datastr[1];
Attribute.Description=datastr[2];
Attribute.SetLinkedObject(“DataType”, Datatype);
if(param1!=null)
{
Attribute.DataTypeParam1 =param1;
if(param2!=null) Attribute.DataTypeParam2 =param2;
}
if(datastr[4].toUpperCase()==‘Y’) Attribute.Mandatory=true;
if(datastr[5].toUpperCase()==‘Y’)
{
//var PK=Entity.KeyItems
}

}
}

Thanks in advance.

Hi,

there is a problem with values of “Valid Values”. Every data type can have different valid values, unfortunately function that manages the values is not accessible via scripting. This will be fixed in next BETA. CR 81180

Our developer Petr prepared a script that can be used as a workaround. Please find it below. Important thing: after you run the script, save your model, close it and open it again. This will fix a problem with values stored in otherwise Model Test may show errors related to GlobalList (internal).

The following script calls CreateNewObject with data type of appropriate ValidValues.

function ValidValuesOTByDataTypeName(AName)
{
var result = 1061;
switch (AName)
{
case ‘Bigint’:
case ‘Byte’:
case ‘Integer’: result = 1058; break;

case 'Float(%p1)': result = 1059; break;

case 'VarChar':
case 'VarChar(%p1)':
case 'Character(%p1)': result = 1060; break;

}

return result;
}

function AddAttributes(datastr,ename)
{
var Entity, Attribute, Datatype,param1,param2,AttrCheck;
var DataType_Bigint = Model.ModelDef.DataTypes.GetObjectByName(“Bigint”);
var DataType_Char = Model.ModelDef.DataTypes.GetObjectByName(“VarChar(%p1)”);
var DataType_Boolean = Model.ModelDef.DataTypes.GetObjectByName(“Boolean”);
var DataType_Number = Model.ModelDef.DataTypes.GetObjectByName(“Decimal(%p1, %p2)”);
var DataType_DateTime = Model.ModelDef.DataTypes.GetObjectByName(“DateTime”);
var DataType_Integer = Model.ModelDef.DataTypes.GetObjectByName(“Integer”);
var DataType_SmallInt = Model.ModelDef.DataTypes.GetObjectByName(“SmallInt”);

if(datastr[1]=="") return;

Datatype=null;
param1=null;
param2=null;
if(datastr[3].toUpperCase()==“UNIQUEIDENTIFIER”) Datatype=DataType_Bigint;
if(datastr[3].toUpperCase()==“BIGINT” || datastr[3].toUpperCase()==“INT”) Datatype=DataType_Integer;
if(datastr[3].toUpperCase()==“BIT”) Datatype=DataType_Boolean;
if(datastr[3].toUpperCase()==“SMALLINT”) Datatype=DataType_SmallInt;
if(datastr[3].toUpperCase()==“DATE” || datastr[3].toUpperCase()==“DATETIME”) Datatype=DataType_DateTime;
if(datastr[3].substring(0,8).toUpperCase()==“NVARCHAR” || datastr[3].substring(0,7).toUpperCase()==“VARCHAR” || datastr[3].substring(0,4).toUpperCase()==“CHAR”)
{
Datatype=DataType_Char;
param1= datastr[3].substring((datastr[3].indexOf(’(’))+1,(datastr[3].indexOf(’)’)));
}
if(datastr[3].substring(0,7).toUpperCase()==“DECIMAL” || datastr[3].substring(0,7).toUpperCase()==“NUMERIC” || datastr[3].substring(0,6).toUpperCase()==“NUMBER”)
{
Datatype=DataType_Number;
param1= datastr[3].substring((datastr[3].indexOf(’(’))+1,(datastr[3].indexOf(’,’)));
param2= datastr[3].substring((datastr[3].indexOf(’,’))+1,(datastr[3].indexOf(’)’)));
}

Entity = Model.Entities.GetObjectByName(ename);
Attribute=Entity.Attributes.GetObjectByName(datastr[1]);
if(Attribute==null)
{
Attribute = Entity.CreateNewObject( 4007 );
Attribute.Name = datastr[1];
Attribute.Caption = datastr[1];
Attribute.Description=datastr[2];
Attribute.SetLinkedObject(“DataType”, Datatype);

//Work Around. This create and assign Valid Values, but doesn't free old Valid Values. Old Valid Values stay in global list.
//After reopen model it will be OK
Attribute.CreateNewObject(ValidValuesOTByDataTypeName(Datatype.Name));
   
if(param1!=null)
{
  Attribute.DataTypeParam1 =param1;
  if(param2!=null) Attribute.DataTypeParam2 =param2;
}
if(datastr[4].toUpperCase()=='Y') Attribute.Mandatory=true; 
if(datastr[5].toUpperCase()=='Y')
{
//var PK=Entity.KeyItems
}           

}
}

function main()
{
var Attr = new Array();
Attr[1] = ‘Attr1’;
Attr[2] = ‘Some Description’;
Attr[3] = ‘Bit’;
Attr[4] = ‘N’;
Attr[5] = ‘N’;
AddAttributes(Attr, ‘Entity1’);

Attr[1] = ‘Attr2’;
Attr[2] = ‘Some Description’;
Attr[3] = ‘UNIQUEIDENTIFIER’;
Attr[4] = ‘N’;
Attr[5] = ‘N’;
AddAttributes(Attr, ‘Entity1’);

Attr[1] = ‘Attr3’;
Attr[2] = ‘Some Description’;
Attr[3] = ‘BIGINT’;
Attr[4] = ‘N’;
Attr[5] = ‘N’;
AddAttributes(Attr, ‘Entity1’);

Attr[1] = ‘Attr4’;
Attr[2] = ‘Some Description’;
Attr[3] = ‘Bit’;
Attr[4] = ‘N’;
Attr[5] = ‘N’;
AddAttributes(Attr, ‘Entity1’);

Attr[1] = ‘Attr5’;
Attr[2] = ‘Some Description’;
Attr[3] = ‘SMALLINT’;
Attr[4] = ‘N’;
Attr[5] = ‘N’;
AddAttributes(Attr, ‘Entity1’);

Attr[1] = ‘Attr6’;
Attr[2] = ‘Some Description’;
Attr[3] = ‘DATE’;
Attr[4] = ‘N’;
Attr[5] = ‘N’;
AddAttributes(Attr, ‘Entity1’);

Attr[1] = ‘Attr7’;
Attr[2] = ‘Some Description’;
Attr[3] = ‘VARCHAR(5)’;
Attr[4] = ‘N’;
Attr[5] = ‘N’;
AddAttributes(Attr, ‘Entity1’);

Attr[1] = ‘Attr8’;
Attr[2] = ‘Some Description’;
Attr[3] = ‘DECIMAL(1,2)’;
Attr[4] = ‘N’;
Attr[5] = ‘N’;
AddAttributes(Attr, ‘Entity1’);
}

Regards,

Vaclav & Petr

Thanks. One other doubt. I need to add the newly added attributes to uniqueidentifier/primary key list. Can it be done in logical model?

Hi,

yes this is possible. See the script below. It needs to be improved, becase it only shows possibilities.

function main()
{
// Lock model
Model.Lock();
// Get first entity in a model
var Entity = Model.Entities.GetObject(0);
// Get second attribute in your entity
var Attribute = Entity.Attributes.GetObject(1);
// Get first unique identifier in your entity
var UniqueIdentifier = Entity.UniqueIdentifiers.GetObject(0);
// Create new unique identified item
var UniqueIdentifierItem = UniqueIdentifier.CreateNewObject (4012);
// Add attribute to unique identifier item
UniqueIdentifierItem.Attribute = Attribute;
// Add information to attribute properties
Attribute.LinkObject(UniqueIdentifierItem);
// Refresh model
Model.RefreshModel();
// Unlock model
Model.UnLock();
}

Regards,

Vaclav

Message was edited by: vaclav

Hi,

the Change request CR 81180 concerning your issue was addressed and will be in the next Beta release of TDM or in TDM 4 in June.

Regards,

R&D Team