Is it possible to copy range with formating using apps scripts? - google-apps-script

dears
I need your support to edit this function as I need to copy data with formatting
This is the equation I working on
function copyRows()
{
var copySheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('sheet1');
var dataSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('sheet2');
var dataRange = dataSheet.getDataRange();
var dataValues = dataRange.getValues();
for(var i = 1; i < dataValues.length; i++)
{
if(dataValues[i][29] === 'done')
{
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][29] === 'done')
{
var clearRow = i+1;
dataSheet.getRange('A' + clearRow + ':AC' + clearRow).clear();
}

Related

Google Sheet : The result could not be auto-expanded. Please insert new columns (1)

This script import opportunities that we get. It populates rows which then calculates some numbers such as interest and stuff. However, I now have errors when populating my cells (#REF error, see pictures below). Nothing has changed so my first guess is it has do with the processing of the sheet which has become too heavy.
`
function onInstall(e) {
onOpen(e);
}
function onOpen(e) {
var menu = SpreadsheetApp.getUi().createAddonMenu();
menu.addItem('Créer étude', 'init');
menu.addToUi();
}
function init() {
ss = SpreadsheetApp.getActiveSpreadsheet();
identifyJe();
sheetMaker = ss.getActiveSheet();
currentRow = ss.getActiveCell().getRowIndex();
ssEtudes = SpreadsheetApp.openById(getSheetEtudesId());
var ui = SpreadsheetApp.getUi();
var respon se = ui.alert(
'Ligne sélectionnée : ' + currentRow + '. Exécuter ?',
ui.ButtonSet.OK_CANCEL
);
if (response !== ui.Button.OK) return;
doEtude();
doContrat();
doPhases();
}
function doEtude(nomEtude) {
var etudeData = [];
for (var i = 0; i < etudeNamedRanges.length; i++) {
var column = ss.getRangeByName(etudeNamedRanges[i]).getColumn();
etudeData.push(sheetMaker.getRange(currentRow, column).getValue());
}
var destSheet = ssEtudes.getSheetByName('etudes');
var rowToAppend = getFirstEmptyRow(destSheet, 0);
for (var i = 0; i < etudeData.length; i++) {
var column = ssEtudes.getRangeByName(etudeNamedRanges[i]).getColumn();
destSheet.getRange(rowToAppend, column).setValue(etudeData[i]);
}
}
function doContrat() {
var contratData = [];
for (var i = 0; i < contratNamedRanges.length; i++) {
var column = ss.getRangeByName(contratNamedRanges[i]).getColumn();
contratData.push(sheetMaker.getRange(currentRow, column).getValue());
}
var destSheet = ssEtudes.getSheetByName('contrats');
var rowToAppend = getFirstEmptyRow(destSheet, 11);
for (var i = 0; i < contratData.length; i++) {
destSheet.getRange(rowToAppend, i + 4).setValue(contratData[i]);
}
}
function doPhases() {
var phasesCoords = getPhasesCoords();
var phasesData = [];
for (var i = 0; i < phasesCoords.length; i++) {
var phaseData = getPhaseData(phasesCoords[i]);
phaseData.unshift(i + 1);
phasesData.push(phaseData);
}
var destSheet = ssEtudes.getSheetByName('phases');
var rowToAppend = getFirstEmptyRow(destSheet, 9);
var columns = [];
for (var nPhase = 0; nPhase < phasesData.length; nPhase++) {
var phaseData = phasesData[nPhase];
for (var i = 0; i < phaseData.length; i++) {
if (columns[i] === undefined)
columns[i] = ssEtudes.getRangeByName(phasesNamedRanges[i]).getColumn();
destSheet
.getRange(rowToAppend + nPhase, columns[i])
.setValue(phaseData[i]);
}
}
}
`
Type of formula
The results
The error, which translates into The result could not be auto-expanded. Please insert new columns (1).
The results actually appear for some time and disappear after a few seconds, constantly. Does it have something to do with the size of the spreadsheet ?

Google Script adding cell name on a formula

I'm new to google script, and learn a lot by searching through this site, but now I'm trying to figure out how can I add a cell name (A1, A2, .....) to a formula using google script.
Please see my sample here: https://docs.google.com/spreadsheets/d/1mttb7dD4RvfXmNt3xGe7cAR6SAXB7Tom97vNOK-YQB0/edit?usp=sharing
On column C you will see "=A16+1" but it should be like "=A2+1" since I'm on row 2
here is the google script code
function myFunction() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("test1");
var range = sheet.getActiveCell();
var valueToWatch = "y";
var searchRange = sheet.getRange("A1:A" + sheet.getLastRow()); // Modified
// get the values in an array
var values = searchRange.getValues();
// examine the values in the array
var i = [];
for (var y = 0; y < values.length; y++) {
if (values[y][0] == valueToWatch) {
i.push("C" + (y + 1)); // Modified
}
}
//sheet.getRangeList(i).setValue("this is a test");
var data = [];
for (var x = 0; x < values.length; x++) {
data = ['=A' + (x + 1).toString() + '&"1"'];
}
sheet.getRangeList(i).setFormula(data);
}
Upon reviewing your code, it looks like you want to add formula to column C if the same row in column A has y.
Try this code below:
function myFunction() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("test1");
var valueToWatch = "y";
var searchRange = sheet.getRange("A1:A" + sheet.getLastRow()); // Modified
var values = searchRange.getValues();
var i = [];
for (var y = 0; y < values.length; y++) {
if(values[y][0] == valueToWatch){
i.push("C" + (y + 1));
}else{
i.push('');
}
}
var data = [];
for (var x=0; x < i.length; x++){
if(i[x] != ''){
var rowNum = i[x].replace( /^\D+/g, '');
data.push(['=A' + rowNum + '&"1"' ])
}else{
data.push(['']);
}
}
sheet.getRange("C1:C" + sheet.getLastRow()).setFormulas(data);
}
Example:
Reference:
Range.setFormulas(formulas)

