优化功能以可变数量复制选定数据的列 (up/down)

Optimised Function to copy columns of selected data by a variable amount (up/down)

是否可以创建一个可以在宏中使用的 javascript 函数,当按可变行移动数据列时,可以将数据移动一定量。例如,通过将参数(iRow?)传递给 setcolumn 之类的东西,它会在上方插入数据(-1 丢失第一个值然后插入,这就像将列数据向上移动一行)或 + 2(将前两行列数据空白,然后粘贴其余数据,这就像将其向下移动两列?

在处理大量数据(数百万行)时针对速度进行了理想优化。几个例子。 Col1 是源数据,Col2 正在复制该列并向上移动一行 (-1)。 Col3 正在复制初始 col 并向下移动两个 (+2):

Data Data-1 Data+2
00000001 00000002
00000002 00000003
00000003 00000004 00000001
00000004 00000005 00000002
00000005 00000006 00000003
00000006 00000007 00000004
00000007 00000008 00000005
00000008 00000009 00000006
00000009 00000010 00000007
00000010 00000008

我为 EmEditor 写了一个 JavaScript 宏。 MoveCells( -1, true ) 将 selected 单元格复制到右侧,MoveCells( 1, false ) 将 selected 单元格向下移动。

// yShift : Specify how many rows to shift (move) the cell selection ( >0 : down, <0 : up )
function MoveCells( yShift, bCopy )
{
    if( !yShift || yShift == 0 ) {
        Quit();
    }
    if( !document.CellMode ) {   // Must be cell selection mode
        alert( "Cell selection mode must be turned on" );
        Quit();
    }

    xTop = document.selection.GetTopPointX(eePosCellLogical);
    yTop = document.selection.GetTopPointY(eePosCellLogical);
    xBottom = document.selection.GetBottomPointX(eePosCellLogical);
    yBottom = document.selection.GetBottomPointY(eePosCellLogical);

    yLines = document.GetLines();   // retrieve the number of lines
    if( document.GetLine( yLines ).length == 0 ) {  // -1 if the last line is empty
        --yLines;
    }

    if( yTop < 0 || xTop < 0 || xBottom < 0 || yBottom < 0 ) {
        alert( "Incorrect selection" );
        Quit();
    }
    if( xTop != xBottom ) {
        alert( "More than one columns are selected" );
        Quit();
    }

    bOldRedraw = Redraw;
    Redraw = false;
    bOldCombineHistory = CombineHistory;
    CombineHistory = false;
    yFirstLine = document.HeadingLines + 1;
    if( (yShift < 0 && yTop + yShift < yFirstLine) || (yShift > 0 && yBottom + yShift > yLines) ) {
        if( yShift < 0 ) {
            document.selection.SetActivePoint( eePosCellLogical, xTop, yFirstLine );  // move to the first line
            nCount = yFirstLine - (yTop + yShift);
            for( i = 0; i < nCount; ++i ) {
                document.selection.LineOpen(true);
            }
            yTop += nCount;
            yBottom += nCount;
        }
        else {
            document.selection.SetActivePoint( eePosCellLogical, xTop, yLines );  // move to the first line
            nCount = yBottom + yShift - yLines;
            for( i = 0; i < nCount; ++i ) {
                document.selection.LineOpen(false);
            }
        }
    }

    sDelimiter = document.Csv.Delimiter;  // retrieve the delimiter
    str = document.GetColumn( xTop, sDelimiter, eeCellIncludeQuotes, yTop, yBottom - yTop + 1 );  // get cell selections from top to bottom, separated by delimiter

    if( bCopy ) {
        ++xTop
        document.InsertColumn( xTop );
    }

    if( yShift > 0 ) {  // shift down
        for( i = 0; i < yShift; ++i ) {  // insert delimiters before the copied string
            str = sDelimiter + str;
        }
        document.SetColumn( xTop, str, sDelimiter, eeDontQuote, yTop );
    }
    else {              // shift up
        for( i = 0; i < -yShift; ++i ) {  // add delimiters to the copied string
            str += sDelimiter;
        }
        document.SetColumn( xTop, str, sDelimiter, eeDontQuote, yTop + yShift );
    }

    document.selection.SetActivePoint( eePosCellLogical, xTop, yTop + yShift );  // move the current selection
    document.selection.SetActivePoint( eePosCellLogical, xTop, yBottom + yShift, true );

    Redraw = bOldRedraw;
    CombineHistory = bOldCombineHistory;
}

// Here is the main code
MoveCells( -1, true );  // Copy the selection up to right
MoveCells( 2, false );  // Move the selection down

为了运行这个,将这个代码保存为,例如Macro.jsee,然后select这个文件来自Select... 菜单中。最后,select 运行 Macro.jseeMacros 菜单中,同时当前 CSV 文档处于活动状态。

参考文献: