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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 06.05.2012, 17:53   #1  
Cardagant is offline
Cardagant
Участник
 
317 / 54 (2) ++++
Регистрация: 11.10.2011
выбивает Excel при использовании merge()
Всем здравствуйте! Вопрос.
Есть класс, реализующий сбор данных, которые после выводятся в эксель. При выводе данных производится форматирование ячеек, в частности объединение. При определённых параметрах отчёта, доходя до определённой строки, говорит о невозможности объединения ячеек, говорит что выделенная область уже имеет ячейки, которые объединены с другими, хотя предыдущие 11960 таких же строк вывел нормально. Дал отчёту построиться без объединений, range формируется верно и не затрагивает уже объединённых ячеек, то есть ошибки быть не должно. Уже всё проверил, не знаю что искать и где... Может кто сталкивался? Спасибо.

DAX 2009

Последний раз редактировалось Cardagant; 06.05.2012 в 18:32.
Старый 07.05.2012, 11:57   #2  
ZVV is offline
ZVV
MCITP
MCP
Oracle
MCBMSS
 
1,006 / 246 (11) ++++++
Регистрация: 13.02.2004
Адрес: Минск
->
Цитата:
Сообщение от Cardagant Посмотреть сообщение
...При определённых параметрах отчёта...
Может есть смысл в эту сторону покопать?
__________________
Zhirenkov Vitaly
Старый 07.05.2012, 22:13   #3  
Silence is offline
Silence
Участник
Аватар для Silence
 
287 / 27 (1) +++
Регистрация: 29.09.2004
Адрес: г. Москва, Зеленоград
Давно не общался с АХ.

Возможно в записи 11960 есть какие СПЕЦСИМВОЛЫ. (Как бы логично, если 12к записей отработали, а одна нет, то она и виновата.)
А, не создаёт ли класс лишних строк в экселе? Видел как то такое, затраивались строки. Был не верно написан цикл.
__________________
Бывает, что человек молчит, когда ничего не знает о данном предмете, но чаще – когда знает о нем все. (Джордж Бернард Шоу)

Последний раз редактировалось Silence; 07.05.2012 в 22:18. Причина: Дополнил
Старый 08.05.2012, 09:45   #4  
Cardagant is offline
Cardagant
Участник
 
317 / 54 (2) ++++
Регистрация: 11.10.2011
Цитата:
Сообщение от Silence Посмотреть сообщение
Давно не общался с АХ.

Возможно в записи 11960 есть какие СПЕЦСИМВОЛЫ. (Как бы логично, если 12к записей отработали, а одна нет, то она и виновата.)
А, не создаёт ли класс лишних строк в экселе? Видел как то такое, затраивались строки. Был не верно написан цикл.
Всё верно, что предыдущие 11960, что строки последующие. Строки не задваиваются, затраиваются и т д. Диапазон формируется верно, никаких наложений на существующие области нет.
Может ли это быть какой-либо баг Экселя, какое-то ограничение на количество объединений в сессии и т д? Уже не знаю что предполагать.
Старый 08.05.2012, 11:49   #5  
ZVV is offline
ZVV
MCITP
MCP
Oracle
MCBMSS
 
1,006 / 246 (11) ++++++
Регистрация: 13.02.2004
Адрес: Минск
->
Цитата:
Сообщение от Cardagant Посмотреть сообщение
Всё верно, что предыдущие 11960, что строки последующие. Строки не задваиваются, затраиваются и т д. Диапазон формируется верно, никаких наложений на существующие области нет.
Может ли это быть какой-либо баг Экселя, какое-то ограничение на количество объединений в сессии и т д? Уже не знаю что предполагать.
Пробовали в цикле пропустить запись № 11960?
Если проблема в ней, то цикл пойдёт дальше и наверное придётся таки проверить данные в этой строке....
__________________
Zhirenkov Vitaly
Старый 08.05.2012, 14:12   #6  
Cardagant is offline
Cardagant
Участник
 
317 / 54 (2) ++++
Регистрация: 11.10.2011
Цитата:
Сообщение от ZVV Посмотреть сообщение
Пробовали в цикле пропустить запись № 11960?
Если проблема в ней, то цикл пойдёт дальше и наверное придётся таки проверить данные в этой строке....
Идея прекрасная, попробовал. Пропустил строку 11960, он выбился с той же ошибкой, но со сдвигом на одну строку, на ту, которую пропустил)
Старый 10.05.2012, 10:44   #7  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,691 / 1195 (43) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
Приведите уже код выгрузки в Excel. Интересуют следующие вопросы

