Pop() and append() to next row - google-apps-script

In this spreadsheet, I have a row with all the employee data, with values coming from another table; In order to create the layout requested, I need 3 rows per employee, each row starting with the |1|,|1.1|,|1.1|, I found some code here that allows me to append two rows to every row of data, but no idea how to move the |1.1|,GTF,'100' to the next row, and then, |1.1|,PPA,'15' to the next one.
This is what i have:
|1|,'900','04000','0000','0','0000','0','11','0','S','A',|1.1|,GTF,'100',|1.1|,PPA,'15'
|1|,'986','01000','0000','0','0000','0','14','0','S','A',|1.1|,GTF,'110',|1.1|,PPA,'30'
|1|,'1046','01000','0000','0','0000','0','14','0','S','A',|1.1|,GTF,'120',|1.1|,PPA,'45'
And what Im looking for is to look like this:
|1|,'900','04000','0000','0','0000','0','11','0','S','A'
|1.1|,GTF,'100'
|1.1|,PPA,'15'
|1|,'986','01000','0000','0','0000','0','14','0','S','A',
|1.1|,GTF,'110'
|1.1|,PPA,'30'
function insertRows() {
var startRow = 1;
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Prenom");
var sourceRange = sheet.getRange(startRow, 1, sheet.getLastRow());
var sheetData = sourceRange.getValues();
var numRows = sourceRange.getNumRows() - startRow;
// Logger.log(numRows);
for (var i=numRows; i > -1; i--) {
if (sheetData[i].join("")) {
sheet.insertRowsAfter(i + startRow, 2);
}
}
}
Which leaves me with two empty rows. ty

You have to split the cell value every time |1.1| is found. There are several ways to do this. For example, you can combine indexOf and splice and in the sample below.
After you have done that, use setValues to overwrite the original data.
Code sample:
function insertRows() {
var startRow = 1;
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Prenom");
var sourceRange = sheet.getRange(startRow, 1, sheet.getLastRow());
var sheetData = sourceRange.getValues().flat();
sheetData = sheetData.map(cell => {
const array = cell.split(",");
const outputArray = [];
let index = 0;
while (index >= 0) {
index = array.indexOf("|1.1|", 1);
if (index !== -1) section = array.splice(0, index).join(",");
else section = array.join(",");
outputArray.push(section);
}
return outputArray;
}).flat().map(row => [row]);
sheet.getRange(startRow, 1, sheetData.length, sheetData[0].length).setValues(sheetData);
}

