Copying and Pasting, but Pasting to Wrong Location - google-apps-script

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;
}

Related

Script to copy contents of cell (in a2) and paste this into 1st empty (of text and formulas) cell on row 2

I am trying to write a script to copy contents of cell (in a2) and paste this into the 1st empty (of text and formulas) cell on row 2.
Ones that I have tried to copy and use are to do similar but finding the next row in a column.
I have also tried functions that should do this but they find the first cell in the row that contains a formula, I need it to be empty of text and formulas.
Can anyone help please?
Thanks
Copy A2 to end of row2 + 1 col
function copy() {
const ss = SpreadsheetApp.getActive();
const sh = ss.getSheetByName("Your Sheet Name");
const v = sh.getRange("A2").getValue();
sh.getRange(2, getRowWidth(2,sh,ss) + 1).setValue(v);
}
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;
}
Use getValues to check whether there's some text in your cells.
Use getFormulas to check whether there are formulas in your cells.
Code sample:
function copyToFirstEmptyCell() {
const rowIndex = 2;
const sheet = SpreadsheetApp.getActiveSheet();
const row = sheet.getRange(`${rowIndex}:${rowIndex}`);
const values = row.getValues()[0];
const a2Value = values.shift();
const formulas = row.getFormulas()[0];
const columnIndex = values.findIndex((value,i) => !value.length && !formulas[i+1].length) + 2;
const foundCell = sheet.getRange(rowIndex, columnIndex);
foundCell.setValue(a2Value);
foundCell.activate();
}

App Script to Move data daily to a new sheet, Keeping track of each days data

Looking for a script that will move data from one sheet to another, moving down the columns for each day.
Day 1 copy data in B3:B24 to log sheet column A with date copied in row 1
Day 2 copy data in B3:B24 to log sheet Column B and with date copied in row 1
This is for google sheets
Log Data
function logdata() {
const ss = SpreadsheetApp.getActive();
const sh = ss.getSheetByName("Enter your Sheet Name");
const vs = sh.getRange("B3:B24").getDisplayValues();
const lsh = ss.getSheetByName("Enter Log Sheet Name");
const dts = Utilities.formatDate(new Date(),Session.getScriptTimeZone(),"MM/dd/yyyy")
vs.unshift([dts]);
lsh.getRange(1,getRowWidth(1,lsh,ss) + 1, vs.length, vs[0].length);
}
function dailyTimer() {
if(ScriptApp.getProjectTriggers().filter(t => t.getHandlerFunction() == "logdata").length == 0) {
ScriptApp.newTrigger("logdata").timeBased().atHour(1).everyDays(1).create();//You can add more detail if you wish
}
}
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;
}

Pop() and append() to next row

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);
}

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);
}

script to automatically add a new row when filling the field of column 8

I need a script to automatically add a blank line at the beginning whenever I finish filling the field in column 8 of a line?
Note: It is for this new line preserve the formula of the previous line.
This is the script that I am using.
It works by writing any part of the line (any column)
but I wanted him to be activated only when i write something in column 8.
function onEdit(e) {
if (e) {
var ss = e.source.getActiveSheet();
var r = e.source.getActiveRange();
// If you want to be specific
// do not work in first row
// do not work in other sheets except "Outubro"
if (r.getRow() != 1 && ss.getName() == "Outubro") {
// E.g. status column is
status = ss.getRange(r.getRow(), 8).getValue();
// Status
if (status == 'yes', 'null') {
var planilha = SpreadsheetApp.getActiveSpreadsheet();
var folha = planilha.getActiveSheet();
if (folha.getName() === "Outubro")
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
sheet.insertRowBefore(4);
var rangeToCopy = sheet.getRange(3, 1, 1, sheet.getMaxColumns());
rangeToCopy.copyTo(sheet.getRange(4, 1));
}
}
}
}
Thank you for the help from the community.
The code is now working.
I'll leave the code here for anyone who need.
Once again thank you all for the help.
function onEdit(e) {
if (e) {
var ss, activeRange, activeColumn;
var planilha = SpreadsheetApp.getActiveSpreadsheet();
var folha = planilha.getActiveSheet();
if (folha.getName() === "Outubro")
ss = SpreadsheetApp.getActiveSpreadsheet();
activeRange = ss.getActiveRange();
activeColumn = activeRange.getColumn();
//Logger.log('activeColumn: ' + activeColumn); //VIEW LOGS
if (activeColumn !== 8) {return;};//Quit if not column 8 {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
sheet.insertRowBefore(4);
var rangeToCopy = sheet.getRange(3, 1, 1, sheet.getMaxColumns());
rangeToCopy.copyTo(sheet.getRange(4, 1));
}
}