Good morning,
I am working thru a problem and I cannot use VBA as that will disallow autosave to be on (which our company requires on this specific document).
I have two tables on two separate sheets. I would like to MOVE completed jobs from "Job" table to "CompletedJobs" table.
The column for criteria of Complete, which will simple have a "Y" is U:U.
This issue is causing me lots of problems and I just cannot figure it out. Can anyone help?
Having any set filters within the script is not an absolute requirement.
The script that i have input is not returning any rows. Not sure what needs to be adjusted.
https://drive.google.com/drive/folders/11JhtjSVmXZ7WeKEc4GTfCRJL-wtAPgzV?usp=share_link
function main(workbook: ExcelScript.Workbook) {
// Update the table names, column index to look-up on as neededconst TargetTableName = 'Job';const SourceTableName = 'CompletedJobs';const IndexOfColumnToFilterOn = 19; // 0-indexconst NameOfColumnToFilterOn = 'Complete';const ValueToFilterOn = 'Y';
// Get the table objectslet 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('Table test').getTables()[0];// let sourceTable = workbook.getWorksheet('Completed Jobs').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 criteriaconst tableFilters = {};// For each table column, collect the filter criteriasourceTable.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 dataconst sourceRange = sourceTable.getRangeBetweenHeaderAndTotal();// Get data values of the tablw rowsconst dataRows: (number | string | boolean)[][] = sourceTable.getRangeBetweenHeaderAndTotal().getValues();
// Create variables to hold the rows to be moved and their addresseslet rowsToMoveValues: (number | string | boolean)[][] = [];let rowAddressToRemove: string[] = [];
// Get the data values to insert to target tablefor (let i = 19; 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, 19).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 rowssourceTable.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 filtersreApplyFilters(sourceTable, NameOfColumnToFilterOn, tableFilters);console.log("Finished.")return;}
function reApplyFilters(sourceTable: ExcelScript.Table, columnNameFilteredOn: string, tableFilters: {}): void {
// Re-apply all column filtersObject.keys(tableFilters).forEach((columnName) => {sourceTable.getColumnByName(columnName).getFilter().apply(tableFilters[columnName]);});sourceTable.getColumnByName(columnNameFilteredOn).getFilter().clear();return;}