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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 21.05.2014, 19:06   #1  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,716 / 1204 (44) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
Кстати, может просто "мусор" остался в буфере обмена после последнего tb.toClipboard()? В смысле, первая команда rows.copy() пытается скрестить "ежа и ужа". Часть буфера от Windows загнанный в tb.toClipboard() и часть буфера от OWC через rows.copy()

Попробуй сначала сделать оба листа и только потом наполнять их данными через tb.toClipboard() + range.paste()

Я бы еще поэкспериментировал с копированием без параметра. Т.е. через буфер обмена.

X++:
        // Выделяю образцовую строку
        bookMark  = int2str(_rowTemplate) + ":" + int2str(_rowTemplate);
        range   = sheet.range(bookMark);
        // Копирую ее содержимое со всеми форматами в буфер обмена
        range.copy();
        // Вставляю из буфера обмена в строку ниже (под выделенной)
        range.insert(#xlDown);
У меня для вставки в Excel написан свой метод в классе SysExcelWorksheet. Попробуй его адаптировать под OWC SpreadSheet.

X++:
/*
    Вставка указанного количества строк, как копии одной строки шаблона
    _rowTemplate - номер строки, которая будет размножена (скопирована)
    _rowsInsert - количество строк, вставляемых ПОД указанной строкой шаблона

    При вставке указанным способом "раздвигается" диапазон ячеек для суммирования если вставка выполняется "внутри" диапазона формулы

    Для сохранения суммирования в шаблоне надо делать минимум 2 строки "деталей" (чтобы была возможность указать диапазон в формуле),
    а вставку выполнять после второй строки "деталей", используя эту вторую строку как шаблон
*/
void insertRowsAsCopy(Row _rowTemplate, Row _rowsInsert)
{
    MSOfficeBookMark_RU bookMark;
    SysExcelRange       sysExcelRange;

    Row     currentRow,
            insertedRows;
    ;

    if (_rowsInsert < 2)
    {
        return;
    }

    // Итерационный цикл
    // Вставляю сначала 1, потом 2, 4, 8 и т.п. строк на последнем шаге вставляю остаток строк
    currentRow = 1;
    while (currentRow < _rowsInsert)
    {
        if (currentRow * 2 <= _rowsInsert)
        {
            insertedRows = currentRow;
            currentRow  += insertedRows;
        }
        else
        {
            insertedRows = _rowsInsert - currentRow;
            currentRow   = _rowsInsert;
        }
        bookMark        = int2str(_rowTemplate) + ":" + int2str(_rowTemplate + insertedRows - 1);
        sysExcelRange   = this.range(bookMark);
        sysExcelRange.copy();
        sysExcelRange.insert(#xlDown);
    }   // while (currentRow < _rowsInsert)
/*
        // Прямая вставка указанного количества
        // По времени одинаков с итерационным циклом, но имеет недостатки
        // 1) Нужно физическое наличие необходимого количества пустых строк
        // 2) В качестве "конца листа" (последней использованной ячейки) будет удвоенное количество вставляемых строк
        // т.е. переход по Ctrl+End выбросит далеко за конец информационной части отчета

        // Выделяю нужное количество строк ПОД итоговой строкой
        bookMark        = int2str(_rowTemplate+1)+":"+int2str(_rowTemplate+1+_rowsInsert-1);
        sysExcelRangeSource   = this.range(bookMark);
        sysExcelRangeSource.comObject().cut();

        // Вставляю выделенные строки перед второй строкой
        bookMark            = int2str(_rowTemplate)+":"+int2str(_rowTemplate);
        sysExcelRangeTarget = this.range(bookMark);
        sysExcelRangeTarget.insert(#xlDown);

        // Выделяю образцовую строку
        bookMark            = int2str(_rowTemplate)+":"+int2str(_rowTemplate);
        sysExcelRangeSource = this.range(bookMark);
        // Копирую образцовую строку со всеми формулами во вновь добавленные строки
        bookMark            = int2str(_rowTemplate)+":"+int2str(_rowTemplate+_rowsInsert-1);
        sysExcelRangeTarget = this.range(bookMark);
        sysExcelRangeSource.comObject().copy(sysExcelRangeTarget.comObject());
*/

}
__________________
- Может, я как-то неправильно живу?!
- Отчего же? Правильно. Только зря...
Старый 22.05.2014, 14:27   #2  
sashanka is offline
sashanka
Участник
 
28 / 10 (1) +
Регистрация: 07.02.2013
Цитата:
Сообщение от Владимир Максимов Посмотреть сообщение
Кстати, может просто "мусор" остался в буфере обмена после последнего tb.toClipboard()? В смысле, первая команда rows.copy() пытается скрестить "ежа и ужа". Часть буфера от Windows загнанный в tb.toClipboard() и часть буфера от OWC через rows.copy()

Попробуй сначала сделать оба листа и только потом наполнять их данными через tb.toClipboard() + range.paste()

Я бы еще поэкспериментировал с копированием без параметра. Т.е. через буфер обмена.

X++:
        // Выделяю образцовую строку
        bookMark  = int2str(_rowTemplate) + ":" + int2str(_rowTemplate);
        range   = sheet.range(bookMark);
        // Копирую ее содержимое со всеми форматами в буфер обмена
        range.copy();
        // Вставляю из буфера обмена в строку ниже (под выделенной)
        range.insert(#xlDown);
Последовательность действий такова:
  1. подгружаю шаблон xlt
  2. открываю лист шаблон
  3. копирую его
  4. далее начинаю заполнять новый лист данными с помощью TextBuffer
Ошибка появляется даже если 1 лист добавить копированием и попытаться туда что-то записать.

Если вставлять новые строки по одной то время выгрузки увеличивается в разы.

Насчет вставки строк - я вроде так и делаю

X++:
    COM         worksheets,
                sheet,
                newsheet,
                range,
                rows,
                newRows,
                cell;

    TextBuffer  tb;

    Table1      table1;
    Table2      table2;

    int         curRow,
                numRows;

    ;
    //загрузка шаблона
    GridExcel.XMLURL("S:\\testSpreadSheet.xml");

    worksheets  = GridExcel.Worksheets();

    //выделем нужную строчку на шаблоне
    sheet       = worksheets.Item(1);
    range       = sheet.Range("A9:F9");
    curRow      = 9;

    //подсчитываем кол-во необходимых для вставки строк
    select count(recid) from table1;
    numRows = table1.RecId;

    if( numRows <= 1 )
    {
        return;
    }

    //вставляем строки
    rows    = sheet.Rows();
    newRows = rows.Item( strfmt("%1:%2", curRow + 1,NumRows + curRow) ); //вставляем после выделенной строки
    newRows.Insert();

    //копируем нужный формат
    newRows = rows.Item( strfmt("%1:%2", curRow + 1,NumRows + curRow) ); //куда будем копировать форматирование
    rows = range.EntireRow(); //откуда будем копировать форматирование
    rows.copy( newRows );
Старый 25.05.2014, 18:34   #3  
Владимир Максимов is offline
Владимир Максимов
Участник
КОРУС Консалтинг
 
1,716 / 1204 (44) ++++++++
Регистрация: 13.01.2004
Записей в блоге: 3
Цитата:
Сообщение от sashanka Посмотреть сообщение
Насчет вставки строк - я вроде так и делаю
У Вас много лишних "телодвижений" Если очистить код от лишних действий, то должно быть примерно так

X++:
    COM         worksheets,
                sheet,
                rowTemplate,
                newRows;
    int         curSheet;
    int         curRow,
                numRows;


    worksheets  = GridExcel.Worksheets();

    // Сразу создаем нужное количество листов по образцу первого листа
    sheet = worksheets.Item(1);
    sheet.copy( sheet );

    for (curSheet = 1; curSheet <= 2; curSheet++)
    {
        //выделем нужную строчку на шаблоне
        sheet       = worksheets.Item(curSheet);
        curRow      = 9;

        //подсчитываем кол-во необходимых для вставки строк
        select count(recid) from table1;
        numRows = table1.RecId;

        if (!numRows)
        {
            warning('Нет данных для вставки на листе ' + int2str(curSheet));
            continue;
        }
    
        //вставляем строки
        newRows = sheet.Range(strfmt("%1:%2", curRow + 1,NumRows + curRow) ); //вставляем после выделенной строки
        newRows.Insert();

        //копируем нужный формат
        rowTemplate = sheet.Range(strfmt("%1:%2", curRow, curRow) ); //откуда будем копировать форматирование
        rowTemplate.copy( newRows );

    }   // for (curSheet = 1; curSheet <= 2; curSheet++)

PS: Для справки

OWC SpreadSheet имеет предел в 32766 операций. Не важно каких. Например, не в состоянии вставить большее количество строк. У Вас какое значение numRows получается для второго листа?
__________________
- Может, я как-то неправильно живу?!
- Отчего же? Правильно. Только зря...

Последний раз редактировалось Владимир Максимов; 25.05.2014 в 18:38.
Теги
errors, spreadsheet

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
palleagermark: Easy reusable method to load postal codes (zipcodes) or how to save a spreadsheet as XML Blog bot DAX Blogs 0 11.10.2013 19:11
palleagermark: XML transformation from Excel spreadsheet Blog bot DAX Blogs 0 22.11.2012 14:11
Медленное копирование данных из Spreadsheet в PivotTable PSerg DAX: Программирование 0 12.08.2009 10:19
SpreadSheet if_maks DAX: База знаний и проекты 8 22.12.2005 12:42
Использование OWC.Spreadsheet для ускорения экспорта/импорта в/из Excel. storer DAX: Программирование 24 28.03.2005 19:10
Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра
Комбинированный вид Комбинированный вид

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

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

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