Is it possible to create a javascript function that can be used in macros, that can move data by an amount when moving columns of data by variable rows. For example, by passing a parameter (iRow?) to something like setcolumn and it would insert the data either above (-1 to lose the first value and then insert which is like moving the column data up one line up for example) or 2 (to blank the first 2 rows column data and then paste the rest of the data, which is like moving it down 2 columns?
Ideally optimised for speed when working on very large amounts of data (millions of rows). Couple of examples. Col1 is source data, Col2 is copying that column and moving up by one row (-1). Col3 is copying that initial col and moving down by two ( 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 |
CodePudding user response:
I wrote a JavaScript for EmEditor macro. MoveCells( -1, true )
copies the selected cells up to right, and MoveCells( 1, false )
moves the selected cells down.
// 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
To run this, save this code as, for instance, Macro.jsee
, and then select this file from Select... in the Macros menu. Finally, select Run Macro.jsee in the Macros menu while the current CSV document is active.
References: