Некоторым боком сегодня был недалеко от этой темы и набросал небольшой пример. Немного помучался, куда помещать это сообщение - сюда или в свой
"блог". Решил всё же сюда, так как здесь уже имеется интересное готовое обсуждение.
Простенький статический метод. Без больших претензий. Построчно выводит в буфер текстовые представления значений (valueStr) контролов грида (со строкой заголовков). Не умеет работать с выделенными строками, но учитывает сортировку, фильтрацию, перестановку и скрытие колонок пользователем. И нумерует строчки - о как!
Может быть помещен, например, в Global или аналогичный класс - набор утилит (у меня такой класс называется KKu - я предпочитаю не портить фирменный Global ).
X++:
static TextBuffer gridToBuffer( FormRun _formRun,
str _gridName,
str _separator = '\t')
{
FormGridControl grid;
FormControl control;
FormDataSource formDataSource;
Common common;
int i;
int row;
str lineToBuffer;
TextBuffer textBuffer = new TextBuffer();
;
grid = _formRun.design().controlName(_gridName);
// заголовки колонок (label) -> вывод в буфер
lineToBuffer = strfmt('%1%2', 'Row', _separator);
for (i=1; i<=grid.controlCount(); i++)
{
control = grid.controlNum(i);
if (control.isDisplayed())
{
lineToBuffer += strFmt('%1%2', control.labelText(), _separator);
}
}
lineToBuffer = subStr( lineToBuffer, 1, strLen(lineToBuffer)-strLen(_separator) );
textBuffer.appendText( lineToBuffer + '\n' );
// ищем датасорс грида
for (i=1; i<=_formRun.dataSourceCount(); i++)
{
if (_formRun.dataSource(i).id() == grid.dataSource())
{
formDataSource = _formRun.dataSource(i);
break;
}
}
// неявный цикл по строкам грида (явный - по датасорсу)
row = 0;
for ( common = formDataSource.getFirst() ? formDataSource.getFirst() : formDataSource.cursor();
common ;
common = formDataSource.getNext() )
{
row++;
if (row==1)
{
formDataSource.first();
}
else
{
formDataSource.next();
}
// очередная строка -> вывод в буфер
lineToBuffer = strFmt('%1%2', row, _separator);
for (i=1; i<=grid.controlCount(); i++)
{
control = grid.controlNum(i);
if (control.isDisplayed())
{
lineToBuffer += strFmt('%1%2',
strReplace(strReplace( control.valueStr(), '\n',' '), '\r',' '), _separator);
}
}
lineToBuffer = subStr( lineToBuffer, 1, strLen(lineToBuffer)-strLen(_separator) );
textBuffer.appendText( lineToBuffer + '\n' );
}
return textBuffer;
}
Для тестирования вызов метода можно повесить на какое-нибудь событие для грида. Мне нравится двойной щелчок - mouseDblClick. И русская форма "Основные средства" (RAssetTable), грид на первой вкладке "Обзор".
X++:
public int mouseDblClick(int _x, int _y, int _button, boolean _Ctrl, boolean _Shift)
{
int ret;
ret = super(_x, _y, _button, _Ctrl, _Shift);
KKu::gridToBuffer(element, 'Grid').toClipboard();
return ret;
}
Щелкать надо либо по строке слева (по серому квадратику полосы выделения), либо по сетке между ячейками (указатель при этом не меняет форму). Перед щелчком по сетке указатель мыши надо либо подвести к вертикальной линии между соседними ячейками в строке так, чтобы он сливался с этой линией, либо навести указатель на горизонтальную линию сетки между соседними строками так, чтобы эта линия делила указатель примерно пополам. Не следует щелкать по самим ячейкам - это зона ответственности mouseDblClick того контрола, по которому произведен щелчок, и до грида этот щелчок не дойдет.
После двойного щелчка и наблюдения за тем, как пробежит вниз бегунок вертикальной полосы прокрутки, можно перейти в Excel и выполнить вставку. Если у вас очень много основных средств, желательно сначала наложить фильтр, чтобы в рамках эксперимента разумно ограничить количество строк в буфере.