AXForum  
Вернуться   AXForum > Microsoft Dynamics AX > DAX: Программирование
All
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 19.01.2021, 18:05   #1  
DesparioN is offline
DesparioN
Участник
 
86 / 15 (1) ++
Регистрация: 21.10.2014
Копирование листов при формировании отчета
Добрый день!

Подскажите в чем может быть проблема.
Написан отчет XMLExcelReport, DAX2012. В шаблоне находится 1 лист, созданы именованные диапазоны, настроены группировки ячеек.
На вход идет номер партии. Соответственно сколько номеров передано, столько листов должно сформироваться.
Если партия 1, то отчет формируется корректно. Если более - Система начинает при добавлении новой строки (диапазон Body) ее формировать на месте отформатированных строк нижестоящего именованного диапазона (Footer). При этом последний лист всегда формируется корректно.

В чем может быть причина?
Старый 20.01.2021, 10:31   #2  
Pandasama is offline
Pandasama
Участник
 
457 / 134 (5) +++++
Регистрация: 11.08.2014
Адрес: Барнаул
Ни шаблон ваш не понятен, ни кода формирования новых листов нет - поэтому можно только гадать.
Попробую погадать так: может быть, не переключаете номер текущего/активного листа при создании нового?
Старый 20.01.2021, 10:54   #3  
DesparioN is offline
DesparioN
Участник
 
86 / 15 (1) ++
Регистрация: 21.10.2014
Вот шаблон https://yadi.sk/i/crRporC89Cxc0A

Диапазон Body клонируется в зависимости от количества параметров партии.
Когда происходит копирование листов (не последнего), то отчет формируется таким образом:
https://yadi.sk/i/J5h_fQOQOh45xg

Т.е. при создании второй строки Body остается форматирование строк Footer.
В последнем листе все строки Body такие же как и первая.

Новые листы формирую следующим образом:
X++:
document.workbook().insertSheet(1, i, sheetName);
document.copyDefineNames(1, i);
this.setCurrentWorksheetNum(i);
this.initSectionMap();
Надеюсь теперь стало понятнее.
Старый 20.01.2021, 11:42   #4  
Pandasama is offline
Pandasama
Участник
 
457 / 134 (5) +++++
Регистрация: 11.08.2014
Адрес: Барнаул
.copyDefineNames() - что-то не стандартное, как я понимаю? а там что?
Старый 20.01.2021, 11:45   #5  
DesparioN is offline
DesparioN
Участник
 
86 / 15 (1) ++
Регистрация: 21.10.2014
Да. Метод копирует метки для нового листа.
X++:
public void copyDefineNames(int _copyFromSheet = 0, int _after = 1, str _suffix = '')
{
    Map             buffDefinedNamesMap = Map::create(this.definedNamesMap().pack());
    MapEnumerator   mapEnumerator = buffDefinedNamesMap.getEnumerator();

    container       mapKey,
                    mapValue;

    Bookmark        bookmarkOrig;


    if(_suffix == '')
        _suffix = strFmt('_%1', _after);

    while(mapEnumerator.moveNext())
    {
        mapKey = mapEnumerator.currentKey();

        bookmarkOrig = conPeek(mapKey, 1);

        mapKey = conPoke(mapKey, 1, strFmt('%1%2', conPeek(mapKey, 1), _suffix));

        mapValue = mapEnumerator.currentValue();
        mapValue = conPoke(mapValue, 1, workbook.worksheets().lookup(_after).name());

        this.definedNamesMap().insert(mapKey, mapValue);
    }
}
Старый 20.01.2021, 15:02   #6  
Pandasama is offline
Pandasama
Участник
 
457 / 134 (5) +++++
Регистрация: 11.08.2014
Адрес: Барнаул
Цитата:
Сообщение от DesparioN Посмотреть сообщение
Да. Метод копирует метки для нового листа.
Что-то не совсем понимаю - в классе в мэпу вы новые метки вставляете, а в Excel-то они как-то попадают?

Ну и то что пишет VORP вроде верно - в Excel метки к листу не привязаны
Старый 20.01.2021, 15:10   #7  
DesparioN is offline
DesparioN
Участник
 
86 / 15 (1) ++
Регистрация: 21.10.2014
Цитата:
Сообщение от Pandasama Посмотреть сообщение
Что-то не совсем понимаю - в классе в мэпу вы новые метки вставляете, а в Excel-то они как-то попадают?
Затрудняюсь ответить на этот вопрос - настолько глубоко не копал принцип работы класса, но то что по метке Header_2 Система однозначно понимает, что нужно вывести значение на второй лист - это да.
Старый 20.01.2021, 14:26   #8  
VORP is offline
VORP
Участник
Аватар для VORP
 
146 / 95 (4) ++++
Регистрация: 26.05.2006
Насколько я помню, в стандарте все definedNames были глобальные. То есть нельзя было задать ячейки с одинаковыми именами на разных листах. Была сделана заготовка для глобальных, связанная в первую очередь с системными именами диапазонов, но в полной мере не была сделана. Может быть когда вы размножаете диапазоны давать им префикс или постфикс с именем(или номером) листа? Может быть можно не размножать листы, а если вам надо именно для печати генерить на одном листе и вставлять pageBreak?
Старый 20.01.2021, 15:04   #9  
DesparioN is offline
DesparioN
Участник
 
86 / 15 (1) ++
Регистрация: 21.10.2014
Так они копируются с постфиксом. С точки зрения определения метки и записи в нее проблем нет. Данные выводятся как надо. Проблема только в форматировании.
Старый 20.01.2021, 19:57   #10  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,691 / 1195 (43) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
Если я правильно понимаю, то у Вас идея заключается в том, чтобы создать первый лист "как положено": HEADER+BODY+FOOTER. Затем Вы создаете новый лист как копию этого созданного листа и хотите только заменить BODY, оставив без изменения HEADER и FOOTER

Сомневаюсь я, что это возможно...

Создание полосы - это метод execute(), а собственно вставка в отчет - document.insertRowsByBookmark() и там дело кончается командой

OXML_RU::appendChild(sheetData, row.row());

Т.е. явно вставка в конец, а не в указанное место

По-моему, Вам придется на каждом листе повторять формирование HEADER и FOOTER. Соответственно, новые листы создавать не как копии первого, а делать их чистыми

Т.е. в команде

document.workbook().insertSheet(1, i, sheetName);

Первый параметр - указать 0 и формировать эти листы с нуля
__________________
- Может, я как-то неправильно живу?!
- Отчего же? Правильно. Только зря...
Старый 20.01.2021, 22:07   #11  
DesparioN is offline
DesparioN
Участник
 
86 / 15 (1) ++
Регистрация: 21.10.2014
Я пробовал, но тогда вылезает ошибка в initSectionMap.
В общем по ходу придется все выводить на 1 лист, ибо сложно выявить проблему в недоступных для дебага объектах.
Старый 20.01.2021, 23:13   #12  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,691 / 1195 (43) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
А при чем здесь initSectionMap()? Это же просто список констант, которые записываются в MAP. Идентификаторы полос отчета. Там просто инициализация и наполнение MAP

Я не очень понимаю, зачем Вам вообще вот эти 2 команды

document.copyDefineNames(1, i);
this.initSectionMap();

Физически же работа происходит так

1. По именам ячеек заполняются ячейки в ШАБЛОНЕ
2. По именам полосы (вот то, что в initSectionMap задается) выделяется секция из шаблона и копируется в итоговый отчет в конце

Т.е. я вообще не понимаю какой смысл в этих играх с переименованием. В этом просто нет смысла. По логике, у Вас в методе CreateReport должно быть что-то вроде такого

X++:
// Инициализация MAP с именами секций отчета
// Один раз в самом начале
this.initSectionMap();

// Выбор первой записи таблиц-источников

