|
|
#1 |
|
Участник
|
SpreadSheet for dummies
Доброго времени суток.
На форме имеется SpreadSheet 11.0, с установленным в Yes свойством AutoDeclaration. При загрузке формы в SpreadSheet подгружается и наполняется данными шаблон : 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;
//вставляем строки
rows = sheet.Rows();
newRows = rows.Item( strfmt("%1:%2", curRow + 1,NumRows + curRow) ); //вставляем после выделенной строки
newRows.Insert();
//копируем нужный формат
newRows = rows.Item( strfmt("10:%1", NumRows + curRow) ); //куда будем копировать форматирование
rows = range.EntireRow(); //откуда будем копировать форматирование
rows.copy( newRows );
//заполняем подготовленные строки данными
tb = new TextBuffer();
while select table1
{
tb.setText( strfmt( "%1\t%2\t%3\t%4\t%5\t%6",
table1.ItemName,
table1.Qty,
table1.PurchPrice,
table1.PurchPriceAmount,
table1.VendName,
table1.Invoice)
);
tb.toClipboard();
range.paste();
curRow++;
range = sheet.range("A" + int2str(curRow ) + ":F" + int2str(curRow ) ); //переход на следующую строчку
}
tb.setText("");
//добавляем строчку Итого
cell = range.item(1,1); cell.value2("Итого");
cell = range.item(1,4); cell.value2(strfmt( '=SUM(R[-%1]C:R[-1]C)', numRows));
//делаем шрифт строки жирным
cell = range.Font();
cell.bold(true);НО стоит только захотеть проделать все те же операции в другом листе книги, скопированном с первого: X++: sheet.copy( sheet );
newsheet = worksheets.Item(1); //так как вставка нового листа происходит перед существующим
range = newsheet.Range("A9:F9");Цитата:
Метод "copy" в COM-объекте класса "_Range" возвратил код ошибки 0x800A03EC (<неизвестно>), который означает: <неизвестно>.
- необходимое кол-во строк на новый лист добавляется, они выделяются и их можно заполнить каким-либо значением из кода; ![]() На данный момент проблема "решена" копированием всех строк из шаблона в новый лист, а там уже аналогично вставляем новые строки и форматируем их. Новый лист добавляется с помощью X++: newsheet = worksheets.add(); Шаблон прилагается
Последний раз редактировалось sashanka; 19.05.2014 в 19:47. |
|
|
|
|
#2 |
|
Участник
|
"На вскидку" метод EntireRow относится к активному в данный момент листу Excel (SpreadSheet). Но вновь созданный лист не является активным. Его надо либо активизировать принудительно, либо вместо метода EntireRow использовать явное указание строки через Rows().
либо так X++: sheet.copy( sheet ); newsheet = worksheets.Item(1); newsheet.select(); // Принудительно активируем лист для корректной работы EntireRow X++: //копируем нужный формат newRows = rows.Item( strfmt("10:%1", NumRows + curRow) ); //куда будем копировать форматирование // rows = range.EntireRow(); //откуда будем копировать форматирование rows = rows.Item( strfmt("%1:%2", curRow, curRow) ); //откуда будем копировать форматирование rows.copy( newRows );
__________________
- Может, я как-то неправильно живу?! - Отчего же? Правильно. Только зря... |
|
|
|
|
#3 |
|
Участник
|
Спасибо за ответ. Ни один из способов не подошел.
Проверила еще X++: sheet.copy( sheet );
newsheet = worksheets.Item(1); //так как вставка нового листа просиходит перед существующим
newsheet.Activate(); |
|
|
|
|
#4 |
|
Участник
|
Кстати, может просто "мусор" остался в буфере обмена после последнего 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); 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()); */ }
__________________
- Может, я как-то неправильно живу?! - Отчего же? Правильно. Только зря... |
|
|
|
|
#5 |
|
Участник
|
Цитата:
Сообщение от Владимир Максимов
Кстати, может просто "мусор" остался в буфере обмена после последнего 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);
Если вставлять новые строки по одной то время выгрузки увеличивается в разы. Насчет вставки строк - я вроде так и делаю 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 ); |
|
|
|
|
#6 |
|
Участник
|
У Вас много лишних "телодвижений"
Если очистить код от лишних действий, то должно быть примерно так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 |
|
|
|