Показать сообщение отдельно
Старый 04.09.2008, 19:06   #17  
Gustav is offline
Gustav
Moderator
Аватар для Gustav
SAP
Лучший по профессии 2009
 
1,858 / 1152 (42) ++++++++
Регистрация: 24.01.2006
Адрес: Санкт-Петербург
Записей в блоге: 19
Некоторым боком сегодня был недалеко от этой темы и набросал небольшой пример. Немного помучался, куда помещать это сообщение - сюда или в свой "блог". Решил всё же сюда, так как здесь уже имеется интересное готовое обсуждение.

Простенький статический метод. Без больших претензий. Построчно выводит в буфер текстовые представления значений (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 и выполнить вставку. Если у вас очень много основных средств, желательно сначала наложить фильтр, чтобы в рамках эксперимента разумно ограничить количество строк в буфере.