-
Notifications
You must be signed in to change notification settings - Fork 36
Expand file tree
/
Copy pathMoveRowsUsingRangeValues.ts
More file actions
94 lines (81 loc) · 4.18 KB
/
MoveRowsUsingRangeValues.ts
File metadata and controls
94 lines (81 loc) · 4.18 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
function main(workbook: ExcelScript.Workbook) {
// Update the table names, column index to look-up on as needed
const TargetTableName = 'Table1';
const SourceTableName = 'Table2';
const IndexOfColumnToFilterOn = 1; // 0-index
const NameOfColumnToFilterOn = 'Category';
const ValueToFilterOn = 'Clothing';
// Get the table objects
let targetTable = workbook.getTable(TargetTableName);
let sourceTable = workbook.getTable(SourceTableName);
// If you don't know the table names, you can fetch first table on a given worksheet name
// let targetTable = workbook.getWorksheet('Sheet1').getTables()[0];
// let sourceTable = workbook.getWorksheet('Sheet2').getTables()[0];
if (!targetTable || !sourceTable) {
console.log(`Tables missing - Check to make sure both source (${TargetTableName}) and target table (${SourceTableName}) are present before running the script. `);
return;
}
// Save all of the filter criteria
// Initialize an empty object to hold the filter criteria
const tableFilters = {};
// For each table column, collect the filter criteria
sourceTable.getColumns().forEach((column) => {
let colFilterCriteria = column.getFilter().getCriteria();
if (colFilterCriteria) {
// If we don't remove these two keys, the API fails for some reason. So, remove these..
delete colFilterCriteria['@odata.type'];
delete colFilterCriteria['subField'];
tableFilters[column.getName()] = colFilterCriteria;
}
});
// Range object of table data
const sourceRange = sourceTable.getRangeBetweenHeaderAndTotal();
// Get data values of the tablw rows
const dataRows: (number | string | boolean)[][] = sourceTable.getRangeBetweenHeaderAndTotal().getValues();
// Create variables to hold the rows to be moved and their addresses
let rowsToMoveValues: (number | string | boolean)[][] = [];
let rowAddressToRemove: string[] = [];
// Get the data values to insert to target table
for (let i = 0; i < dataRows.length; i++) {
if (dataRows[i][IndexOfColumnToFilterOn] === ValueToFilterOn) {
rowsToMoveValues.push(dataRows[i]);
// Get the intersection between table address and the entire row where we found the match. This provides the address of the range to remove.
let address = sourceRange.getIntersection(sourceRange.getCell(i,0).getEntireRow()).getAddress();
rowAddressToRemove.push(address);
}
}
// If no data rows to process, exit script.
if (rowsToMoveValues.length < 1) {
console.log('No rows selected from the source table that matched the filter criteria.');
return;
}
console.log(`Adding ${rowsToMoveValues.length} rows to target table.`);
// Insert rows at the end of target table. Change the first argument to suit your target location (e.g., 0 for beginning, -1 for end).
targetTable.addRows(-1, rowsToMoveValues)
// Get worksheet reference where the table rows to be deleted resides.
const sheet = sourceTable.getWorksheet();
// Remove all filters before removing rows
sourceTable.getAutoFilter().clearCriteria();
// !!Important!! Reverse the address and remove from the bottom so that the right rows are removed. If not reversed, the resulting row upwards shift will mean that incorrect rows will be removed.
console.log(`Removing ${rowAddressToRemove.length} from the source table. `)
rowAddressToRemove.reverse().forEach((address) => {
sheet.getRange(address).delete(ExcelScript.DeleteShiftDirection.up);
});
// Re-apply filters
// Log the criteria for testing purpose (not required)
console.log(tableFilters);
// Format source table to wrap text (important to do this before applying back filters)
sourceTable.getRange().getFormat().setWrapText(true);
// Re-apply all column filters
reApplyFilters(sourceTable, NameOfColumnToFilterOn, tableFilters);
console.log("Finished.")
return;
}
function reApplyFilters(sourceTable: ExcelScript.Table, columnNameFilteredOn: string, tableFilters: {}): void {
// Re-apply all column filters
Object.keys(tableFilters).forEach((columnName) => {
sourceTable.getColumnByName(columnName).getFilter().apply(tableFilters[columnName]);
});
sourceTable.getColumnByName(columnNameFilteredOn).getFilter().clear();
return;
}