Google Sheets Apps Script Copy Row of Data If date same as tab name - javascript

I found some code that almost does what i need and have tried playing around with it to get it to work, but no luck. I get an export with data with dates in the last column on every row.
I simply want to copy the last column rows of dates to the tabs with the same name.
function MoveDate_FourthDEC() {
var ss=SpreadsheetApp.getActive();
var sh1=ss.getSheetByName("Import");
var sh2=ss.getSheetByName("4/12/2020");
var rg1=sh1.getRange(2,1,sh1.getLastRow(),32);//starting at column2
var data=rg1.getValues();
for(var i=0;i<data.length;i++) {
// 13 = collected should be in this column which is column N
if(data[i][31]=="4/12/2020") {
sh2.appendRow(data[i]);
}}}

Explanation:
Your goal is to copy all the rows for which column AF matches the names of the sheets.
To begin with, you can use forEach() to iterate over every sheet. For each sheet, you want to check whether the sheet name matches a date in column AF. If it does, then you need to filter only the rows that contain this date in column AF and store them into an temporary array:
let temp_data = data.filter(r=>r[31]==sh.getName());
Then you can efficiently copy and paste all the relevant rows to the matching sheet:
sh.getRange(sh.getLastRow()+1,1,temp_data.length,temp_data[0].length).setValues(temp_data);
Side notes:
When dealing with date objects you need to consider the display values in the sheet. This is why I am using getDisplayValues instead of getValues.
Since data starts from the second row, you need to deduct one row from the last row with content, to get the correct range:
getRange(2,1,sh1.getLastRow()-1,32)
I am using includes to check if the sheet name matches the last column. In order to use includes you need to flatten the 2D array that is returned by the getDisplayValues function.
Solution:
function MoveDate_FourthDEC() {
const ss = SpreadsheetApp.getActive();
const sh1 = ss.getSheetByName("Import");
const shs = ss.getSheets();
const dts = sh1.getRange('AF2:AF'+sh1.getLastRow()).getDisplayValues().flat();
const data=sh1.getRange(2,1,sh1.getLastRow()-1,32).getDisplayValues();
shs.forEach(sh=>{
if (dts.includes(sh.getName())){
let temp_data = data.filter(r=>r[31]==sh.getName());
sh.getRange(sh.getLastRow()+1,1,temp_data.length,temp_data[0].length).setValues(temp_data);
}});
}

Related

How Do You Generate List On "Sheet A" from Data on "Sheet B" in Google Sheets Using a Script

I have a list of roughly 3,000 First Names, Last Names, and other items on a sheet in Google Sheets. The name of that sheet is "Database." (link below).
I want to create a script that takes 100 random entries from each column in "Database" and populates cells on another sheet called, "Results."
So, basically, Col 1 on "Results" would take 100 random results from Col 1 in "Database." Col 2 in "Results" would take 100 random results from Col 2 in "Database." So on and so forth. Ideally, this can be regenerated by assigning a script to a button on the sheet as opposed to using a formula that will create new results every time an action is performed.
Ultimately, I'll end up having about 10 columns or so, but I'm using test data for now just to get the structure built. Here's a link to the test document I'm using...
https://docs.google.com/spreadsheets/d/1qOgZxLtl8ruQHUDMkIjCNdXV3Jy5eOv0dC5DkLEpB8w/edit?usp=sharing
Thanks so much for the help!
You can try this:
Pre-requisite:
LodashGS Library should be added in your project
//Load LodashGS:
var _ = LodashGS.load();
function myFunction() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var resultSheet = ss.getSheetByName("Results");
var dBSheet = ss.getSheetByName("Database");
//Loop all columns in Database Sheet
for (var col = 1; col <= dBSheet.getLastColumn() ; col++){
//Generate an array of unique numbers from 2 to the last row number of the Database Sheet
const uniqRandomNumbers = _.sampleSize(_.range(2,dBSheet.getLastRow() + 1), 100);
Logger.log(uniqRandomNumbers);
var rowValues = [];
//Get the cell value based on the uniqRandomNumbers as row index, create a 2-d array of row values
uniqRandomNumbers.forEach(row=>{rowValues.push([dBSheet.getRange(row,col).getValue()]);});
//Write the row values into the Results Sheet with 100 row entries
resultSheet.getRange(2,col,100).setValues(rowValues);
Logger.log(rowValues);
}
}
What it does?
(This is done for each column)
Generate an array of unique numbers from the range provided in _.range(). We will use this unique array numbers as row indexes.
Get the cell value based on the unique array numbers generated in Step1, and create a 2-d array of row values.
Write the 2-d array of row values into the Results Sheet using .setValues()
Sample Output:
Additional References:
Creating array of length n with random numbers in JavaScript