Question Marks Symbols when importing CSV

I'm importing a CSV from an email with the following code:
function RetrieveAttachment()
{
var threads = GmailApp.search("Report*")
var msgs = GmailApp.getMessagesForThreads(threads);
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var today= new Date();today.setDate(today.getDate());
var today= Utilities.formatDate(today, "GMT+1", "dd.MM.yyyy");
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Import");
for(var i = 0; i < msgs.length; i++)
{
for(var j = 0; j < msgs[i].length; j++)
{
var msgdate = Utilities.formatDate(new Date(msgs[i][j].getDate()), "GMT+1", "dd.MM.yyyy");
if(msgdate == today)
{
var attachments = msgs[i][j].getAttachments();
for(var k = 0; k < attachments.length; k++)
{
var attachmentName = attachments[k].getName();
var stringValue = attachmentName.search("*");
if(stringValue > -1)
{
var attachmentData = attachments[k].getDataAsString();
var parseCsv = Utilities.parseCsv(attachmentData, ",");
sheet.clearContents();
sheet.getRange(1,1, parseCsv.length, parseCsv[0].length).setValues(parseCsv);
}
}
}
}
}
}
Usually this works just fine, but with one specific csv I get via email only this two question marks are being written in the Spreadsheet:
I checked with the debugger and apparently the whole content of the csv is being read, however not correctly parsed:
I presume this is some coding problem, however I tried with the base64Encode/base64Decode utilities without any success.
Does someone have any clue on how to solve this?
The original CSV file was UTF-16 and tab separated, I solved it specifying the encoding and different separator:
var attachmentData = attachments[k].getDataAsString("UTF-16");
var parseCsv = Utilities.parseCsv(attachmentData, "\t");
Here the new Code
function RetrieveAttachment()
{
var threads = GmailApp.search("Report*")
var msgs = GmailApp.getMessagesForThreads(threads);
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var today= new Date();today.setDate(today.getDate());
var today= Utilities.formatDate(today, "GMT+1", "dd.MM.yyyy");
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Import");
for(var i = 0; i < msgs.length; i++)
{
for(var j = 0; j < msgs[i].length; j++)
{
var msgdate = Utilities.formatDate(new Date(msgs[i][j].getDate()), "GMT+1", "dd.MM.yyyy");
if(msgdate == today)
{
var attachments = msgs[i][j].getAttachments();
for(var k = 0; k < attachments.length; k++)
{
var attachmentName = attachments[k].getName();
var stringValue = attachmentName.search("*");
if(stringValue > -1)
{
var attachmentData = attachments[k].getDataAsString("UTF-16");
var parseCsv = Utilities.parseCsv(attachmentData, "\t");
sheet.clearContents();
sheet.getRange(1,1, parseCsv.length, parseCsv[0].length).setValues(parseCsv);
}
}
}
}
}
}

