Skip to main content

Sort tables

Automatically sorts table rows alphabetically or numerically based on the selected column.

tip

Please select the entire column by which you want the table to be sorted. The macro will only work correctly if the whole column is selected.

(function() {
let isFirstRowIncluded = false; // Set to true to include the header row in sorting

let doc = Api.GetDocument();
let pageIndex = doc.GetCurrentPage();
let tables = doc.GetAllTablesOnPage(pageIndex);

let selectedRange = doc.GetRangeBySelect();
let selectedStart = selectedRange.GetStartPos();
let selectedEnd = selectedRange.GetEndPos();

// Compares two cell values: numerically if both are numbers, alphabetically otherwise
function compareCells(a, b) {
let numA = parseFloat(a);
let numB = parseFloat(b);
if (!isNaN(numA) && !isNaN(numB)) {
return numA - numB;
}
return a.localeCompare(b);
}

// Collects and sorts rows by the specified column
function sortRowsByColumn(table, colIndex, startRow) {
let rowsArr = [];
let rowNum = table.GetRowsCount();

for (let rowIndex = startRow; rowIndex < rowNum; rowIndex++) {
let row = table.GetRow(rowIndex);
let cellVal = row.GetCell(colIndex).GetContent().GetText();
rowsArr.push({ row, cellVal });
}

rowsArr.sort((a, b) => compareCells(a.cellVal, b.cellVal));
return rowsArr.map(item => item.row);
}

// Finds the index of the column that contains the selection start position
function findSelectedColIndex(table, selectedStart) {
let rowNum = table.GetRowsCount();
let colNum = table.GetRow(0).GetCellsCount();
for (let rowIndex = 0; rowIndex < rowNum; rowIndex++) {
for (let colIndex = 0; colIndex < colNum; colIndex++) {
let cell = table.GetCell(rowIndex, colIndex);
let cellStart = cell.GetContent().GetRange().GetStartPos();
let cellEnd = cell.GetContent().GetRange().GetEndPos();
if (selectedStart >= cellStart && selectedStart <= cellEnd) {
return colIndex;
}
}
}
return -1;
}

for (let i = 0; i < tables.length; i++) {
let table = tables[i];
let rowNum = table.GetRowsCount();
let colNum = table.GetRow(0).GetCellsCount();
let tableStart = table.GetCell(0, 0).GetContent().GetRange().GetStartPos();
let tableEnd = table.GetCell(rowNum - 1, colNum - 1).GetContent().GetRange().GetEndPos();

if (selectedStart >= tableStart && selectedEnd <= tableEnd) {
let selectedColIndex = findSelectedColIndex(table, selectedStart);

if (selectedColIndex !== -1) {
let startRow = isFirstRowIncluded ? 0 : 1;
let sortedRowsArr = sortRowsByColumn(table, selectedColIndex, startRow);
let rowToRemove = isFirstRowIncluded ? 0 : 1;

for (let k = 0; k < sortedRowsArr.length; k++) {
let sortedRow = sortedRowsArr[k];
let newRow = table.AddRow();

for (let j = 0; j < colNum; j++) {
let text = sortedRow.GetCell(j).GetContent().GetText().trim();
newRow.GetCell(j).GetContent().GetElement(0).AddText(text);
}
table.GetRow(rowToRemove).Remove();
}
}
}
}
})();

Methods used: GetDocument, GetCurrentPage, GetAllTablesOnPage, GetRangeBySelect, GetStartPos, GetEndPos, GetRowsCount, GetRow, GetCellsCount, GetCell, GetCell, GetContent, GetRange, GetText, AddRow, GetElement, AddText, Remove

Result

SortTables SortTables