Google Sheet App Script - How to only setValues only unique values

sojim2

In this spreadsheet: https://docs.google.com/spreadsheets/d/1givNbMvgzD8lbk6NAcwjkpp4-A_D8MetltHjEpinOAI/edit#gid=0

I'd like to Combine only unique Links and Category into Combined sheet.

Right now, with my script, it can only combine all existing data:

function combine() {
    var ss = SpreadsheetApp.getActive();
    var allsheets = ss.getSheets();
    var sourceID = '1givNbMvgzD8lbk6NAcwjkpp4-A_D8MetltHjEpinOAI';
    var targetID = '1givNbMvgzD8lbk6NAcwjkpp4-A_D8MetltHjEpinOAI';

    var sheetExclude = ["Combined"];
    var sheetExcludeIndex = new Array(sheetExclude.length);

    for (var s in allsheets) {
        var sheet = allsheets[s];
        for (var e in sheetExclude) {
            if (String(sheet.getName() == sheetExclude[e])) {
                sheetExcludeIndex[e] = sheet.getIndex;

            }
        }
    }


    allsheets.splice(sheetExcludeIndex, sheetExclude.length);

    for (var s in allsheets) {
        var sheet = allsheets[s];
        updateSourceToTarget(sourceID, sheet.getName(), targetID, 'Combined');
    }
}

function updateSourceToTarget(sourceID, sourceName, targetID, targetname) {
    Logger.log(sourceID + ' ' + sourceName + ' ' +targetname);
    var source = SpreadsheetApp.openById(sourceID).getSheetByName(sourceName);
    var destination = SpreadsheetApp.openById(targetID).getSheetByName(targetname);
    var sourcelastRow = source.getLastRow();
    var sourcelastCol = source.getLastColumn();
    var destinationlastRow = destination.getLastRow();
    var destinationlastCol = destination.getLastColumn();
    var sourcedata = source.getRange(2, 9, sourcelastRow, 10).getValues();


    destination.getRange(destinationlastRow + 1, 2, sourcelastRow, sourcelastCol).setValues(sourcedata);
}

However, I'd like to only combine unique links from Sheet2 and Sheet3:

In red is unique data

Sheet2: enter image description here

Sheet3: enter image description here

How can I efficiently add only unique values to Combined from Sheet2& Sheet3?

