Combine multy arrays side by side google script - arrays

I have this code on Google script for get arrays from Sheet1 by criteria in Sheet2 at Sheet3. But now arrays placed only one under the other. What I need is place every new array from 'v' in next 5 columns like in example on my spreadsheet.
Secondly - before this, I used filter with search formula, that allow me use wildcards like * or ?. How I can use wildcards or regexp in my new function?
I would be grateful for any help.
function getval(){
var ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet1");
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet2");
var sspodbor = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet3");
var range = ss.getRange("A2:A29");
var values = range.getValues();
var rangez = sheet.getRange("A1:A14");
var valuesz = rangez.getValues();
var z = []
for (var x = 0; x<valuesz.length; x++){
z.push(valuesz[x])
}
var v = [];
for (var q = 0; q < valuesz.length; q++){
for (var s = 0; s < values.length; s++){
if(values[s][5] == z[q]){
v.push([values[s][0],values[s][1],values[s][2],values[s][3],values[s][4]]);
}
//I am guessing that here must be a separating function
}
}
var range = sspodbor.getRange(4, 1, v.length,v[0].length);
range.setValues(v);
}
My spreadsheet: https://docs.google.com/spreadsheets/d/1o7ErbeFHA7yyxMC0HMn3Uj5ZBRcy2uAwa1UpolVpBFI/edit?usp=sharing

Spreading the Groups out Horizontally
It's not the prettiest solution you'll ever see and hopefully others will look it over and make improvements but here it is.
function getval()
{
var Sheet1 = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet1");
var Sheet2 = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet2");
var output = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("output");
var knew = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('knew');
var knewrange = knew.getRange(1,1,10,100);
var pipe = '';
var range1 = Sheet1.getRange("A2:F29");
var values1 = range1.getValues();
var range2 = Sheet2.getRange("A1:A14");
var values2 = range2.getValues();
var z = [];
for (var x = 0; x<values2.length; x++)
{
z.push(values2[x])
}
var v = [];
for (var q = 0; q < values2.length; q++)
{
for (var s = 0; s < values1.length; s++)
{
if(values1[s][5] == z[q])
{
v.push([values1[s][0],values1[s][1],values1[s][2],values1[s][3],values1[s][4],q]);
}
}
}
var vlength=v.length;
var range3 = output.getRange(1, 1, v.length,6);
range3.setValues(v);
var w = [];
var voff = 0;
var hoff = 0;
for(var m=0;m<10;m++)
{
w[m]=[];
for(var n=0;n<100;n++)
{
w[m][n]='' ;
}
}
var color = ['yellow','orange'];
for(var i=0;i<v.length;i++)
{
for(var j=0;j<5;j++)
{
if(i-voff==0){knew.getRange((i-voff + 1),(j + hoff + 1),4,5).setBackground(color[v[i][5] % 2])};
if((i-voff)==0 || v[i][5] == v[i-1][5])
{
w[i - voff][j + hoff]=v[i][j];
}
else
{
voff = i;
hoff += 5;
w[i - voff][j + hoff]=v[i][j];
}
}
}
knewrange.setValues(w);
}
I copied the data from your spreadsheet and the the original getval function. I ended up changing some of the names so I could figure out where to find the data easier. It was a difficult problem for me and one that i enjoyed.
Thanks

Related

Why array comparison isn't working? (GAS)