Creating sheets with from master sheet

I have a sheet named form responses which gets input from google
forms,Then I created sheets with names from Column C which is
employee code and append all the respective rows from form responses
to the newly created sheets.
Now I have sheets with name as employee code ( which is in column c of the sheet). Then I want to create secondary sheets from this master sheet(sheets with name as employee code) whose name is using the column E value as attached to the Employee code.for eg : if Emp code is 10003825 and value in column E is ASR, the sheet name should be 10001515ASR.
In Column E there are only 4 values ADC,ASR ACC,RSR. let the master sheet(sheets with name as employee code) retain ADC rows always while when other rows containing ASR,ACC,RSR comes append the respective row to the newly created sheet(ie if ASR the row goes to 10001515ASR).
I have shown my present sheet and expected output
The code I developed is shown below:
function switchSheet(){
var activeSpreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var sheets = activeSpreadsheet.getSheets();
for (var i = 1; i < sheets.length; i++) {
var p = sheets[i].getSheetName();
sheetCreateChannel(p);
}
}
function sheetCreateChannel(ss){
var activeSpreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var sheet1 = activeSpreadsheet.getSheetByName(ss);
var getNames = sheet1.getDataRange().getValues();
getNames.shift();
var sheets = activeSpreadsheet.getSheets();
var sheetsObj = {};
for (var i = 0; i < sheets.length; i++) {
sheetsObj[sheets[i].getSheetName()] = sheets[i];
for (var i = 0; i < getNames.length; i++) {
var r = getNames[i];
if (r[4].toString()== "ASR"&& !((ss+(r[4])) in sheetsObj)) {
var newSheet = activeSpreadsheet.insertSheet(ss + "ASR");
sheetsObj[ss+"ASR"] = newSheet;
}
else if (r[4].toString()== "ACC"&&!((ss+(r[4])) in sheetsObj)) {
var newSheet = activeSpreadsheet.insertSheet(ss + "ACC");
sheetsObj[ss+"ACC"] = newSheet;
}
else if (r[4].toString()== "RSR"&& !((ss+(r[4])) in sheetsObj)) {
var newSheet = activeSpreadsheet.insertSheet(ss + "RSR");
sheetsObj[ss+"RSR"] = newSheet;
}
else {
break;
}
}
}
var deleteRows = 0;
for (var i = 0; i < getNames.length; i++) {
var r = getNames[i];
if (r[4].toString() != "") {
if ((ss+(r[4])) in sheetsObj) {
var Q =ss+(r[4]);
sheetsObj[Q].appendRow(r);
}
deleteRows = i + 2;
}
}
sheet1.getRange(2, 1, deleteRows - 1, sheet1.getLastColumn()).clearContent();
}
This code works fine for my above issue
function sheetCreate(){
var activeSpreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var sheet1 = activeSpreadsheet.getSheetByName("Form Responses 1");
var getNames = sheet1.getDataRange().getValues();
getNames.shift();
var sheets = activeSpreadsheet.getSheets();
var sheetsObj = {};
for (var i = 0; i < sheets.length; i++) {
sheetsObj[sheets[i].getSheetName()] = sheets[i];
}
var deleteRows = 0;
for (var i = 0; i < getNames.length; i++) {
var r = getNames[i];
var N=r[2].toString()+r[4].toString();
if (N != "") {
if (N in sheetsObj) {
sheetsObj[N].appendRow(r);
} else {
var newSheet = activeSpreadsheet.insertSheet((N));
var cell1 = newSheet.getRange("A1").setValue("Timestamp");
var cell2 = newSheet.getRange("B1").setValue("Score");
var cell3 = newSheet.getRange("C1").setValue("Employee ID");
var cell4 = newSheet.getRange("D1").setValue("Name of the ATCO");
var cell5 = newSheet.getRange("E1").setValue("The channel on which duty is performed ");
var cell6 = newSheet.getRange("F1").setValue("DATE on which duty is performed");
var cell7 = newSheet.getRange("G1").setValue("Total duration of duty done");
newSheet.appendRow(r);
sheetsObj[N] = newSheet;
}
deleteRows = i + 2;
}
}
sheet1.getRange(2, 1, deleteRows - 1, sheet1.getLastColumn()).clearContent();
}

