Moderator
Регистрация: 24.01.2006
Адрес: Санкт-Петербург
|
Немного сумбурно, но всё же завершу трудовую неделю на мажорной ноте. Потом неспешно покомментирую.
В общем, прислушавшись к коллегам, родил получение состава и порядка колонок - вроде, правильно. Ковырялся с достаточно сложной формой, поэтому наступил, как мне кажется, уже на все возможные грабли.
Но дальнейшие исследования всячески приветствуются, поэтому желающие могут поучаствовать в небольшом эксперименте.
Для участия надо: - открыть любую форму с гридом и желательно большим количеством закладок
- выделить несколько строк грида, скопировать и вставить в Excel
- не закрывая форму с гридом, открыть окно с кодом джоба, подправив gridName
- "макнуть" мышку в форму, вернуться в джоб и нажать F5 (см.комментарии в джобе)
- получившийся список меток скопировать из инфолога в Excel на отдельный лист
- "развернуть" вертикальный список горизонтально при помощи команды Специальная вставка \ Транспонировать
- сравнить названия колонок из грида и из моего списка, расположив обе строки на одном листе Excel
- сообщить в ветку об успехе или неудаче
Вот мой джоб:
X++: static void Job2192_exportGridColumnOrder(Args _args)
{
// перед запуском ткнуть мышкой в желаемую форму,
// затем ткнуть в текст этого джоба и нажать F5
// (для наглядности лучше сначала закрыть (или свернуть) все ненужные окна,
// а оставшиеся открытые расположить мозаикой)
str gridName = 'RequestList'; // ПОДПРАВЬ ДЛЯ СВОЕЙ ФОРМЫ ИМЯ ИССЛЕДУЕМОГО ГРИДА!
FormRun formRun;
FormGridControl grid;
FormDataSource gridDataSource;
int j, k, m;
Map colNames = new Map(Types::String, Types::Integer);
Map colLabels = new Map(Types::Integer, Types::String);
boolean hasClassMethod(Object _obj, str _methodName)
{ // функция заимствована у Russland'а
ClassId classId = classIdGet(_obj);
SysDictClass sysDictClass = new sysDictClass(classId);
;
return sysDictClass.hasObjectMethod(_methodName);
}
void nextControl(Object _obj)
{
Object control;
int i;
DictField dictField;
DictType dictType;
DictMethod dictMethod;
str columnLabel;
str columnName;
;
for(i=1; i<=_obj.controlCount(); i++)
{
control = _obj.controlNum(i);
if (hasClassMethod(control, 'dataSource') &&
hasClassMethod(control, 'dataField' ) &&
hasClassMethod(control, 'dataMethod'))
{
if (!control.isContainer() &&
control.isVisible() &&
control.dataSource() == gridDataSource.id())
{
if (!control.dataMethod())
{
dictField = new DictField(gridDataSource.table(), control.dataField());
dictType = new DictType (dictField.typeId());
columnLabel =
control.label() ? control.label()
: dictField.label() ? dictField.label()
: dictType.label();
columnName = dictField.name();
}
else
{
// обращение с dictMethod заимствовано у EVGL
dictMethod = new DictMethod(UtilElementType::TableInstanceMethod, gridDataSource.table(), control.dataMethod());
dictType = new DictType(dictMethod.returnId());
columnLabel =
control.label() ? control.label()
: (dictMethod.returnType()==Types::UserType) ? dictType.label()
: dictMethod.name();
m++;
columnName = strFmt('%1(%2)', control.dataMethod(), m);
}
if (! colNames.exists(columnName))
{
k++;
colNames.insert(columnName, k);
colLabels.insert(k, columnLabel);
}
}
}
if(control.isContainer())
{
nextControl(control);
}
}
}
;
formRun = infolog.parmLastActivatedForm().object();
grid = formRun.design().controlName(gridName);
// ищем датасорс грида
for (j=1; j<=formRun.dataSourceCount(); j++)
{
if (formRun.dataSource(j).id() == grid.dataSource())
{
gridDataSource = formRun.dataSource(j);
break;
}
}
k = 0; // счетчик уникальных имен
m = 0; // счетчик дисплей-методов
nextControl(formRun.design());
for (k=1;k<=colNames.elements();k++)
{
info(strFmt('%1 -- %2', k, colLabels.lookup(k)));
}
} P.S. Теперь несколько тезисов по теме русским бытовым языком: - После копировании строк грида и последующей вставки в Excel выводятся столбцы, соответствующие всем видимым (visible=Yes) управляющим элементам ("контролам") формы, у которых в свойстве dataSource указан датасоурс копируемого грида.
.
- Порядок следования колонок в Excel определяется порядком рекурсивного перебора контролов работающей (перебор по AOT не годится!) формы (см. джоб) по всем вкладкам, начиная с первой (обычно это вкладка "Обзор", на которой расположен сам грид). То, что первыми идут колонки самого грида - не более, чем следствие того, что грид расположен именно на первой вкладке. Перетащите вкладку "Обзор" в конец набора вкладок - и колонки ее грида станут последними на листе Excel.
.
- Копируются данные контролов, соответствующих как полям датасорса, так и дисплей-методам базовой таблицы (у меня Axapta 3.0 sp4, со слов glibs'а вывод дисплей-методов появился с версии 3.0 sp3).
.
- Если одно и то же поле выводится на форму несколько раз, то в Excel попадает только самый первый по порядку перебора контрол с этим полем. Оставшиеся контролы с этим полем не выводятся, даже если имеют различные метки (становящиеся в Excel названиями колонок).
.
- В отличие от полей, контролы, ссылающиеся на один и тот же дисплей-метод, выводятся в Excel все (а не только самый первый). Не знаю, фича это или бага, но это так.
.
- Видимость (visible) проверяется непосредственно по самому контролу. Если контрол входит в группу и имеет visible=Yes, а у группы стоит visible=No, то контрол не виден на форме, НО (!) появляется в Excel!
.
- Пока не проверял контролы с разными ключами безопасности. Надеюсь, там всё хорошо.
Последний раз редактировалось Gustav; 29.01.2010 в 23:33.
|