so... i got a problem on comparing different tables contents.
I basically need to clear the content where the cells data is the same, but the tables are unordered, and when i run my code, only the first line is cleared.
So i modified from this (Because it was clearing only the first line of the table):
function clearSourceValues(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sourceTable = ss.getSheetByName("Encaminhamento");
var targetTable = ss.getSheetByName("testeBD");
var rowCount = targetTable.getLastRow() + 1;
var sourceValues = sourceTable.getRange(2, 8, rowCount, 1).getValues();
var targetValues = targetTable.getRange(2, 3, rowCount, 1).getValues();
for (var i = 0; i < targetValues.length; i++){ // Modified
var clearRange = targetTable.getRange(i + 2, 2, 1, 8); // Modified
if (targetValues[i][0] == sourceValues[i][0]){
clearRange.clear();
};
};;
};
To this:
for (var i = 0; i < targetValues.length; i++){
var clearRange = targetTable.getRange(i + 2, 2, 1, 8);
for (var j = 0; j < sourceValues.length; j++){
if (targetValues[i][0] == sourceValues[j][0]){
clearRange.clear();
};
};
};
But now when i run it, every cells are cleared.
Clearing Source and Destination Ranges on a match in columns 3 of source and 8 of destination
function clearSourceandDestinationValues(){
var ss=SpreadsheetApp.getActive();
var ssh=ss.getSheetByName("Encaminhamento");
var tsh=ss.getSheetByName("testeBD");
var srg=ssh.getRange(2,8,ssh.getLastRow()-1,1);
var trg=tsh.getRange(2,3,tsh.getLastRow()-1,1);
var svA=srg.getValues();
var sA=svA.map(function(r){return r[0]});//flatten
var tvA=trg.getValues();
var tA=tvA.map(function(r){return r[0]});//flatten
svA.forEach(function(r,i){if(tA.indexOf(r[0])!=-1) {ssh.getRange(i+2,1,1,ssh.getLastColumn()).clear();}});//clears source range
tvA.forEach(function(r,i){if(sA.indexOf(r[0])!=-1) {tsh.getRange(i+2,1,1,tsh.getLastColumn()).clear();}});//clears destination range
}
map function is good to use
function clearSourceValues() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sourceTable = ss.getSheetByName("Encaminhamento");
var targetTable = ss.getSheetByName("testeBD");
var sourceValues = sourceTable.getRange(2, 8, (targetTable + 1), 1).getValues();
var targetValues = targetTable.getRange(2, 3, (targetTable + 1), 1).getValues();
var mapSourceTable = sourceValues.map(function(r) {
return r[5]
}) //this return you the whole data in the column "f"
var mapTargetTable = targetValues.map(function(r) {
retunrn r[0]
}); //this return you the whole data in the column "a"
for (var i = 1; /*remove the header*/ i < mapSourceTable.length; i++) {
var eltToCompare = mapSourceTable[i];
mapSourceTable.forEach(function(elt, index) {
//remove the header
if (index > 0) {
if (eltToCompare == elt) {
targetTable.deleteRow(index + 2);
}
}
});
}
Related
The goal is to get each sheet name and check if it's not in the array. If not, then certain ranges are copied into a "database" sheet and then compare the next sheet and so on.
The problem is that itis comparing, it is giving me -1 as the result and it is executing the tasks, when it shouldn't be and I can't see where the flaw is.
Here's the code:
function concatenarResumos() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var databaseSheet = ss.getSheetByName("Database");
var processedSheetsRng = ss.getSheetByName("Suporte").getRange("F6:F").getValues().flat();
var shts = ss.getSheets();
for (var j = 0; j < shts.length; j++) {
for (var n = 0; n < processedSheetsRng.length; n++) {
if (processedSheetsRng[n].indexOf(shts[j].getSheetName() === -1)) {
shts[j].activate;
var sheetName = shts[j].getSheetName();
Logger.log("Sheet Name: " + sheetName);
Logger.log("Processed Sheet Name: " + processedSheetsRng[n])
var data = shts[j].getRange("C4").getValue();
var naoConforme = shts[j].getRange("B8:G12").getValues();
shts[j].getRange("B8:G12").copyTo(databaseSheet.getRange(databaseSheet.getLastRow() + 1, 2, 6, naoConforme.length), { contentsOnly: true });
var targetCol = databaseSheet.getRange('A:A').getValues();
var maxIndex = targetCol.reduce(function (maxIndex, row, index) {
return row[0] === "" ? maxIndex : index;
}, 0);
databaseSheet.getRange(maxIndex + 2, 1, naoConforme.length, 1).setValue(data);
}
}
}
Here is the logger output:
function concatenarResumos() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const dsh = ss.getSheetByName("Database");
const ssh = ss.getSheetByName("Suporte");
const svs = ssh.getRange(6, 6, sh.getLastRow() - 5).getValues().flat();
const shts = ss.getSheets();
for (let j = 0; j < shts.length; j++) {
for (let n = 0; n < svs.length; n++) {
if (~svs[n].indexOf(shts[j].getName())) {
let d1 = shts[j].getRange("C4").getValue();
shts[j].getRange("B8:G12").copyTo(dsh.getRange(dsh.getLastRow() + 1, 2, 6, d2.length), { contentsOnly: true });
let tcol = dsh.getRange(1, 1, dsh.getLastRow()).getValues();
let maxIndex = tcol.reduce(function (maxIndex, row, index) {return row[0] === "" ? maxIndex : index;}, 0);
dsh.getRange(maxIndex + 2, 1, d2.length, 1).setValue(d1);
}
}
}
Ranges like F6:F & A:A are bad to use with google apps script because they create a lot of nulls at the end of the array which need to get filtered out.
I am having a difficult time editing this script. It looks at one tab, pulls all rows that meet the criteria and pastes them into another tab. The script below works, but doesn't quite fit my needs. It is pasting the entire row, I only need Columns A,B and C. Ideally, I would need the data copied into Columns A,D and E respectively. Thanks for any help!
function Migrate2() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('OnBoard');
var targetSheet = ss.getSheetByName('NewHire');
var val = sheet.getRange('a3:l').getValues();
var headers = val.shift();
var arr = [],
rowsToWriteBack = [];
rowsToWriteBack.push(headers);
val.forEach(function (r, i) {
r[7] == 'COMPLETE'&& r[11] == 'N' ? arr.push(r) : rowsToWriteBack.push(r)});
if (arr.length > 0) {
targetSheet.getRange(targetSheet.getLastRow() + 1, 1, arr.length, arr[0].length).setValues(arr);
}
}
Try this
function Migrate2() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('OnBoard');
var targetSheet = ss.getSheetByName('NewHire');
var val = sheet.getRange('a3:l').getValues();
var headers = val.shift();
var arr = [],
rowsToWriteBack = [];
rowsToWriteBack.push(headers);
val.forEach(function (r, i) {
r[7] == 'COMPLETE'&& r[11] == 'N' ?
arr.push([r[0],r[1],r[2]]) :
rowsToWriteBack.push([r[0],r[1],r[2]])
});
if (arr.length > 0) {
for(var i = 0; i < arr.length; i++) {
targetSheet.getRange(targetSheet.getLastRow() + i + 1, 1, 1, 1).setValues(arr[i][0]);
targetSheet.getRange(targetSheet.getLastRow() + i + 1, 4, 1, 1).setValues(arr[i][1]);
targetSheet.getRange(targetSheet.getLastRow() + i + 1, 5, 1, 1).setValues(arr[i][2]);
}
}
}
}
Hard to test without access to the environment you're working in, but I think the above should work. Good luck!
Here's the updated version that (hopefully) fixes the staggering issue:
function Migrate2() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('OnBoard');
var targetSheet = ss.getSheetByName('NewHire');
var val = sheet.getRange('a3:l').getValues();
var headers = val.shift();
var arr = [],
rowsToWriteBack = [];
rowsToWriteBack.push(headers);
val.forEach(function (r, i) {
r[7] == 'COMPLETE'&& r[11] == 'N' ?
arr.push([r[0],r[1],r[2]]) :
rowsToWriteBack.push([r[0],r[1],r[2]])
});
if (arr.length > 0) {
for(var i = 0; i < arr.length; i++) {
var addToRow = targetSheet.getLastRow() + i + 1;
targetSheet.getRange(addToRow, 1, 1, 1).setValues(arr[i][0]);
targetSheet.getRange(addToRow, 4, 1, 1).setValues(arr[i][1]);
targetSheet.getRange(addToRow, 5, 1, 1).setValues(arr[i][2]);
}
}
}
}
attempt #3 to prevent the row skipping
function Migrate2() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('OnBoard');
var targetSheet = ss.getSheetByName('NewHire');
var startingRow = targetSheet.getLastRow() + 1;
var val = sheet.getRange('a3:l').getValues();
var headers = val.shift();
var arr = [],
rowsToWriteBack = [];
rowsToWriteBack.push(headers);
val.forEach(function (r, i) {
r[7] == 'COMPLETE'&& r[11] == 'N' ?
arr.push([r[0],r[1],r[2]]) :
rowsToWriteBack.push([r[0],r[1],r[2]])
});
if (arr.length > 0) {
for(var i = 0; i < arr.length; i++) {
var addToRow = startingRow + i;
targetSheet.getRange(addToRow, 1, 1, 1).setValues(arr[i][0]);
targetSheet.getRange(addToRow, 4, 1, 1).setValues(arr[i][1]);
targetSheet.getRange(addToRow, 5, 1, 1).setValues(arr[i][2]);
}
}
}
}
I'm trying to transpose (copy column content into a row) a range from one sheet to another. Yet the catch is that each row has a different number of columns populated, and I don't want to have blank columns copied over into the output sheet.
So I was trying to do the following:
Go to 'import manipulation' tab
row by row (in a loop), check what the last POPULATED column is
Then col by col (second loop), copy each cell's value then paste it onto "Transpose" sheet in the first available row
Keep doing this until the last Populated column was copied over, and then move onto the next row
Repeat
I've ran the debugger and nothing comes up, however when I run the function it doesn't paste anything into the "Test" sheet. Any suggestions?
function transpose(sh) {
var sh = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Import Manipulation");
var lastrow = sh.getLastRow();
var numrows = lastrow;
for(var i= 1; i<= numrows; i++) {
Logger.log(i);
var rowrange = sh.getRange(i, 50);
Logger.log(rowrange);
var lastcol = rowrange.getValues().length;
for(var j=5; j<= lastcol; j++) {
var colrange = sh.getRange(i,j);
var copycell = colrange.getValue();
var pastesheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Test");
var pasterow = pastesheet.getLastRow();
Logger.log(pasterow);
var pastecell = pastesheet.getRange(pasterow + 1, 1);
Logger.log(pastecell);
var doit = pastecell.setValue(copycell);
doit(pastecell);
}
}
}
I was able to do it so that it transposes, and it's working (albeit probably not the most efficient).... appreciate suggestions for how to make it more efficient!
function transpose(sh) {
var sh = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Import Manipulation");
var lastrow = sh.getLastRow();
var numrows = lastrow;
var lastcol = sh.getLastColumn();
for(var i= 1; i<= numrows; i++) {
Logger.log(i);
var rowrange = sh.getRange(i,1,1,lastcol);
Logger.log(rowrange);
for(var j=5; j<= lastcol; j++) {
var colrange = sh.getRange(i,j);
var copycell = colrange.getValue();
var pastesheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Transpose");
var pasterow = pastesheet.getLastRow();
Logger.log(pasterow);
var pastecell = pastesheet.getRange(pasterow + 1, 1);
Logger.log(pastecell);
pastecell.setValue(copycell);
}
}
}
This line of code:
var rowrange = sh.getRange(i, 50);
Is only getting one cell. On the first loop, it gets the cell in row 1 column 50.
The variable lastcol in this line:
var lastcol = rowrange.getValues().length;
will always be 1. getValues() gets a 2D array and in this case it will be [[cellValue]]
I created some new code:
function transpose(sh) {
var arrayThisRow,cellValue,i,j,lastCol,lastrow,numrows,pastesheet,
rowrange,rowValues,sh;
sh = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Import Manipulation");
pastesheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Test");
lastrow = sh.getLastRow();
lastCol = sh.getLastColumn();
Logger.log('lastCol: ' + lastCol);
numrows = lastrow;
arrayThisRow = [];
for(i=1; i<= numrows; i++) {
//Logger.log(i);
rowrange = sh.getRange(i,1,1,lastCol);
//Logger.log(rowrange);
rowValues = rowrange.getValues();//
rowValues = rowValues[0];//There is only 1 inner array
for(j=0; j <= lastCol; j++) {
cellValue = rowValues[j];
if (cellValue) {
arrayThisRow.push(cellValue);
} else {
break;//Stop pushing values into the array as soon as a blank cell is found
}
}
}
Logger.log('arrayThisRow: ' + arrayThisRow)
if (arrayThisRow.length > 0) {
pastesheet.appendRow(arrayThisRow)
}
}
I'm a little bit stuck with my Google Apps script purposed to calculate a sum of cells which are not strikethrough.
Here is its source:
function SumIfNotStrikethrough(rangeA1Notation)
{
var sheet = SpreadsheetApp.getActiveSpreadsheet();
var mysheet = sheet.getActiveSheet();
var dataRange = mysheet.getDataRange();
var mydatarange = mysheet.getRange(rangeA1Notation);
var numRows = mydatarange.getLastRow();
var rowindex = mydatarange.getRowIndex();
var columnindex = mydatarange.getColumnIndex();
var total =0;
for(i=rowindex;i<=numRows;i++)
{
if(dataRange.offset(i-1, columnindex-1, 1, 1).isBlank() != true && dataRange.offset(i-1, columnindex-1, 1, 1).getFontLine() != "line-through")
{
var temp = dataRange.offset(i-1, columnindex-1, 1, 1).getValue();
total = total + temp;
}
}
return total;
}
Here is its formula: =SumIfNotStrikethrough("J2").
I have two questions here:
How to add the Google Apps script to use this formula as, for example, SumIfNotStrikethrough(J2) rather than SumIfNotStrikethrough("J2")? Quotes are so annoying in terms of changing its range manually after scaling the formula on other cells :-(. What should be changed in the source code?
When I run this script I face with following error:
Range not found (line 9, file "SumIfNotStrikethrough"
Thus, how can I fix it?
UPD № 1. Here is an example with a string reference, but it only counts the number of cells:
function countStrike(range) {
var count = 0;
SpreadsheetApp.getActiveSheet()
.getRange(range)
.getFontLines()
.reduce(function (a, b) {
return a.concat(b);
})
.forEach(function (el) {
if (el === "line-through") {
count++
}
});
return count;
}
UPD № 2. Unfortunately, this question is different from my previous question "Sum cells if they are not bold". I respectively tried to change the script, but it didn't work. Yes, it sums cells but it sums all the cells with strike-through and without :-(.
Here is what I changed:
function SumIfNotStrikethrough(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = SpreadsheetApp.getActiveSheet();
var formula = SpreadsheetApp.getActiveRange().getFormula();
var args = formula.match(/=\w+\((.*)\)/i)[1].split("!");
try {
if (args.length == 1) {
var range = sheet.getRange(args[0]);
}
else {
sheet = ss.getSheetByName(args[0].replace(/'/g, ''));
range = sheet.getRange(args[1]);
}
}
catch(e) {
throw new Error(args.join("!") + " is not a valid range");
}
var weights = range.getFontLine();
var numbers = range.getValues();
var x = 0;
for (var i = 0; i < numbers.length; i++) {
for (var j = 0; j < numbers[0].length; j++) {
if (weights[i][j] != "line-through" && typeof numbers[i][j] == "number") {
x += numbers[i][j];
}
}
}
return x;
}
Thank you for all your attempts to help me in advance!
I've modified the suggested answer with getFontLines() rather that getFontLine():
function SumIfNotStrikethrough1(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = SpreadsheetApp.getActiveSheet();
var formula = SpreadsheetApp.getActiveRange().getFormula();
var args = formula.match(/=\w+\((.*)\)/i)[1].split("!");
try {
if (args.length == 1) {
var range = sheet.getRange(args[0]);
}
else {
sheet = ss.getSheetByName(args[0].replace(/'/g, ''));
range = sheet.getRange(args[1]);
}
}
catch(e) {
throw new Error(args.join("!") + " is not a valid range");
}
var lines = range.getFontLines();
var numbers = range.getValues();
var x = 0;
for (var i = 0; i < numbers.length; i++) {
for (var j = 0; j < numbers[0].length; j++) {
if (lines[i][j] != "line-through" && typeof numbers[i][j] == "number") {
x += numbers[i][j];
}
}
}
return x;
}
Here is the formula to use it: =SumIfNotStrikethrough1(A2:B3).
Now that seems to be working properly in its single use.
So, I'm working on a javascript application that can solve any size matrix. I'm running into a SUPER weird problem, where my main array only has the value of 0 after a certain point. The input should be a data set, like this
1, 8
2, 10
3, 13
4, 17
5, 22
But I'm having trouble with it. When I run the code, the console.log prints out a pretty derpy array
[[1, 1, 1, 8],
[0, 0, 0, 0],
[0, 0, 0, 0]]
It gets even weirder. If I move the console.log to before I call the rref function, I get the same thing.
Anybody ever seen this before? Anyone know how to fix it? Thanks!
//Matrix object
var matrix = {
startingDataSet: [],
degree: 0,
M: []
}
//splits up user input into a more readable format
function getDataFromString(data) {
var points = data.split("\n");
for (var i=0; i<points.length; i++) {
points[i] = points[i].split(", ");
points[i][0] = parseInt(points[i][0]);
points[i][1] = parseInt(points[i][1]);
}
return points;
}
//finds the degree of the polynomail from the matrix object's data
function setPolynomialDegree(original) {
var data = original;
console.log(original);
//temporary data set to hold numbers in
var tempNumbers = [];
var degree = 1;
//move the original set of Y values into the temporary data set
for (var i = 0; i < data.length; i++) {
tempNumbers.push(data[i][1]);
}
//while the numbers in tempdata are not the same, execute subtraction
while (tempNumbers[0] != tempNumbers[1]) {
var newnums = []
var l = tempNumbers.length;
//find the difference for every set of numbers (0 & 1, 1 & 2, 2 & 3, etc.), and push those into the new data set
for (var i = 0; i < l - 1; i++) {
newnums.push(tempNumbers[i + 1] - tempNumbers[i]);
}
//replace old data set with new one
tempNumbers = newnums;
//increase polynomial degree by one
degree += 1;
}
return degree;
}
//add 2 arrays together
function addrows(r1, r2) {
var temprow = [];
for (var i = 0; i < r1.length; i++) {
temprow.push(r1[i] + r2[i]);
}
return temprow;
}
//multiply array by constant
function multrow(r1, num) {
var temprow = [];
for (var i = 0; i < r1.length; i++) {
temprow.push(r1[i] * num);
}
return temprow;
}
//rref function
function rref(mtrx, deg) {
var temp1 = [];
var temp2 = [];
for (var row = 0; row < mtrx.length; row++) {
for (var j = 0; j < mtrx.length-1; j++) {
temp1 = multrow(mtrx[row], mtrx[j+1][row]);
temp2 = multrow(mtrx[j+1], mtrx[row][row]);
temp1 = multrow(temp1, -1);
mtrx[j+1] = addrows(temp1, temp2);
}
}
return mtrx;
}
//Main function that will solve the matrix
function solveFromDataSet(data) {
data = getDataFromString(data);
for (var i=0; i<data.length; i++) {
matrix['startingDataSet'].push(data[i]);
}
matrix.degree = setPolynomialDegree(matrix.startingDataSet);
matrix.M = [];
for (var i = 0; i < matrix.degree; i++) {
var row = [];
for (var j = matrix.degree; j > 0; j--) {
row.push(Math.pow(data[i][0], j - 1));
}
row.push(data[i][1]);
matrix['M'][i] = row;
}
var var_array = rref(matrix['M']);
console.log(matrix.M);
return matrix.M;
}