function separate() {
const s = `|1|,'900','04000','0000','0','0000','0','11','0','S','A',|1.1|,GTF,'100',|1.1|,PPA,'15'
|1|,'986','01000','0000','0','0000','0','14','0','S','A',|1.1|,GTF,'110',|1.1|,PPA,'30'
|1|,'1046','01000','0000','0','0000','0','14','0','S','A',|1.1|,GTF,'120',|1.1|,PPA,'45'`;
let r = s.match(/([^']+[^|]+)/g);
Logger.log(r.join('\n'));
}
Execution log
12:02:55 PM Notice Execution started
12:02:55 PM Info ||1|,'900','04000','0000','0','0000','0','11','0','S','A',
|1.1|,GTF,'100',
|1.1|,PPA,'15'
|1|,'986','01000','0000','0','0000','0','14','0','S','A',
|1.1|,GTF,'110',
|1.1|,PPA,'30'
|1|,'1046','01000','0000','0','0000','0','14','0','S','A',
|1.1|,GTF,'120',
|1.1|,PPA,'45'
12:02:56 PM Notice Execution completed
function separate() {
const s = `|1|,'900','04000','0000','0','0000','0','11','0','S','A',|1.1|,GTF,'100',|1.1|,PPA,'15'
|1|,'986','01000','0000','0','0000','0','14','0','S','A',|1.1|,GTF,'110',|1.1|,PPA,'30'
|1|,'1046','01000','0000','0','0000','0','14','0','S','A',|1.1|,GTF,'120',|1.1|,PPA,'45'`;
let r = s.match(/([^']+[^|]+)/g).map(e => [e]);
let sh = SpreadsheetApp.getActiveSheet();
sh.getRange(1,1,r.length).setValues(r);
}

Related

Copying and Pasting, but Pasting to Wrong Location

I hope I post this correctly, first timer. Sorry in advance for any rules or formalities I violate.
Goal: I am trying to copy a range of data from a source tab, then paste the data into a target tab in the first available column in row 2, which is B2 (there is a header A1:Z1).
Issue: I want it to post the data in B2 as its the first open cell in row 2, but the code sees the first available column as AA as there is no header, so it posts the range starting in AA:2.
Help? Haha.
function movelog() {
var sheetFrom = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Entry");
var sheetTo = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Log");
// Copy from 3rd row, 5th column (E), all rows for one column
var valuesToCopy = sheetFrom.getRange(3, 5, sheetFrom.getLastRow(), 1).getValues();
//Paste to another sheet from first cell onwards
sheetTo.getRange(2,sheetTo.getLastColumn()+1,valuesToCopy.length,1).setValues(valuesToCopy);
}
Move Log
function movelog() {
const ss = SpreadsheetApp.getActive();
const sheetFrom = ss.getSheetByName("Entry");
const sheetTo = ss.getSheetByName("Log");
const valuesToCopy = sheetFrom.getRange(3, 5, sheetFrom.getLastRow() - 2).getValues();
sheetTo.getRange(2, getRowWidth(2, sheetTo, ss) + 1, valuesToCopy.length, 1).setValues(valuesToCopy);
}
function getRowWidth(row, sh, ss) {
var ss = ss || SpreadsheetApp.getActive();
var sh = sh || ss.getActiveSheet();
var row = row || sh.getActiveCell().getRow();
var rcA = [];
if (sh.getLastColumn()) { rcA = sh.getRange(row, 1, 1, sh.getLastColumn()).getValues().flat().reverse(); }
let s = 0;
for (let i = 0; i < rcA.length; i++) {
if (rcA[i].toString().length == 0) {
s++;
} else {
break;
}
}
return rcA.length - s;
}

data transfert based on cell value on google sheet

I'm not good with coding and i tried to mix some codes that i found and made what i needed, but now i face a difficult problem for me, so I'm trying when to press the button that i created to run the script to send the data that have for example an 'X' in the last column. i successfully made the sending from one sheet to another but it send all the data for now i want to be sent only the chosen ones with an 'X'.
any help I'll be grateful.
this is my code
thank you
var ss = SpreadsheetApp.getActiveSpreadsheet();
var copySheet = ss.getSheetByName("Sheet1");
var url = "https://docs.google.com/spreadsheets/d/15nIAXcP0a14OvvBr5lww4tO23stQD4PEu0QDAcgaFyE/edit#gid=0";
var ss2 = SpreadsheetApp.openByUrl(url);
var pasteSheet = ss2.getSheetByName("Sheet2");
// get source range
var max = copySheet.getMaxRows().toString();
var range = copySheet.getRange(2,1,max,4);
var dataValues = range.getValues();
for(var i = 1; i < dataValues.length; i++)
{
if(dataValues[i][5] === 'X')
{
copySheet.appendRow([dataValues[i][0],
dataValues[i][1],
dataValues[i][2],
dataValues[i][3],
dataValues[i][4]]);
}
}
for(var i = 1; i < dataValues.length; i++)
{
if(dataValues[i][5] === 'X')
{
var clearRow = i+1;
dataSheet.getRange('A' + clearRow + ':F' + clearRow).clear();
}
}
// get destination range
var destination = pasteSheet.getRange(pasteSheet.getLastRow()+1,1,max,1);
// clear source values
Browser.msgBox('Commande Confirmer');
}
This is all that your function does
dataSheet is undefined so I assume it was csh
function lfunko() {
const ss = SpreadsheetApp.getActive();
const csh = ss.getSheetByName("Sheet1");
const ss2 = SpreadsheetApp.openByUrl("ssurl");
const psh = ss2.getSheetByName("Sheet2");
var vs = csh.getRange(2, 1, csh.getLastRow() - 1, csh.getLastColumn()).getValues();
vs.forEach((r,i) => {
if (vs[i][5] === 'X') {
csh.appendRow([vs[i][0], vs[i][1], vs[i][2], vs[i][3], vs[i][4]]);
csh.getRange(i + 1, 1, 1, 6).clear();
}
});
}

Google apps script - right align cell based on another cell's value

I am trying to write a Google Apps Script that will right align text strings in column C, if column F in the same row is not blank. Please see the sample screenshot attached. The script should make C4 and C7 right aligned.
sample-google-sheet
I have also tried !isnotblank function but couldn't get that to work either. When running the code below nothing happens, and it doesn't stop running until I click cancel.
function alignRight() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Sheet1');
var startRow = 3;
var numRows = 1000;
var dataRange = sheet.getRange(startRow, 1, numRows, 6);
var data = dataRange.getValues();
for (var i=0; i<numRows; i++) {
var row = data[i];
var columnF = sheet.getDataRange().getValues();
columnF.forEach(function(row) {
row[6]
});
var columnC = sheet.getDataRange().getValues();
columnC.forEach(function(row) {
row[3]
});
if (0 < columnF) {
sheet.getRange(columnC).setHorizontalAlignment("right");
};
};
}
So first you want to not call getRange() and then call getDataRange() a few times in your for loop because you already have all the data you need with your first call. So basically
var data = dataRange.getValues()
data.forEach( (row, i) => {
// Column F is 6th in line, so it would be in the 5th index
if( !row[5] || !row[5].length ) {
// align right
sheet.getRange(i+startRow, 3).setHorizontalAlignment("right");
}
})
Align right
function alignRight() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Sheet1');
var startRow = 3;
var data = sheet.getRange(startRow, 1, sheet.getLastRow() - startRow + 1, 6).getValues();
data.forEach(r => {
if(r[5])sheet.getRange(i + startRow,3).setHorizontalAlignment("right");
});
}
A bit faster
function alignRight() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Sheet1');
var startRow = 3;
var numRows = 1000;
var data = sheet.getRange(startRow, 1, sheet.getLastRow() - startRow + 1, 6).getValues();
let cA = [];
data.forEach(r => {
if (r[6]) {
cA.push(['right'])
} else {
cA.push(['left']);
}
});
sheet.getRange(startRow, 3,cA.length,1).setHorizontalAlignments(cA);
}

Get Selected Row's Specific Col Value via script (Google Sheets)

I've been trying to get this one to work without success so far.
I need to get the TaskNumber on the first column of the row I'm on and bring it to the destination sheet, so that I can update it there.
I have the following, which I'm tweaking to achieve my goal, but I guess I've bumped into my limitation walls:
function jump() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var TaskNumberSheet = ss.getSheetByName('To-Do List');
var TaskNoRow = TaskNumberSheet.getActiveCell();
var TaskNoCol = TaskNoRow.getColumn() == 1
var TaskNo = TaskNoCol.getValue;
var sheet = ss.getSheetByName('Updates');
//var Tasks = ss.getSheetByName("To Do List").getActiveRange(Tasks.getColum(1)).getValue();
var values = sheet.getRange("B:B").getValues();
var maxIndex = values.reduce(function(maxIndex, row, index) {
return row[0] === "" ? maxIndex : index;
}, 0);
sheet.setActiveRange(sheet.getRange(maxIndex + 2,2)).setValue(TaskNo);
}
Any help is appreciate.
Cheers,
A
If I understood you correctly, you want to:
Get the value in column A from the currently active row (in sheet To-Do List).
Find the first empty cell in column B (in sheet Updates) (start looking at row #8).
Copy the value that was retrieved in step 1 to the cell retrieved in step 2.
Set the cell retrieved in step 2 as the active cell.
If that's the case, you can do the following:
function jump() {
var ss = SpreadsheetApp.getActive();
// Step 1:
var TaskNumberSheet = ss.getSheetByName('To-Do List');
var TaskNoRow = TaskNumberSheet.getActiveCell().getRow();
var TaskNoCol = 1;
var TaskNo = TaskNumberSheet.getRange(TaskNoRow, TaskNoCol).getValue();
// Step 2:
var sheet = ss.getSheetByName('Updates');
var firstRow = 8;
var column = 2;
var numRows = sheet.getLastRow() - firstRow + 1;
var values = sheet.getRange(firstRow, column, numRows).getValues().map(function(value) {
return value[0]
});
var i = 0;
for (i; i < values.length; i++) {
if (values[i] === "") break;
}
var targetRange = sheet.getRange(i + firstRow, column);
targetRange.setValue(TaskNo); // Step 3
sheet.setActiveRange(targetRange); // Step 4
}
function jump() {
var TargetRow=?;//Fillin target row
var TargetCol=?;//Fillin target column
var ss=SpreadsheetApp.getActive();
var TaskNumberSheet=ss.getSheetByName('To-Do List');
var TaskNoRow=TaskNumberSheet.getActiveCell().getRow();//Getting row from active cell
var TaskNoCol=1
var TaskNo=TaskNumberSheet.getRange(TaskNoRow,TaskNoCol).getValue();
ss.getSheetByName('Updates').getRange(targetRow,targetCol).setValue(TaskNo);
}

Google Apps Script : Insert x rows after every cells in range

I'm trying to add x blank rows after every no blank cells in a range.
I use a loop but with my loop, only the first cell is affected.
Here, my code :
I think I know where I'm wrong (I need to loop in sheet.insertRowsAfter(i, 5); but I can not do it...)
Thank you !
function insertRows() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("test");
var sourceRange = sheet.getRange(10, 1, sheet.getLastRow());
var sheetData = sourceRange.getValues();
var numRows = sourceRange.getNumRows();
Logger.log(numRows);
for (var i=10; i < numRows; i++) {
sheet.insertRowsAfter(i, 5);
}
}
In your case we need to start at the end of the range and work our way up, adding rows where appropriate. The code below will do this and add a 5 rows below any row which has data, even adding rows if there is a blank row following the one with data. You could pass startRow to the function if you wish for more flexibility
function insertRows() {
var startRow = 10;
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("test");
var sourceRange = sheet.getRange(startRow, 1, sheet.getLastRow());
var sheetData = sourceRange.getValues();
var numRows = sourceRange.getNumRows() - startRow;
// Logger.log(numRows);
for (var i=numRows; i > -1; i--) {
if (sheetData[i].join("")) {
sheet.insertRowsAfter(i + startRow, 5);
}
}
}
As a general comment: You are retrieving more rows as necessary as sheet.getLastRow() gets the last row number with data and the use in getRange() is telling the app to pull that number of rows as opposed to that number minus the starting position.
Try the below. This will add 3 rows when there is a no blank cell.
function insertRows() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("test");
var sourceRange = sheet.getRange(1, 1, sheet.getLastRow());
var sheetData = sourceRange.getValues();
for (var i=0; i < sheetData.length; i++) {
if(sheetData[i][0]!=""){
sheet.insertRowsAfter(i+1, 3);
sheetData = sheet.getRange(1, 1, sheet.getLastRow()).getValues();
}
}
}