Google Spreadsheet setBackgroundColors() "Deprecated"

A gs I have been using in the past to check for duplicates, is no longer working. The script would check all cells in the spread sheet if any were identical it would highlight all their occurrences green. I also had another function that would revert all the cells back to white.
setBackgroundColors() has been deprecated; people have been recommended to now use setBackground(). The script still doesn't work...
Here is my gs, make a copy and fiddle with it. Many Thanks...
https://docs.google.com/spreadsheets/d/1UELTxZRZPKQKU9NsQwNefvdxJDM0xDt8904sZy3etoY/edit#gid=0
Here is the script.
/**
* Retrieves all the rows in the active spreadsheet that contain data and logs the
* values for each row.
* For more information on using the Spreadsheet API, see
* https://developers.google.com/apps-script/service_spreadsheet
*/
function readRows() {
var sheet = SpreadsheetApp.getActiveSheet();
var rows = sheet.getDataRange();
var numRows = rows.getNumRows();
var values = rows.getValues();
for (var i = 0; i <= numRows - 1; i++) {
var row = values[i];
Logger.log(row);
}
};
/**
* Adds a custom menu to the active spreadsheet, containing a single menu item
* for invoking the readRows() function specified above.
* The onOpen() function, when defined, is automatically invoked whenever the
* spreadsheet is opened.
* For more information on using the Spreadsheet API, see
* https://developers.google.com/apps-script/service_spreadsheet
*/
function onOpen() {
var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var entries = [{
name : "Check Directory",
functionName : "CheckDirectory"
}];
spreadsheet.addMenu("Script Center Menu", entries);
};
function CheckDirectory() {
var sheet = SpreadsheetApp.getActiveSheet();
var dataRange = sheet.getDataRange();
var data = dataRange.getValues();
var numRows = data.length;
var numColumns = data[0].length;
var formats = [];
var values = [];
for (var i = 0; i < numRows; i++) {
formats[i] = [];
for (var j = 0; j < numColumns; j++) {
formats[i][j] = 'white';
if (data[i][j] != '') {
values.push([data[i][j], i, j]);
}
}
}
var numValues = values.length;
for (var k = 0 ; k < numValues - 1; k++) {
if (formats[values[k][1]][values[k][2]] == 'white') {
for (var l = k + 1; l < numValues; l++) {
if (values[k][0] == values[l][0]) {
formats[values[k][1]][values[k][2]] = 'green';
formats[values[l][1]][values[l][2]] = 'green';
}
}
}
}
dataRange.setBackground(formats);
};
function resetCheckDirectory() {
var sheet = SpreadsheetApp.getActiveSheet();
var dataRange = sheet.getDataRange();
var data = dataRange.getValues();
var numRows = data.length;
var numColumns = data[0].length;
var formats = [];
var values = [];
for (var i = 0; i < numRows; i++) {
formats[i] = [];
for (var j = 0; j < numColumns; j++) {
formats[i][j] = 'white';
if (data[i][j] != '') {
values.push([data[i][j], i, j]);
}
}
}
var numValues = values.length;
for (var k = 0 ; k < numValues - 1; k++) {
if (formats[values[k][1]][values[k][2]] == 'white') {
for (var l = k + 1; l < numValues; l++) {
if (values[k][0] == values[l][0]) {
formats[values[k][1]][values[k][2]] = 'white';
formats[values[l][1]][values[l][2]] = 'white';
}
}
}
}
dataRange.setBackground(formats);
};
Use setBackgrounds(). With an s since it's a method that applies multiple background colors to multiple cells