Tanaike
  • You want to put the values, which removed the duplicated links, to the target sheet (in this case, it's Combined sheet.).
  • The duplicated links are checked from the target sheet and source sheets. In this case, the target sheet and source sheets are Combined, Sheet2 and Sheet3, respectively.
    • In your sample Spreadsheet, you want to put the following rows to the target sheet.
      • https://thehill.com/policy/national-security/department-of-homeland-security/460158-new-hampshire-border-patrol BorderSecurity
      • https://abcnews.go.com/International/climate-change-frontier-worlds-northernmost-town/story?id=65381362 ClimateChange
  • You want to achieve this by modifying your Google Apps Script.

If my understanding is correct, how about this modification? Please think of this as just one of several answers.

Modified script:

Please modify your script as follows. In this modification, your function of updateSourceToTarget() is not used.

From:

for (var s in allsheets) {
    var sheet = allsheets[s];
    updateSourceToTarget(sourceID, sheet.getName(), targetID, 'Combined');
}

To:

// Retrieve values from the target sheet.
var targetSheet = ss.getSheetByName(sheetExclude[0]);
var targetValues = targetSheet.getRange("B2:C" + targetSheet.getLastRow()).getValues();

// Retrieve values from all source sheets. <--- Modified
var sourceValues = allsheets.reduce(function(ar, sheet) {
  var v = sheet.getRange(2, 9, sheet.getLastRow() - 1, 10).getValues().filter(function(r) {return r[0] && r[1]});
  if (v.length > 0) {
    v = v.filter(function(e) {return !ar.some(function(f) {return e[0] === f[0]})});
    Array.prototype.push.apply(ar, v);
  }
  return ar;
}, []);

// Remove the duplication values between the target sheet and all source sheets.
var dstValues = sourceValues.filter(function(e) {return !targetValues.some(function(f) {return e[0] === f[0]})});

// Add the result values to the target sheet.
if (dstValues.length > 0) {
  var destination = SpreadsheetApp.openById(targetID).getSheetByName(sheetExclude[0]);
  destination.getRange(destination.getLastRow() + 1, 2, dstValues.length, dstValues[0].length).setValues(dstValues);
}

The flow of this modified script is as follows.

  1. Retrieve values from the target sheet.
  2. Retrieve values from all source sheets.
  3. Remove the duplication values between the target sheet and all source sheets.
  4. Add the result values to the target sheet.

Note:

  • When your shared Spreadsheet is used as the target (Combined) and source sheets (Sheet2 and Sheet3), the following rows are added to the target sheet.
    • https://thehill.com/policy/national-security/department-of-homeland-security/460158-new-hampshire-border-patrol BorderSecurity
    • https://abcnews.go.com/International/climate-change-frontier-worlds-northernmost-town/story?id=65381362 ClimateChange

References:

If I misunderstood your question and this was not the direction you want, I apologize.

Added:

In this additional script, a hash table is used for this situation, as mentioned by TheMaster's comment. For example, a sample can be also seen at this thread. In your situation, at first, all values are retrieved from all sheets including Combined sheet, and the hash table is created. By this, the duplicated values are removed. Then, the converted values to an array are put to the Spreadsheet.

Sample script:

Please modify your script as follows.

From:
allsheets.splice(sheetExcludeIndex, sheetExclude.length);

for (var s in allsheets) {
    var sheet = allsheets[s];
    updateSourceToTarget(sourceID, sheet.getName(), targetID, 'Combined');
}
To:
// allsheets.splice(sheetExcludeIndex, sheetExclude.length); // In this script, this line is not used.

// Retrieve values from the target sheet.
var targetSheet = ss.getSheetByName(sheetExclude[0]);
var targetValues = targetSheet.getRange("B2:C" + targetSheet.getLastRow()).getValues();

// Retrieve values from all source sheets.
// Remove the duplication values between the target sheet and all source sheets.
var sourceValues = allsheets.reduce(function(obj, sheet) {
  var v = sheet.getRange(2, 9, sheet.getLastRow() - 1, 10).getValues().filter(function(r) {return r[0] && r[1]});
  if (v.length > 0) v.forEach(function(e) {if (!(e[0] in obj)) obj[e[0]] = e[1]});
  return obj;
}, {});
var dstValues = Object.keys(sourceValues).map(function(e) {return [e, sourceValues[e]]});

// Add the result values to the target sheet.
if (dstValues.length > 0) {
  var destination = SpreadsheetApp.openById(targetID).getSheetByName(sheetExclude[0]);
  destination.getRange(2, 2, destination.getLastRow(), 2).clearContent();
  destination.getRange(2, 2, dstValues.length, dstValues[0].length).setValues(dstValues);
}
  • The proposed 2 sample scripts can be used for your situation. So please select one of them.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

Google script to duplicate sheet with values and format only

How can I assign a Google Sheet script to only one sheet?

Google app script OnEdit to run only on one cell in one sheet

google apps script - batch setValues() on Sheet

Google Sheet Script Editor - setValues for array

Google Apps Script - setvalues not working on sheet

Google Sheet importxml - How to retrieve only the 5 first values?

How to duplicate google sheet as values and formatting only & rename it to a certain cell

How to check for duplicates and only append unique values in google-app-scripts?

How to avoid parsing of data with google app script range.setValues

how to reduce runtime of google app script that using setValues() and copyto() in for loop

Google App Script: Fetch all URLs from column A, and individually openByURL,getSheetByName, getRange, getValues, then setValues in master sheet

Google App script - setValues() doesn't work

How to automatically sorting continuously only if a certain value is set for a certain column in Google Apps Script/Google Sheet?

How to only move values rather than formulas in my Google Script

How to refer to other sheet in google app script?

How to make user input Google Sheet database only using by Web App Form and RESTRICT to input directly in Google Sheet?

How to assign Sheet with Sheet CodeName in Google Sheets App Script

onedit script in google sheet works for only one function

Google sheet script Check mark only the last matching row

Use script only on specific sheet not on all sheets in Google sheets

Google App Script Only Pull Rows With Data

How to create a random list with only unique values?

How to select only unique values in a form?

How to set unique values only for the child model?

How to keep only unique values in my array?

How to get only unique values in Mongoose?

Google Sheet App Script: Match two values from one sheet to another sheet and then set a value if they match

Return only unique values