BlueIris
BlueIris

Reputation: 149

Google Apps Script - Conditionally retrieve data from other Google Sheet to Overview sheet

To explain the larger context: there are several forms which generate different sheets. I'm looking for a way to conditionally copy some of the responses sheet to a seperate "Overview" document. Code-wise, I had some ideas for the Overview document, but stranded near the start.

My method was going to be to build functions for all the information I want to retrieve, such as date of birth (example in code block below), date of submission and phone number, when I click on a button. The information may only be copied if the first and surname match the ones in the Overview. The order of the sheets in different docs are not the same and the column length is continually in flux. Furthermore, the amount of rows in the Overview doc is different than the form submission sheets.

In other words: if Anne Annenson would be the twenty-first respondent to a form, I want that information in the overview sheet where they are the first person.

function getDobs() {
    var targetSpreadsheet = SpreadsheetApp.getActive();
    var targetSheet = targetSpreadsheet.getSheetByName("Overview");
    var targetFirstNameCheck = targetSpreadsheet.getRange("A4:A");
    var targetSurnameCheck = targetSpreadsheet.getRange("B4:B"); 
    var sourceSpreadsheetDob = SpreadsheetApp.openById("..."); 
    var sourceDob = sourceSpreadsheetDob.getSheetByName("Form responses 1"); 
    var sourceFirstNameCheckDob = sourceSheetDob.getRange("C2:C"); 
    var sourceSurnameCheckDob = sourceSheetDob.getRange("D2:D"); 
    var sourceRangeDob = sourceSheetDobConsent.getRange("E2:E");

if (sourceFirstNameCheckDob==targetFirstNameCheck && sourceSurnameCheckDob==targetSurnameCheck){ //then I want to copy the data 
    var sourceData = sourceRangePronouns.getValues(); 
    var targetRangeDob = targetSheet.getRange("C4:C");  
 } 
    else (//I want it to leave the cells alone, so any text or formatting that might have been put in manually is still there.){ 
}
}

I would like for the responses to remain in the form response sheets as well.

Any thoughts?

Upvotes: 1

Views: 536

Answers (1)

NightEye
NightEye

Reputation: 11184

Cooper already explained all the things you need in the comments. And below is what your code would look like following Cooper's comments.

Code

function getDobs() {
  var targetSpreadsheet = SpreadsheetApp.getActive();
  var targetSheet = targetSpreadsheet.getSheetByName("Overview");
  var targetLastRow = targetSheet.getLastRow();
  // range equivalent to A4:B
  var targetNamesCheck = targetSheet.getRange(4, 1, targetLastRow - 3, 2).getValues();

  // tested in same spreadsheet, change "targetSpreadsheet" to openById on your actual script
  var sourceSpreadsheetDob = targetSpreadsheet; 
  var sourceDob = sourceSpreadsheetDob.getSheetByName("Form responses 1");
  var sourceLastRow = sourceDob.getLastRow();
  // range equivalent to C2:D
  var sourceNamesCheckDob = sourceDob.getRange(2, 3, sourceLastRow - 1, 2).getValues();
  // range for data to be copied (E2:G in my sample data)
  var sourceRangeDob = sourceDob.getRange(2, 5, sourceLastRow - 1, 3).getValues();

  var output = [];
  targetNamesCheck.forEach(function (targetNames) {
    // search sourceNamesCheckDob for targetNames 
    var index = searchForArray(sourceNamesCheckDob, targetNames);
    // if targetNames is in sourceNamesCheckDob, save the data on that row for later
    if (index > -1)
      output.push(sourceRangeDob[index]);
    // append blank cells if data is not found
    else
      output.push(new Array(sourceRangeDob[0].length)); 
  });
  // if there were names that were found, write the data beside the targetNames
  if (output.length > 0) {
    targetSheet.getRange(4, 3, output.length, output[0].length).setValues(output);
  }
}

// function to search the array for the object
function searchForArray(haystack, needle) {
  var i, j, current;
  for(i = 0; i < haystack.length; ++i) {
    if(needle.length === haystack[i].length) {
      current = haystack[i];
      for(j = 0; j < needle.length && needle[j] === current[j]; ++j);
      if(j === needle.length)
        return i;
    }
  }
  return -1;
}

Overview:

overview

Form responses 1:

form data

Overview after running getDobs:

output

EDIT:

Since there are no methods that includes the apostrophe when the cell value is being fetched, easiest way is to have the sheets identify the phone number as text so it won't remove the 0 in the beginning. I've thought of 3 ways to have the 0 included in the output:

  • Add the apostrophe manually on the specific output column via script
  • Add dashes on the number so it is treated as text (09395398314 -> 093-9539-8314) (just an example, not sure if that is the right format)
  • Format the output column into number -> plain text instead of number -> automatic

I prefer formatting the output column as that will be the fastest and easiest thing to do.

Format:

format

Output:

Output

Note:

  • This function will fill up rows where names in Overview are present in Form responses 1.

References:

Upvotes: 0

Related Questions