2 sukhanchik
Как было сказано, собственно поля, созданные согласно рекомендациям, мной уже найдены алгоритмом, описанным в первом сообщении. Поэтому UpgradeColumnList ничего нового не даст.
Вопрос в том, чтобы найти поля, созданные вопреки рекомендациям: с типами, не унаследованными от RefRecId (или уж хотя бы напрямую от recId), и в то же время содержащие значения RecId.
2 glibs
Спасибо за скрипт, это очень хорошая идея, перебрать все подозрительные integer-поля таким образом, пропуская некоторые типы. Я добавил ещё некоторые типы, к-рые стоит игнорировать (IMHO):
TimeUnits PositiveDays PositiveMonths createdTime modifiedTime Periods IntvMth IntvQr IntvWk enumId CCColor OLE_Color MaximumLength MinimumLength CACPriority Priority BatchPeriodic HWND LabelIdNum extendedTypeId ColumnWidth NegativeAdjustment NoOfDecimals OprNum AssetInterval AssetLifeTime AssetLifeTimeRest indexId CovStatus SysCodeProfilerAOS* SysCodeProfilerSQL* OLAPCube* OLAPDatabase* OLAPView*.
В итоге получается довольно обозримый список полей, просмотрев к-рый, получим большую уверенность, что мы ничего не упустили.
Скрипт с добавленными типами и с выводом чуть понагляднее, к-рый теперь запускаю:
X++:
// Находим integer-поля, в которых МОГУТ находиться значения RecId, с типом, не унаследованным от recId
static void findProbablyBadRefRecId(Args _args)
{
UtilElements utilElements;
DictTable dictTable;
DictField dictField;
DictType dictType;
TableName prevTable;
Counter i,
result,
fieldsFound,
tablesFound;
Boolean skipField(extendedTypeId _typeId)
{
DictType localDictType = new DictType(_typeId);
;
if (! localDictType)
{
return false;
}
switch (localDictType.id())
{
case typeId2ExtendedTypeId(typeid(recId)) :
case typeId2ExtendedTypeId(typeid(tableId)) :
case typeId2ExtendedTypeId(typeid(ParametersKey)) :
case typeId2ExtendedTypeId(typeid(classId)) :
case typeId2ExtendedTypeId(typeid(FieldNum)) :
case typeId2ExtendedTypeId(typeid(fieldId)) :
case typeId2ExtendedTypeId(typeid(FontSize)) :
case typeId2ExtendedTypeId(typeid(SessionId)) :
case typeId2ExtendedTypeId(typeid(timeOfDay)) :
case typeId2ExtendedTypeId(typeid(Days)) :
case typeId2ExtendedTypeId(typeid(WeekDay)) :
case typeId2ExtendedTypeId(typeid(InventDimFixed)) :
case typeId2ExtendedTypeId(typeid(PrintCopies)) :
case typeId2ExtendedTypeId(typeid(TaxReportField)) :
case typeId2ExtendedTypeId(typeid(JmgSeconds)) :
case typeId2ExtendedTypeId(typeid(Minutes)) :
case typeId2ExtendedTypeId(typeid(Seconds)) :
case typeId2ExtendedTypeId(typeid(Column)) :
case typeId2ExtendedTypeId(typeid(Columns)) :
case typeId2ExtendedTypeId(typeid(Yr)) :
case typeId2ExtendedTypeId(typeid(Months)) :
case typeId2ExtendedTypeId(typeid(NumberSequenceRange)) :
case typeId2ExtendedTypeId(typeid(TimeUnits)) :
case typeId2ExtendedTypeId(typeid(PositiveDays)) :
case typeId2ExtendedTypeId(typeid(PositiveMonths)) :
case typeId2ExtendedTypeId(typeid(createdTime)) :
case typeId2ExtendedTypeId(typeid(modifiedTime)) :
case typeId2ExtendedTypeId(typeid(Periods)) :
case typeId2ExtendedTypeId(typeid(IntvMth)) :
case typeId2ExtendedTypeId(typeid(IntvQr)) :
case typeId2ExtendedTypeId(typeid(IntvWk)) :
case typeId2ExtendedTypeId(typeid(enumId)) :
case typeId2ExtendedTypeId(typeid(CCColor)) :
case typeId2ExtendedTypeId(typeid(OLE_Color)) :
case typeId2ExtendedTypeId(typeid(MaximumLength)) :
case typeId2ExtendedTypeId(typeid(MinimumLength)) :
case typeId2ExtendedTypeId(typeid(CACPriority)) :
case typeId2ExtendedTypeId(typeid(Priority)) :
case typeId2ExtendedTypeId(typeid(BatchPeriodic)) :
case typeId2ExtendedTypeId(typeid(HWND)) :
case typeId2ExtendedTypeId(typeid(LabelIdNum)) :
case typeId2ExtendedTypeId(typeid(extendedTypeId)) :
case typeId2ExtendedTypeId(typeid(ColumnWidth)) :
case typeId2ExtendedTypeId(typeid(NegativeAdjustment)) :
case typeId2ExtendedTypeId(typeid(NoOfDecimals)) :
case typeId2ExtendedTypeId(typeid(OprNum)) :
case typeId2ExtendedTypeId(typeid(AssetInterval)) :
case typeId2ExtendedTypeId(typeid(AssetLifeTime)) :
case typeId2ExtendedTypeId(typeid(AssetLifeTimeRest)) :
case typeId2ExtendedTypeId(typeid(indexId)) :
case typeId2ExtendedTypeId(typeid(CovStatus)) :
return true;
default :
}
if (localDictType.name() like "SysCodeProfilerAOS*" ||
localDictType.name() like "SysCodeProfilerSQL*" ||
localDictType.name() like "OLAPCube*" ||
localDictType.name() like "OLAPDatabase*" ||
localDictType.name() like "OLAPView*")
{
return true;
}
if (localDictType.extend())
{
return skipField(localDictType.extend());
}
return false;
}
str typesChain(extendedTypeId _typeId)
{
DictType chainDictType = new DictType(_typeId);
str ret;
;
if (chainDictType)
{
ret = ret + strfmt(" --> %1", chainDictType.name());
}
if (chainDictType.extend())
{
ret = ret + strfmt("%1", typesChain(chainDictType.extend()));
}
return ret;
}
;
while select utilElements
order by name
where utilElements.recordType == UtilElementType::Table
{
if (prevTable != utilElements.name)
{
dictTable = new DictTable(tablename2id(utilElements.name));
if (! dictTable.isMap() && ! dictTable.isView() && ! dictTable.isTmp())
{
info (strfmt("%1", dictTable.name()));
tablesFound++;
result = 0;
for (i = 1; i <= dictTable.fieldCnt(); i++)
{
dictField = new DictField(dictTable.id(), dictTable.fieldCnt2Id(i));
if (dictField.baseType() == Types::Integer &&
! dictField.isSystem() &&
! skipField(dictField.typeId()))
{
dictType = new DictType(dictField.typeId());
info (strfmt(" %1 : %2",
dictField.name(),
dictType ? typesChain(dictField.typeId()) : int2str(dictField.typeId())));
fieldsFound++;
result++;
}
}
if (! result)
{
infolog.cut(infolog.line());
tablesFound--;
}
}
}
prevTable = utilElements.name;
}
info (strfmt("Total number of tables found: %1", tablesFound));
info (strfmt("Total number of fields found: %1", fieldsFound));
}