1. Для экспорта используется ранее созданный шаблон или создается новый (чистый) лист Excel? Если шаблон, то не остался ли в нем какой-либо мусор в строке 11960?
2. Какой механизм экспорта в Excel используется (поячеечная вставка, буфер обмена, RecordSet, ...)?
3. Как формируется Range для метода Merge? Проверить для строки 11960 какие ячейки попали в Range и какие значения есть в этих ячейках
__________________
- Может, я как-то неправильно живу?!
- Отчего же? Правильно. Только зря...
Старый 10.05.2012, 23:20   #8  
Cardagant is offline
Cardagant
Участник
 
317 / 54 (2) ++++
Регистрация: 11.10.2011
Цитата:
Сообщение от Владимир Максимов Посмотреть сообщение
Приведите уже код выгрузки в Excel. Интересуют следующие вопросы

1. Для экспорта используется ранее созданный шаблон или создается новый (чистый) лист Excel? Если шаблон, то не остался ли в нем какой-либо мусор в строке 11960?
2. Какой механизм экспорта в Excel используется (поячеечная вставка, буфер обмена, RecordSet, ...)?
3. Как формируется Range для метода Merge? Проверить для строки 11960 какие ячейки попали в Range и какие значения есть в этих ячейках
1. Используется новый чистый лист. Ячейки объединения пусты перед вызовом Merge, Range формируется верно.
2. Механизм экспорта - поячеечная вставка, также COM использует OWC10.SpreadSheet.10, возможно, он задаёт ограничение на количество объединений? Опытным путём установил, что в некоторых разных конфигурациях начальных параметров данного отчёта, производится одинаковое количество объединений, после вылетает с вышеописанной ошибкой о невозможности объединения. Написал джоб, который последовательно объединяет 40000 раз по 2 строки в первой колонке, действие очевидно, но и здесь вылетел, хотя всё прозрачно и диапазоны 100% верны, файл изначально чист.
3. В Range попадает верный диапазон, ячейки перед объединением пусты.

Последний раз редактировалось Cardagant; 10.05.2012 в 23:34.
Старый 10.05.2012, 11:40   #9  
kvan is offline
kvan
Moderator
Аватар для kvan
Дети Юза
 
775 / 49 (3) +
Регистрация: 07.08.2002
Адрес: Donetsk
сделайте excel.visible(true) и посмотрите на проблемной строке пошагово какие ячейки выбираются перед обьединением.
__________________
С уважением, kvan.
Старый 10.05.2012, 23:38   #10  
Cardagant is offline
Cardagant
Участник
 
317 / 54 (2) ++++
Регистрация: 11.10.2011
Цитата:
Сообщение от kvan Посмотреть сообщение
сделайте excel.visible(true) и посмотрите на проблемной строке пошагово какие ячейки выбираются перед обьединением.
Спасибо за совет. Уже пробовал, всё подбирается верно. Если программно закрыть документ Эксель, а после снова открыть и продолжить выгрузку данных, то ошибки нет, всё выгружается верно.
Старый 11.05.2012, 14:28   #11  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,691 / 1195 (43) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
И все-таки код приведите. Тот фрагмент где формируется Range и вызывается merge(). Такое впечатление, что у Вас где-то накапливаются и не очищаются ссылки. Соответственно, происходит переполнение некоего внутреннего стека объекта OWC.
__________________
- Может, я как-то неправильно живу?!
- Отчего же? Правильно. Только зря...
Старый 11.05.2012, 15:23   #12  
Gustav is offline
Gustav
Moderator
Аватар для Gustav
SAP
Лучший по профессии 2009
 
1,858 / 1152 (42) ++++++++
Регистрация: 24.01.2006
Адрес: Санкт-Петербург
Записей в блоге: 19
Господа, мне наконец удалось получить это сообщение об ошибке: 0xE004002C The selected cells cannot be merged. The range partially intersects a merged cell. Воспроизвелось на OWC.Spreadsheet (и на 10, и на 11) и на Axapta 3.0. В Excel не воспроизвелось (интересно, о каком же "Excel" мы все-таки тут рассуждаем? )

Суть проблемы не в номере строки, а в количестве выполненных операций Merge на одном листе - 32766. Это максимум. Далее вылетает вышеупомянутое сообщение.

