1

I have created a script that will move an entire row to another tab on the worksheet if certain text is entered into a selected cell.

I want to be able to do this if the cell is not empty rather than having certain text and I would like the row to be deleted all except the first column.

The script is below and works really well, I'm not great at coding and managed to cobble this together from some other scripts i found but i now can't manage to edit it to fit this new task.

I tried using Javascript not equals signs and other symbols and can remove rows that are empty but i can't seem to make it work.

    function main(workbook: ExcelScript.Workbook) {
    
        // You can change these names to match the data in your workbook.
        const TARGET_TABLE_NAME = 'TableNAdded';
        const SOURCE_TABLE_NAME = 'TableN';
    
        // Select what will be moved between tables.
        const FILTER_COLUMN_INDEX = 27;
        const FILTER_VALUE = 'Y';
    
        // Get the Table objects.
        let targetTable = workbook.getTable(TARGET_TABLE_NAME);
        let sourceTable = workbook.getTable(SOURCE_TABLE_NAME);
    
        // If either table is missing, report that information and stop the script.
        if (!targetTable || !sourceTable) {
            console.log(`Tables missing - Check to make sure both source (${TARGET_TABLE_NAME}) and target table (${SOURCE_TABLE_NAME}) are present before running the script. `);
            return;
        }
    
        // Save the filter criteria currently on the source table.
        const originalTableFilters = {};
        // For each table column, collect the filter criteria on that column.
        sourceTable.getColumns().forEach((column) => {
            let originalColumnFilter = column.getFilter().getCriteria();
            if (originalColumnFilter) {
                originalTableFilters[column.getName()] = originalColumnFilter;
            }
        });
    
        // Get all the data from the table.
        const sourceRange = sourceTable.getRangeBetweenHeaderAndTotal();
        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 from the source table.
        for (let i = 0; i < dataRows.length; i++) {
            if (dataRows[i][FILTER_COLUMN_INDEX] === FILTER_VALUE) {
                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 there are no data rows to process, end the script.
        if (rowsToMoveValues.length < 1) {
            console.log('No rows selected from the source table match the filter criteria.');
            return;
        }
    
        console.log(`Adding ${rowsToMoveValues.length} rows to target table.`);
    
        // Insert rows at the end of target table.
        targetTable.addRows(-1, rowsToMoveValues)
    
        // Remove the rows from the source table.
        const sheet = sourceTable.getWorksheet();
    
        // Remove all filters before removing rows.
        sourceTable.getAutoFilter().clearCriteria();
    
        // Important: Remove the rows starting at the bottom of the table.
        // Otherwise, the lower rows change position before they are deleted.
        console.log(`Removing ${rowAddressToRemove.length} rows from the source table.`);
        rowAddressToRemove.reverse().forEach((address) => {
            sheet.getRange(address).delete(ExcelScript.DeleteShiftDirection.up);
        });
    
        // Reapply the original filters. 
        Object.keys(originalTableFilters).forEach((columnName) => {
            sourceTable.getColumnByName(columnName).getFilter().apply(originalTableFilters[columnName]);
        });
    }
Brian Gonzalez
  • 1,178
  • 1
  • 3
  • 15
Eti
  • 23
  • 4
  • Is this the line of code you're trying to get help on? `if (dataRows[i][FILTER_COLUMN_INDEX] === FILTER_VALUE)` Instead of it being assigned to FILTER_VALUE, do you want to see if this value is blank? If not, can you specify which cell the selected cell you're referring to is? – Brian Gonzalez Feb 01 '23 at 14:38
  • Thanks for your response. I want to see whether cells in the following column are blank: const FILTER_COLUMN_INDEX = 27 If that section of the text can be changed to is blank that would be great. – Eti Feb 02 '23 at 09:46

1 Answers1

0

If I understand your question correctly, you are currently filtering the table if the value = "Y" (the value assigned to FILTER_VALUE). This part is happening here:

    if (dataRows[i][FILTER_COLUMN_INDEX] === FILTER_VALUE) {

You'd like to update this line from checking if the cell value is Y to checking if the cell value is not empty. To do this, you can update this line like so:

    if (dataRows[i][FILTER_COLUMN_INDEX] as string !== "") {
Brian Gonzalez
  • 1,178
  • 1
  • 3
  • 15
  • That works brilliantly thank you so much. Cheeky extra question. If i wanted to not delete the first column do you know which part i would edit? – Eti Feb 02 '23 at 14:56
  • I know it may seem tedious but you should ask that as part of a new question. That will help others find the question in the future if they're trying to do similar things to what you're doing now. So if you do that I will answer your question. – Brian Gonzalez Feb 02 '23 at 16:49
  • Thanks. I will do. It was originally part of this question but it was edited out. :) – Eti Feb 06 '23 at 10:01