// Заполнение первого листа
execute(#header);
execute(#body);
execute(#footer);

// Выбор следующей записи таблиц-источников

// Создаем новый лист
document.insertSheet(0, i, sheetName);  // Метод есть и на самом документе
// Выбор листа - не уверен, что это нужно
this.setCurrentWorksheetNum(i);

execute(#header);
execute(#body);
execute(#footer);

// Ну и далее цикл продолжаем

// Выбор следующей записи таблиц-источников

(...)
__________________
- Может, я как-то неправильно живу?!
- Отчего же? Правильно. Только зря...
Старый 21.01.2021, 02:21   #13  
DesparioN is offline
DesparioN
Участник
 
86 / 15 (1) ++
Регистрация: 21.10.2014
Можно и не копировать. Просто тогда изначально создавать новый лист с именем шаблонного, а в конце переименовывать. Иначе Система не сможет сопоставить лист и метку.

Если создавать новый лист, то форматы меток не переносятся.
Как их перенести отдельно я не в курсе.
Старый 21.01.2021, 15:08   #14  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,691 / 1195 (43) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
Цитата:
Сообщение от DesparioN Посмотреть сообщение
Можно и не копировать. Просто тогда изначально создавать новый лист с именем шаблонного, а в конце переименовывать. Иначе Система не сможет сопоставить лист и метку.
Вы опять не о том говорите. Есть шаблон и есть текущий лист итогового отчета. Ему совершенно без разницы, какое имя у листа. Ему важно знать, какой именно лист текущий

Далее тупо выделяется полоса шаблона и вот "как есть", со всем форматированием, копируется в конец текущего листа итогового отчета

Т.е. у Вас стоит задача не просто создать новый лист отчета, но и как-то "убедить" объект document считать этот созданный лист текущим. Как это сделать я не в курсе. Теоретически, новый лист и так должен стать текущим. Но, мало ли...

Цитата:
Сообщение от DesparioN Посмотреть сообщение
Если создавать новый лист, то форматы меток не переносятся.
Как их перенести отдельно я не в курсе.

Так нет в отчете никаких форматов меток. Совсем нет. Все эти метки и форматы - это только в шаблоне. В итоговом отчете они появляются как результат копирования. Просто копирование идет со всеми форматами
__________________
- Может, я как-то неправильно живу?!
- Отчего же? Правильно. Только зря...
Старый 21.01.2021, 14:46   #15  
VORP is offline
VORP
Участник
Аватар для VORP
 
146 / 95 (4) ++++
Регистрация: 26.05.2006
Оно когда начинает работу, в initSectionsMap() вычитывает все диапазоны в память. Затем прям в шаблонный диапазон вставляет данные, то есть положение диапазона в который идёт вставка не меняется в процессе работы, зато его не надо пересчитывать. Правда надо всегда заполнять все ячейки, иначе может остаться "старое" значение. Раз положение не меняется, действительно не совсем понятно зачем копировать ячейки, единственно зачем это может быть нужно для "размножения" ячеек по горизонтали, как например, сделано в отчётах по налоговым регистрам, кажется метод называется multiplyCell.
Дальше заполненный шаблон целиком добавляется в target sheetData, который в начале пустой. Если бы он был не пустой то приходилось бы в процессе пересчитывать номера ячеек расположенных ниже, что сильно медленно. То есть чтобы заполнялся второй лист надо только его наличие и как то указать его, может быть что-то с шириной колонок нового листа проблема(может быть его надо не просто добавлять а копировать с исходного как-то?). Вроде бы подход Владимира должен быть правильный.
Теги
dax2012, xmlexcelreport

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Падение DAX при формировании отчета в Excel Storaenso DAX: Прочие вопросы 16 06.07.2011 15:57
Копирование листов в Excel с шаблоном Zoe DAX: Программирование 8 20.11.2008 15:50
Поймать SQL запрос при формировании отчета Qaz Qwerty DAX: Программирование 7 12.06.2008 01:46
Копирование листов в Excel Андрей К. DAX: База знаний и проекты 12 30.08.2007 08:44
Русская локализация Axapta 3 ? SlavaK DAX: Администрирование 59 01.07.2003 22:38

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 01:31.