Но обо всём по порядку. Вот джоб, реабилитирующий Excel (на каждом шаге по два Merge, и общее их кол-во значительно превышает 32766 - проблем нет):
X++:
{
    COM rng   = SysExcelApplication::construct().workbooks().add().worksheets().itemFromNum(1).range('A1').comObject();
    COM wks   = rng.Parent();
    COM cells = wks.Cells();
    int i;
    ;
    COM::createFromObject(rng.Application()).Visible(true);
    for (i=1; i<=65536-1; i+=2) // только Excel 2003 был в распоряжении
    {
        rng = wks.Range(cells.Item(i,1),cells.Item(i+1,1));
        rng.Merge();
        rng.Value2(i);

        rng = wks.Range(cells.Item(i,2),cells.Item(i+1,2));
        rng.Merge();
        rng.Value2(i);
    }
}
Вот джоб для Spreadsheet, с параллельным выводом в большой Excel значений счетчика - для визуализации момента ошибки (написан на базе моего джоба отсюда: Табличный процессор)
X++:
{
    Form                form = new Form();
    Args                args = new Args();
    FormRun             formRun;
    FormActiveXControl  ss;

    COM                 worksheet;
    COM                 range;
    COM                 cells;
    int                 i;

    COM rng   = SysExcelApplication::construct().workbooks().add().worksheets().itemFromNum(1).range('A1').comObject();
    COM wks   = rng.Parent();
    COM clls  = wks.Cells();
    int                 j;
    ;

    COM::createFromObject(rng.Application()).Visible(true);

    form.addDesign('Design');
    args.object(form);

    formRun = classFactory.formRunClass(args);
    formRun.init();
    formRun.design().caption('Табличный процессор');

    ss = formRun.design().addControl(FormControlType::ActiveX, 'Spreadsheet');
    //ss.className('{0002E541-0000-0000-C000-000000000046}');     // Microsoft Office Spreadsheet 10.0
    ss.className('{0002E559-0000-0000-C000-000000000046}');   // Microsoft Office Spreadsheet 11.0

    ss.heightMode(FormHeight::ColumnHeight);
    ss.widthMode(FormWidth::ColumnWidth);

    range = ss.Range('A1');
    worksheet = range.Parent();
    cells = worksheet.Cells();
    j=0;

    //for (i=1; i<=80000-1; i+=2)
    //for (i=1; i<=32766; i++)
    for (i=1; i<=20; i++)
    {
        j++; // вывод в Excel для визуализации счетчика
        rng = COM::createFromVariant(clls.Item(j));
        rng.Value2(j);

        // вывод в Speadsheet
        //range = ss.Range(cells.Item(i,1),cells.Item(i+1,1));
        range = ss.Range(cells.Item(i,1),cells.Item(i,2));
        range.Merge();
        range.Value2(i);

        //range = ss.Range(cells.Item(i,2),cells.Item(i+1,2));
        //range = ss.Range(cells.Item(i,3),cells.Item(i,6));
        //range.Merge();
        //range.Value2(i);
    }

    formRun.run();
    formRun.wait();
}
С джобом можно поиграться самостоятельно по-всякому (я уже поигрался, поэтому он такой лохматый с комментариями). Самый простой способ убедиться в числе 32766 это сгенерировать джобом небольшое число строк, скажем 100, а затем их скопировать вручную в Spreadsheet'е ниже. После того как число Merge достигнет 32766 дальнейшее копирование будет выполнено без объединения. Можно встать на последнюю merge-ячейку и разъединить ее. В этом случае опять появляется возможность выполнить однократное копирование объединенной ячейки. Если же ее попытаться скопировать в две строки, то объединенной она останется только в первой из них.

Ограничение 32766 действует в пределах текущего рабочего листа, которых в Spreadsheet'е по умолчанию три: Sheet1, Sheet2, Sheet3.
За это сообщение автора поблагодарили: S.Kuskov (2), Cardagant (1).
Старый 12.05.2012, 00:02   #13  
Cardagant is offline
Cardagant
Участник
 
317 / 54 (2) ++++
Регистрация: 11.10.2011
Да, именно так! Именно эта ошибка вылетает у меня, именно об этой ошибке я говорю! Писал аналогичный джоб, чтоб выявить это, получил тот же результат, о котором писал в своих сообщениях выше и о котором пишете Вы. Подскажите есть ли способ избежать или исправить эту ошибку? Помогает сохранение и переоткрытие файла. Возможно сможете подсказать способы лучше? Спасибо!

Последний раз редактировалось Gustav; 12.05.2012 в 00:51. Причина: удалил цитату на свое полное сообщение - излишне!
Старый 12.05.2012, 13:57   #14  
Gustav is offline
Gustav
Moderator
Аватар для Gustav
SAP
Лучший по профессии 2009
 
1,858 / 1152 (42) ++++++++
Регистрация: 24.01.2006
Адрес: Санкт-Петербург
Записей в блоге: 19
Цитата:
Сообщение от Cardagant Посмотреть сообщение
Помогает сохранение и переоткрытие файла.
Чуть отвлекусь на другое. На Сапфоруме участвовал в дискуссии по поводу ошибки Excel при многократном копировании листа внутри рабочей книги. Обнаружил рекомендацию Microsoft - как раз сохранять и переоткрывать файл ( http://support.microsoft.com/kb/210684/ru ).

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

И осторожный совет - при таких заморочках переходите на нормальный Excel...
Старый 12.05.2012, 14:11   #15  
Cardagant is offline
Cardagant
Участник
 
317 / 54 (2) ++++
Регистрация: 11.10.2011
Цитата:
Сообщение от Gustav Посмотреть сообщение
И осторожный совет - при таких заморочках переходите на нормальный Excel...
Думал перестроить отчёт на основе класса ComExcelDocument_RU, но читал на форуме, что вывод в Эксель на его основе существенно медленее, чем с использованием OWC.

Тогда, судя по всему, придётся сравнить производительность обоих способов и выбрать наиболее подходящий в данном случае. Спасибо Вам, Gustav, за совет.
Старый 12.05.2012, 16:11   #16  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,691 / 1195 (43) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
Сделал программное копирование через copy()/paste(). Действительно, после 32766 объединений paste() уже не может скопировать объединенные ячейки. Хотя и ошибок не выдает.

X++:
static void Job_Test(Args _args)
{
    Form                form = new Form();
    Args                args = new Args();
    FormRun             formRun;
    FormActiveXControl  ss;

    COM                 worksheet;
    COM                 range;
    COM                 rangeSource;
    COM                 rangeTarget;
    COM                 cells;
    int                 i;
    int                 maxI;
    int                 timeNowBegin = timeNow();

    SysOperationProgress progress;
    ;

    form.addDesign('Design');
    args.object(form);

    formRun = classFactory.formRunClass(args);
    formRun.init();
    formRun.design().caption('Табличный процессор');

    ss = formRun.design().addControl(FormControlType::ActiveX, 'Spreadsheet');
    //ss.className('{0002E541-0000-0000-C000-000000000046}');     // Microsoft Office Spreadsheet 10.0
    ss.className('{0002E559-0000-0000-C000-000000000046}');   // Microsoft Office Spreadsheet 11.0

    ss.heightMode(FormHeight::ColumnHeight);
    ss.widthMode(FormWidth::ColumnWidth);

    range = ss.Range('A1');
    worksheet = range.Parent();
    cells = worksheet.Cells();

    // Объединение ячеек в первой строке
    range = ss.Range(cells.Item(1,1),cells.Item(1,2));
    range.Merge();
    // Первую строку указываю как источник для последующего копирования
    rangeSource = ss.Range('1:1');
    rangeSource.copy();


#AviFiles
//maxI = 20;
//maxI = 32767;
maxI = 33000;
//maxI = 36409;
//maxI = 37000;
    progress = new SysOperationProgress();
    progress.setAnimation(#aviStopwatch);
    progress.setTotal(maxI);
    progress.setCaption("Проверка объединения");
    progress.setText("Подготовка...");
    progress.update(true);

    for (i=2; i<=maxI; i++)
    {
        progress.setText(strFmt("Осталось %1 из %2", maxI - i + 1, maxI));
        progress.incCount();

        // Копирую в текущую строку "образцовую" строку
        rangeTarget = ss.Range(strFmt('%1:%1',i));
        rangeTarget.paste();

        // Запись значения
//        range = ss.Range(cells.Item(i,1),cells.Item(i,2));
        range = ss.Range('A'+ int2str(i));
        range.Value2(i);
    }

    info("Время выполнения " + time2str(timeNow()-timenowBegin,1,1));
    formRun.run();
    formRun.wait();
}

PS: Где-то в районе 36400 строк OWC съедает всю доступную (ему) память и начинаются дикие торомоза. Так что, думаю, при работе с OWC вообще не стоит использовать такое количество строк. Даже если бы и не было никаких ошибок
__________________
- Может, я как-то неправильно живу?!
- Отчего же? Правильно. Только зря...
Теги
excel, merge, owc, spreadsheet

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Исследование скорости экспорта данных из Axapta в Excel (коллективный эксперимент) Gustav DAX: База знаний и проекты 79 13.02.2014 13:18
Иморт из Excel 2010. Как правильно закрыть Excel? jkspb DAX: Программирование 4 13.10.2013 00:55
проблема использования Excel через clr Batuev Artem DAX: Программирование 8 22.08.2011 18:01
Sample Design Patterns: Microsoft Dynamics AX - Remedy for slow Microsoft Excel import Blog bot DAX Blogs 0 29.05.2011 17:13
[Excel] - Несколько версий Excel на машине клиента Андре DAX: Программирование 11 07.08.2007 13:45

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

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

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