Filter function will not delete my empty rows - Google App Script

I want to import rows from one google sheet to the other, however source sheet imports a number of empty rows. Now I use a filter function to get rid of these rows but they will not disappear, can anyone tell me why?
var a = SpreadsheetApp.openByUrl("url").getSheetByName("Admin Use Only").getRange(4,1,6,21).getValues();
var b = SpreadsheetApp.getActive().getSheetByName('Credit_Detail');
b.getRange(b.getLastRow() +1, 1, a.length,21).setValues(a);
//filter function below:
var otarget=b.getRange(2,1,b.getLastRow()-1, 26).getValues();
var data=otarget.filter(function(r){
return !r.every(function(cell){
return cell === "";});
});
Logger.log(data);
b.getRange("A2:Z").clearContent();
b.getRange(3,1,data.length,data[0].length).setValues(data);
here's how I would do it. First, create an variable to store the array of the source. then run a for loop scanning the first column for empties. something like: for (var i = 0, i < data.length; i++) { if (data[i][0] != '') { XXXX } }
XXXX means that you can either put a code to create a new set of array which can be passed to the target sheet at once or use append row to transfer non blank rows to the target sheet one by one.
Note: Creating a new array to store non-empty rows would speedup the execution time if you are dealing with large data, thousands of rows.

Selecting a range from within a named range google sheets script

Is there any way to select a range specified from within another named range?
For example if I have a named range say "firstRange" and I want to get just the 2nd column from within that range to copy to another named range.
I can do this by copying cells individually with a for loop but it takes a long time.
Unfortunately
getRangeByName("firstRange").getRange(1,1,2) is not valid as getRange is not a method of getRangeByName
Thanks
How about this method? I think that there are several answers for your situation. So please think of this as one of them. The flow is as follows.
Flow:
Range of values you want is retrieved from the source named-range by offset().
When getLastRow() is used to the named range, the returned value is the last row of the named range.
Retrieve the destination named-range.
Copy the retrieved source range to the destination range.
Sample script:
In this sample script, the 2nd column of named range of firstRange is copied to the named range of secondRange.
var ss = SpreadsheetApp.getActiveSpreadsheet();
// Retrieve source range.
var sourceRange = ss.getRangeByName("firstRange");
var src = sourceRange.offset(0, 1, sourceRange.getLastRow(), 1);
// Retrieve destination range.
var destinationRange = ss.getRangeByName("secondRange");
// Copy from source range to destination range.
src.copyTo(destinationRange);
For example, if you want to copy the retrieved source range to 2nd column of the destination range, please modify var destinationRange = ss.getRangeByName("secondRange") as follows.
var destinationRange = ss.getRangeByName("secondRange").offset(0, 1, 1, 1);
References:
getLastRow()
offset()
copyTo()
If this was not what you want, I'm sorry.
You can get the named range and then get the values which returns a multi-dimensional array. Then you can parse the values that you are looking for out of that. For example
var parsed = SpreadsheetApp.getActiveSpreadsheet()
.getRangeByName('namedRange')
.getValues()
.map(function(row) {
return [row[1]];
});
This gets all the values from your named range and then maps over them and grabs the values from the second column (the 1 index in this example)
I hope that helps.

How to rename Google spreadsheets (files) and populate their contents with values from a sheet

Desired to have the following Google Spreadsheet function, which (1) renames a spreadsheet (target file) and (2) populates one of its sheets based on the values contained in another spreadsheet (source file), loop through from the second row onwards until all spreadsheets listed have been renamed and populated.
All the values required for renaming the target files are in cell range D2:D.
All the values required for populating the target files are in cell range A2:D
All the IDs of the target files are in cell range G2:G.
There are no blank rows between and including the second row and the last data-containing row, and all rows with data in this range are to be used. Each of the columns (A, B, C, D, G) has the same number of data-containing rows.
The value of the number of rows which contain entries to be used is in cell range E1, if that's of any use (not used in this function).
function rnmCpyRngTo() {
//rename target spreadsheet and populate range
//in target sheet from values in source spreadsheet
//get source sheet in source spreadsheet
var ssss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("CopyToWrdLists");
//get source cell range containing value of name to be given to target spreadsheet
var scrvn = ssss.getRange("D2").getValue();
//get source cell range containing values to copy to target sheet cell range
var scrvr = ssss.getRange("A2:D2").getValues();
//get source cell range containing values of target spreadsheet ID
var scrvid = ssss.getRange("G2").getValue();
//get target spreadsheet ID
var tssid = DriveApp.getFileById(scrvid);
//get target sheet
var tss = SpreadsheetApp.openById(scrvid).getSheetByName("Wordlist");
//rename target spreadsheet
tssid.setName(scrvn);
//copy values to target sheet cell range
tss.getRange(1, 1, scrvr.length, scrvr[0].length).setValues(scrvr);
}
Question 15616530 seemed close to the desired outcome but was unable to modify it to suit. Help would be much appreciated.
Added:
//get source cell range containing values of target spreadsheet ID
var scrvid = ssss.getRange("G2").getValues();
Source sheet has been shared here so that anyone with link can edit.
Assuming your signed into Google, this folder has been shared.
The folder "Target_Spreadsheet" should have nothing in it.
Run script "Create wordlists - TOMS" from user menus "Wordlists" to create the documents, and
Run function "Rename and populate - TOMS" from the user menus to rename and populate the first listed file only.
Repeat as necessary. That's what I'm up to.
Thanks.
This should do the trick, just put your code in a for loop:
function rnmCpyRngTo() {
//rename target spreadsheet and populate range
//in target sheet from values in source spreadsheet
//get source sheet in source spreadsheet
var ssss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("CopyToWrdLists");
//get source cell range containing value of name to be given to target spreadsheet
var data = ssss.getDataRange().getValues() // All the data in sheet, since there not empty rows.
Logger.log(data)
var dataLength = data[0][4] // Get number of rows from cell E1, can use data.length instead
for (var i = 1; i <= dataLength ; i++){ // If you rather use data.length change the condition to i < data.length
var scrvn = data[i][3] // Get Rename value
var scrvr = []
scrvr[0] = data[i].slice(0, 4) // Get Copy Values
var scrvid = data[i][6] // Get of SpdSheet
var tss = SpreadsheetApp.openById(scrvid) // Get Spreadsheet
tss.rename(scrvn) // Rename Spreadsheet
Logger.log(scrvr)
tss.getSheetByName("Wordlist").getRange(1, 1, scrvr.length,scrvr[0].length).setValues(scrvr) // Set Copy Values to the sheet
}
}
Hope it helps!
just use
newSheet.updateProperties({title: "new title"})
for example

Data Scraping With ImportHTML in Apps Script & Google Sheets

Goal: I am trying to pull data from a website and use it to create a big table. I can tell that I'm very close to getting this to work, but I've reached a roadblock.
Background:
I have a google sheet with three pages. (1) Titled "tickers" is a list of every ticker in the S&P 500, in rows A1-A500. (2) Titled actionField is just a blank page used during the script. (3) Titled resultField will hold the results. The website I am pulling from is (http://www.reuters.com/finance/stocks/companyOfficers?symbol=V) Though, I want the script to work (with minor modification) for any data accessible through importHtml.
Script:
The script I currently have is as follows:
function populateData() {
var googleSheet = SpreadsheetApp.getActive();
// Reading Section
var sheet = googleSheet.getSheetByName('tickers');
var tickerArray = sheet.getDataRange().getValues();
var arrayLength = tickerArray.length;
var blankSyntaxA = 'ImportHtml("http://www.reuters.com/finance/stocks/companyOfficers?symbol=';
var blankSyntaxB = '", "table", 1)';
// Writing Section
for (var i = 0; i < arrayLength; i++)
{
var sheet = googleSheet.getSheetByName('actionField');
var liveSyntax = blankSyntaxA+tickerArray[i][0]+blankSyntaxB;
sheet.getRange('A1').setFormula(liveSyntax);
Utilities.sleep(5000);
var importedData = sheet.getDataRange().getValues();
var sheet = googleSheet.getSheetByName('resultField');
sheet.appendRow(importedData)
}
}
This successfully grabs the ticker from the tickers page. Calls importHtml. Copies the data. And appends SOMETHING to the right page. It loops through and does this for each item in the ticker list.
However, the data being appended is as follows:
[Ljava.lang.Object;#42782e7c
[Ljava.lang.Object;#2de9f184
[Ljava.lang.Object;#4b86a4d0
That displays across many columns, for as many rows as there are iterations in the loop.
How do I successfully append the data?
(And any advice on improving this script?)
The appendRow method is not suitable here. As it only appends one row, its argument is expected to be a 1D array of values.
What you get from getValues is normally a 2D array of values, like [[a,b], [c,d]]. Even if it's just one row, getValues will return [[a,b]]. The only exception is a single-cell range, for which you get just the value in that cell. It's never a 1D array.
If just one row is needed, use, e.g., appendRow(importedData[0]).
Otherwise, insert the required number of rows and assign the 2D array of values to them.
var sheet = googleSheet.getSheetByName('resultField');
var lastRow = sheet.getLastRow();
sheet.insertRowsAfter(lastRow, importedData.length);
sheet.getRange(lastRow + 1, 1, importedData.length, importedData[0].length)
.setValues(importedData);

Categories