The code below used to work. Now, when comparing two arrays, even though there is a difference, as highlighted below, the code says that there is a duplicate.
I've tried it using .join() as well, but I keep getting the same result.
Script:
function SaveEditedEntry() {
const lock = LockService.getScriptLock();
lock.tryLock(3000);
if (lock.hasLock()) {
var sourceSheet = 'Entries';
var destinationSheet = 'Database';
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName(sourceSheet);
var LastRowSource = sheet.getLastRow();
//var LastColumnSource = sheet.getLastColumn();
var entryValues = sheet.getRange(7, 1, LastRowSource, 16).getValues();
var dbSheet = ss.getSheetByName(destinationSheet);
var entryDataPushed = [];
var dbData = dbSheet.getRange(2, 1, dbSheet.getLastRow(), 16).getValues();
var dbDataPushed = [];
//var dbDataPushed = new Array();
var company = sheet.getRange("B3").getValue();
var period = sheet.getRange("B4").getValue();
var entryID = sheet.getRange("J5").getValue();
var timeStamp = new Date();
var user = Session.getActiveUser().getEmail();
if (company == '') {
Browser.msgBox('Make sure that you have chosen a valid company.');
return;
}
if (period == '') {
Browser.msgBox('Please, make sure that you have chosen a valid period.');
return;
}
var emptyRow = 0;
for (var i = 0; i < entryValues.length; i++) {
if (entryValues[i][0] != '') {
emptyRow = i + 1;
}
if (emptyRow < 1) {
Browser.msgBox('Please, make sure that you have entered a transaction.');
return;
}
if (entryValues[i][0] != '') {
entryDataPushed.push(entryValues[i]);
}
}
for (var n = 0; n < dbData.length; n++) {
if (dbData[n][1] != '' && dbData[n][0] == company && dbData[n][14] == period) {
dbDataPushed.push(dbData[n]);
}
}
var duplicate = false;
loop1:
for (var x = 0; x < entryValues.length; x++) {
loop2:
for (var j = 0; j < dbDataPushed.length; j++) {
if (JSON.stringify(entryValues[x]) == JSON.stringify(dbDataPushed[j])) {
duplicate = true;
break loop1;
}
}
}
Logger.log("EntryDataPushed: " + entryDataPushed);
Logger.log("dbDataPushed: " + dbDataPushed);
if (duplicate == true) {
Browser.msgBox('No change has been made.');
return;
This is the logs print:
Could anyone point me to the right direction on getting this solved?
Thank you!
Antonio
You were comparing entryValues vs dbDataPushed but is logging entryDataPushed and dbDataPushed. Is this expected?
Anyways, since you are logging the variables, I assume the variables logged are the ones you need to compare.
Convert them into JSON string by wrapping the variables with JSON.stringify(). I use this all the time when I encounter an issue similar to yours right now.
var duplicate = false;
if (JSON.stringify(entryDataPushed) == JSON.stringify(dbDataPushed)) {
duplicate = true;
}
Output:
See resource below for other ways to properly compare arrays if the above code doesn't work.
Resources:
JSON.stringify()
StackOverflow Reference

Script not running thru all iterations, and getting stuck in a loop

I have a script that is working. It is to loop thru a number of different spreadsheets, and make the same edits in each. The edits are: Adding 2 formulas, conditional formatting a cell, and removing protection from 6 sheets. But there seems to be an issue with the first 'FOR' loop. It is only doing 2 iterations, then keeps running. I have had to force stop each of my attempts after several minutes. I am fairly new, so I think the issue may be with my syntax and brackets {}.
var sheetIds = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Blueprints"); //Change as needed -DONE
var values = sheetIds.getRange('j19:j96').getValues(); //Change to proper range -DONE j3:j96
var idList = values.map(function (row) {
return row[0];
}).filter(function (id) {
return id;
});
for (var i = 0; i < idList.length; i++) {
// var form1 = "Roster!A1"
// var form2 = "KPI!A1"
var s = SpreadsheetApp.openById(idList[i]);
var ss = s.getSheetByName('Blueprint');
var roster = ss.getRange('e3');
var kpi = ss.getRange('f3');
var form1 = "Roster!A1"
var form2 = "KPI!A1"
roster.setFormula(form1)
kpi.setFormula(form2)
//var range = ss.getRange('t1')
var rule = SpreadsheetApp.newConditionalFormatRule()
.whenTextContains('Advocates')
.setFontColor('#c9daf8')
.setRanges([roster])
.build();
var rules = ss.getConditionalFormatRules();
rules.push(rule);
ss.setConditionalFormatRules(rules);
//var s = SpreadsheetApp.getActiveSpreadsheet();
var store = s.getSheetByName('Store');
var prot = store.getProtections(SpreadsheetApp.ProtectionType.SHEET)
for (var i = 0; i < prot.length; i++) {
var protection = prot[i];
if (protection.canEdit()) {
protection.remove();
}
}
var adv1 = s.getSheetByName('Advocate1');
var prot1 = adv1.getProtections(SpreadsheetApp.ProtectionType.SHEET)
for (var i = 0; i < prot1.length; i++) {
var protection1 = prot1[i];
if (protection1.canEdit()) {
protection1.remove();
}
}
var adv2 = s.getSheetByName('Advocate2');
var prot2 = adv2.getProtections(SpreadsheetApp.ProtectionType.SHEET)
for (var i = 0; i < prot2.length; i++) {
var protection2 = prot2[i];
if (protection2.canEdit()) {
protection2.remove();
}
}
var adv3 = s.getSheetByName('Advocate3');
var prot3 = adv3.getProtections(SpreadsheetApp.ProtectionType.SHEET)
for (var i = 0; i < prot3.length; i++) {
var protection3 = prot3[i];
if (protection3.canEdit()) {
protection3.remove();
}
}
var adv4 = s.getSheetByName('Advocate4');
var prot4 = adv4.getProtections(SpreadsheetApp.ProtectionType.SHEET)
for (var i = 0; i < prot4.length; i++) {
var protection4 = prot4[i];
if (protection4.canEdit()) {
protection4.remove();
}
}
var adv5 = s.getSheetByName('Advocate5');
var prot5 = adv5.getProtections(SpreadsheetApp.ProtectionType.SHEET)
for (var i = 0; i < prot5.length; i++) {
var protection5 = prot5[i];
if (protection5.canEdit()) {
protection5.remove();
}
}
}
}
It would be a massive time saver if I could figure this out!!!
Try this:
I just replaced all of the inner loop indices with j
function myFunction() {
var sheetIds=SpreadsheetApp.getActive.getSheetByName("Blueprints");
var values=sheetIds.getRange('j19:j96').getValues();
var idList=values.map(function (row) {return row[0];}).filter(function (id) {return id;});
for (var i=0;i<idList.length;i++) {
var s=SpreadsheetApp.openById(idList[i]);
var ss=s.getSheetByName('Blueprint');
var roster=ss.getRange('e3');
var kpi=ss.getRange('f3');
var form1="Roster!A1";
var form2="KPI!A1";
roster.setFormula(form1);
kpi.setFormula(form2);
var rule=SpreadsheetApp.newConditionalFormatRule().whenTextContains('Advocates').setFontColor('#c9daf8').setRanges([roster]).build();
var rules=ss.getConditionalFormatRules();
rules.push(rule);
ss.setConditionalFormatRules(rules);
var store=s.getSheetByName('Store');
var prot=store.getProtections(SpreadsheetApp.ProtectionType.SHEET)
for(var j=0;j<prot.length; j++) {
var protection=prot[j];
if (protection.canEdit()) {
protection.remove();
}
}
var adv1=s.getSheetByName('Advocate1');
var prot1=adv1.getProtections(SpreadsheetApp.ProtectionType.SHEET)
for (var j=0; j < prot1.length; j++) {
var protection1=prot1[j];
if (protection1.canEdit()) {
protection1.remove();
}
}
var adv2=s.getSheetByName('Advocate2');
var prot2=adv2.getProtections(SpreadsheetApp.ProtectionType.SHEET)
for (var j=0; j < prot2.length; j++) {
var protection2=prot2[j];
if (protection2.canEdit()) {
protection2.remove();
}
}
var adv3=s.getSheetByName('Advocate3');
var prot3=adv3.getProtections(SpreadsheetApp.ProtectionType.SHEET)
for (var j=0; j < prot3.length; j++) {
var protection3=prot3[j];
if (protection3.canEdit()) {
protection3.remove();
}
}
var adv4=s.getSheetByName('Advocate4');
var prot4=adv4.getProtections(SpreadsheetApp.ProtectionType.SHEET)
for (var j=0; j < prot4.length; j++) {
var protection4=prot4[j];
if (protection4.canEdit()) {
protection4.remove();
}
}
var adv5=s.getSheetByName('Advocate5');
var prot5=adv5.getProtections(SpreadsheetApp.ProtectionType.SHEET)
for (var j=0; j < prot5.length; j++) {
var protection5=prot5[j];
if (protection5.canEdit()) {
protection5.remove();
}
}
}
}

Re-set checkboxes to true (dealing with blanks)- Google Apps Script

I found the snippet below here: Re-set checkboxes to false - Google Apps Script
I'm interested in editing this to set false checkboxes to true, specifically adding to it to skip blank cells. Can't find anything helpful on skipping blanks.
function resetCheckBoxesAllSheets() {
var ss = SpreadsheetApp.getActive();
var allsheets = ss.getSheets();
for (var s in allsheets){
var sheet=allsheets[s]
var dataRange = sheet.getRange('A4:Z100');
var values = dataRange.getValues();
for (var i = 0; i < values.length; i++) {
for (var j = 0; j < values[i].length; j++) {
if (values[i][j] == true) {
values[i][j] = false;
}
}
}
dataRange.setValues(values);
}
}
If you wish to flip flop the values of a set of checkboxes this will do it for a given column active range:
Note: capitalization counts and yes those are strings. If you have any doubts about it then use your script editor's debugger to see what is in your checkboxes. That's how I figured it out when I started playing with them.
function resetCheckBoxesAllSheets() {
var ss = SpreadsheetApp.getActive();
var sheet=ss.getActiveSheet()
var dataRange = sheet.getActiveRange();
var values = dataRange.getValues();
for (var i=0;i<values.length;i++) {
values[i][0]=values[i][0]?"FALSE":"TRUE";
}
dataRange.setValues(values);
}
So in your particular case, assuming everything else in your function works then try this:
function resetCheckBoxesAllSheets() {
var ss = SpreadsheetApp.getActive();
var allsheets = ss.getSheets();
for (var s in allsheets){
var sheet=allsheets[s]
var dataRange = sheet.getRange('A4:Z100');
var values = dataRange.getValues();
for (var i = 0; i < values.length; i++) {
for (var j = 0; j < values[i].length; j++) {
if (values[i][j]) {
values[i][j] = "FALSE";
}
}
}
dataRange.setValues(values);
}
}

Angular js $http.put call with multiple ID's(urls) with more than one id is not working

I have an api 'rest/latest/testruns/16543558' the id is test run ids. I want to update a call with different ids in one shot . I have tried with $promise.all(). Its working fine if I give an individual ID but if I give more than one id its giving error
With single ID Working FINE :
var ids = ['16611544']; //'16611345','16611347'
$scope.updateTestRun = function(data) {
data.showedit = true;
$scope.label = 'Save';
var updateform = {};
var updateArr = [];
for (var i = 0; i < data.length; i++) {
var testrunid = data[i].data.data.id;
var updatedata = data[i].data.data.fields;
updateform['fields'] = data[i].data.data.fields;
updateform.fields['duration'] = 1000;
delete updateform.fields['executionDate'];
for (var j = 0; j < data[i].data.data.fields.testRunSteps.length; j++) {
data[i].data.data.fields.testRunSteps[j].status = data[i].data.data.fields.testRunStatus;
}
updateArr.push($http.put("rest/latest/testruns/" + testrunid, updateform))
j = 0;
$scope.loader = true;
}
}
u can use $q.all to send multiple request on one shot
var fullArray = [];
for (var i = 0; i < data.length; i++) {
var testrunid = data[i].data.data.id;
var updatedata = data[i].data.data.fields;
updateform['fields'] = data[i].data.data.fields;
updateform.fields['duration'] = 1000;
delete updateform.fields['executionDate'];
for (var j = 0; j < data[i].data.data.fields.testRunSteps.length; j++) {
data[i].data.data.fields.testRunSteps[j].status = data[i].data.data.fields.testRunStatus;
}
j = 0;
$scope.loader = true;
// push all request to array
fullArray.push($http.put("rest/latest/testruns/" + testrunid, updateform))
}
$q.all(fullArray).then(function(values) {
//resoponse
});

[AS3]Randomly do something without repeat

I've 3 movieclip on stage which is mc1,mc2,mc3
at first they are alpha=0
What I want is when i click on revealBtn, 1 of them will show up as alpha=1.
But with my code below, sometimes I need to click about 5 times or more only can make all those mc show up.
Is there any solution for what I wanted? I've try splice but it's still not working well.
var mcArray:Array = [mc1,mc2,mc3];
for (var j:int = 0; j < mcArray.length; j++)
{
mcArray[j].alpha = 0;
}
revealBtn.buttonMode = true;
revealBtn.useHandCursor = false;
revealBtn.addEventListener(MouseEvent.CLICK, revealClick);
function revealClick(event:MouseEvent):void
{
var i:Number = Math.floor(Math.random() * mcArray.length);
var movieClipToEdit:MovieClip = mcArray[i] as MovieClip;
movieClipToEdit.alpha = 1;
}
Here's one of the many possible solutions. It destroys the initial array though. If you don't want to change the initial array, the rest depends on what you actually want to achieve.
var invisibleList:Array = [mc1,mc2,mc3];
for (var j:int = 0; j < invisibleList.length; j++)
{
invisibleList[j].alpha = 0;
}
revealBtn.buttonMode = true;
revealBtn.useHandCursor = false;
revealBtn.addEventListener(MouseEvent.CLICK, revealClick);
function revealClick(event:MouseEvent):void
{
if (invisibleList.length == 0) {
return;
}
var i:Number = Math.floor(Math.random() * invisibleList.length);
var movieClipToEdit:MovieClip = invisibleList[i] as MovieClip;
invisibleList.splice(i, 1);
movieClipToEdit.alpha = 1;
}
Make a second array to use as your selection source. Every time you pick an item, Splice it from the second array. Also, since all your items are MovieClips you should use a Vector instead.
var mcVector:Vector.<MovieClip> = [mc1,mc2,mc3];
var vector2:Vector.<MovieClip> = mcVector.Slice(0); // This just copies the Vector
for (var j:int = 0; j < mcVector.length; j++)
{
mcVector[j].alpha = 0;
}
revealBtn.buttonMode = true;
revealBtn.useHandCursor = false;
revealBtn.addEventListener(MouseEvent.CLICK, revealClick);
function revealClick(event:MouseEvent):void
{
var i:Number = Math.floor(Math.random() * mcVector.length);
// Retrieves and deletes the item in one step:
var movieClipToEdit:MovieClip = vector2.Splice(i, 1);
movieClipToEdit.alpha = 1;
}

Resources