Google Apps Script - Format value with 4 digits - google-apps-script

I have a variable which needs to be formatted into a 4 digit format,
i.e. 4 would be 0004, or 38 would be 0038
I've tried using getNumberFormat as below but this gives me no luck. Looking around I'm struggling to find a clean solution to this?
var stringVal = 38;
var prettyVal = stringVal.getNumberFormat('0000');
worksheet.getRange(row+1, AUTOINC_COLUMN+1).setValue("GL"+prettyVal);
EDIT - It needs to be formatted before being placed into my spreadsheet - since I'll append the string 'GL' before the value to form the key

To achieve expected result, use below option
var stringVal = 38;
var format = "0000"
var prettyVal = stringVal.toString().length < 4 ? format.slice(stringVal.toString().length) + stringVal.toString() : stringVal ;
console.log(prettyVal)

I'm assuming you are referring to a spreadsheet. Once you have placed the value in a cell or cells you can setNumberFormat.
var range = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet1").getRange("A1");
range.setValue(38);
range.setNumberFormat("000#");

Related

Chekcing cell background of a merged cell

I have a range which I am trying to iterate and store the arrays present in an array until a specific case is encountered.
The data is as follows:
I am trying to iterate from D5:D and store in an object with their A1 notation.
This is what I tried,
var gg = Sheet_1.getRange("D5").getValue();
Concat_rows = {};
const COLUMN = 'D';
const START_LINE = 5;
const Filled_LAST_ROW = Sheet_1.getLastRow();
var LAST_ROW ;
//To get the last row to iterate upto
for (var i = START_LINE; i <= Filled_LAST_ROW; i++){
let cellcolor = Sheet_1.getRange(COLUMN+i).getBackground();
// Trying to check with the cell color to identify upto where to get the values from
if(cellcolor == "#c6d9f0"){
LAST_ROW = i;
break;
} else {continue;}
}
console.log(LAST_ROW);
Once I get that in D5:D I need to just iterate over D5:D26 then I need to pull the values and their A1 notations to store in an objet for further use
I have tried this for the above,
for(let h = START_LINE; h <= LAST_ROW; h++) {
let cellValue = Sheet_1.getRange(COLUMN+h).getValue()
if (cellValue.length >= 1) {
Concat_rows[cellValue] = COLUMN+h;
The problem is that the cell D27 is a merged cell and I am not able to figure out how to deal with it.
Only the top left cell of a merged range holds the value displayed in the user interface, so if you want the value of C27:D27 you could do SpredsheetAppg.getRange('C27:D27').getValue(). If the location of the merged range is static the solution is straight fortwarth, just add a condition and when the loop reach get the value from the merged range instead of the cell, in other words, instead of
let cellValue = Sheet_1.getRange(COLUMN+h).getValue()
use
let cellValue = h === 27
? Sheet_1.getRange('C27:D27').getValue()
: Sheet_1.getRange(COLUMN+h).getValue();
If the location isn't known your script needs to check the location of the merged cells but doing this on a loop it's very likely that will cause that the scripts exceeds the maximum execution time. Unfortunatelly the question doesn't include enough details to provide a specific simple way to handle this. The general advice is to use batch operations and in order of get the best possible performance use the Advanced Sheets Service instead of the Spreadsheet Service.

google sheets macro how to define a range [duplicate]

I have this statement:
var destinationRange = destinationSheet.getRange("D26:E39");
and want to replace it with
var destinationRange = destinationSheet.getRange(daGrowaRange);
The reason I want to use daGrowaRange is not just cause da name, but that the range is not always the same.
D is a fixed constant value and never changes
E is a fixed constant
value and never changes
BUT
26 is dynamic and changes and
39 is an offset based on the 26 (in
this case 13 so 39 = 26+13, but the 13 is a variable value also).
I am sure that I could put this together in some ugly ass way, but I am sick of looking at my crappy code and want to learn how you crackz out there make it nice.
Thank you
You can use Template literals to accomplish this task:
const dValue = 26;
const eValue = dValue + 13;
const daGrowaRange = `D${dValue}:E${eValue}`;
const destinationRange = destinationSheet.getRange(daGrowaRange);

Is there a way to merge multiple range into a single range for sheets appscript?

I was trying to merge 2 ranges(WITH values) into 1 range(empty)
I was trying to do it like this
function regressionMaker(){
var app = SpreadsheetApp;
var activeSheet = app.getActiveSpreadsheet().getActiveSheet();
var name = activeSheet.getRange ("E2:E").getValues();
var title = activeSheet.getRange ("F2:F").getValues();
var x = " - ";
activeSheet.getRange("T2:T").setValues(name + x + title);
}
All I get is an error saying "Cannot find method setValues(string)"
I was expecting of having a result of
Column 1 Column 2 Column3
Apple Banana Apple - Banana
Updates
var name = activeSheet.getRange ("E2:E").getValues();
var title = activeSheet.getRange ("F2:F").getValues();
var merged = name.map(
function(nameValues,rowIndex){
var titleValues = title[rowIndex];
return [nameValues[0] + ' - ' + titleValues[0]];
}
);
activeSheet.getRange("V2:V").setValues(merged);
Tho nothing happened :(
Problem 1.1
You are trying to pass a String to the setValues() method which can only be passed a two-dimensional Array (that is, Array of Arrays). Error message states just that: "there is no method setValues() such that it accepts String as an argument".
Problem 1.2
getValues() method yields an Array of Arrays as well, so your names and title variables actually contain [['Apple']] and [['Banana']] respectively (assuming your ranges include values only).
Problem 1.3
JavaScript is dynamically typed, so it performs type coercion for you and it often leads to issues like you have. In the case of +, if any argument is of type String, JS will try to coerce the other one to a String (e.g. '11' + 2 = '112').
Solution
The abovementioned problems should lead you to an algorithm: "map each row of data in column 1 to a column 2 such that the result is a string concatenation of both values separated by a hyphen with two whitespaces".
Application
Since you do a one-column merge, all you need is to get the first value from column 1, the first value from column 2, concatenate them and wrap into an Array representing new cell.
var merged = names.map(function(nameValues,rowIndex){
var titleValues = titles[rowIndex];
return [nameValues[0] + ' - ' + titleValues[0]];
});

How to work with financial number formatted number in Google Apps Script?

I am reading numbers in financial #s format from cells. 5,000 is financialNumberOne and 3,000 is financialNumberTwo;
var financialNumberOne = ss.getRange("A1").getDisplayValue();
var financialNumberTwo = ss.getRange("A2").getDisplayValue();
How can I convert this into number so that I can do some math with it?
var result = financialNumberOne + financialNumberTwo;
Following did not work.
var result = +financialNumberOne + +financialNumberTwo;
Number(financialNumberOne); //It is reading NaN
parseInt(financialNumberOne); //It is reading 5,000 as 5
You should use getValue() instead of getDisplayValue() because getDisplayValue() will just get a string like "5,000.00". So the correct code for getting the numbers would be something like this.
var financialNumberOne = ss.getRange("A1").getValue();
var financialNumberTwo = ss.getRange("A2").getValue();

Writing a string of multiple date / time to a single cell

I have an array of a couple (the array is up to 10) date/time that I want to write to a spreadsheet using getRange().setValues(). I'm converting the array to a string and it looks correct in Logger.
[Mon Feb 02 14:01:00 GMT-06:00 2015, Tue Feb 02 01:00:00 GMT-06:00 2016, , , , , , , , ]
When I try to write the string to a single cell in a sheet:
target6.setValues(source_range6_values);
I get this error:
Incorrect range width, was 10 but should be 1 (line 84, file "Code")
Edited 4/28/2014 adding entire script:
/**
* Copies source range and pastes at first empty row on target sheet
*/
function CopyIt(){
//Establishing source and target sheets
var source_spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var target_spreadsheet = SpreadsheetApp.openById("0AhCv9Xu_eRnSdHpLTkc0d1ZURUtyTU9oRjdFbmpMUFE");
// Get source and target sheets - can be the same or different
var sourcesheet = source_spreadsheet.getSheetByName("Form Responses");
var targetsheet = target_spreadsheet.getSheetByName("Work_Orders");
//Get row of last form submission
var source_last_row = sourcesheet.getLastRow();
// Check for answer to Do you need a Flyer Created? If No, end now. If Yes, continue.
var check = sourcesheet.getRange("T"+(source_last_row)).getValue();
if (check == 'Yes') {
//Pulling date(s) from the users form entry (source sheet) into an array
var daterange = sourcesheet.getRange("H"+source_last_row+":Q"+source_last_row);
//Getting the values of the array
var classDate = daterange.getValues();
//changing the array values to a string
classDate.toString();
//Building a new variable with the string to be inserted below in the target sheet
var source_range6_values = classDate;
//source_range6_values.toString();
Logger.log(classDate[0]);
// Get the last row on the target sheet
var last_row = targetsheet.getLastRow();
//Setting the target cell in the Marketing Work Order sheet
var target6 = targetsheet.getRange("U"+(last_row+1));
// Aadding a new row in the target sheet
targetsheet.insertRowAfter(last_row);
//Inserting the values of source_range6_values into the target sheet. Unfortunately it does not enter the data into the same field and it's in military time.
target6.setValue(source_range6_values);
Logger.log(source_range6_values);
}
}
To give a correct answer for your question, i guess i need to know how you get the value of source_range6_values.
One quick guess is you might want to use target6.setValue instead of target6.setValues since you want to write the data into one cell only...
A quick & dirty way would be to replace the commas(with spaces):
source = String(source_range6_values).replace("," , " ");
I've had fun with GAS and variables. Casting it as a String should let you use the string functions on it. If that doesn't work can you share a mock-up of your sheets so I can take a look?
edit:
I had to play around with it a bit, seems google's version of .replace() only replaces the first instance (and doesn't allow .replaceAll() ).
I edited your code starting on line 23:
//Getting the values of the array
var classDate = daterange.getValues().toString();
//Building a new variable with the string to be inserted below in the target sheet
//Google has bugs, .replace() seems to only replace the first instance
//-while {} loop replaces all of them
while (!classDate.equals(classDate.replace("," , " "))) { classDate = classDate.replace("," , " "); };
var source_range6_values = classDate;
All the dates are in one cell if you change only those lines (and no errors).
I appreciate the help you two have given me trying to answer this question. #swimmingwood fixed the actual capture of the data into a string, but it left commas and when I inserted it into the target sheet, it wrote it to multiple cells with an error. It did write to the sheet but the error had you use a CTRL-E (inside the taget sheet) to complete the insert and wrote them into separate cells.
#MickATX suggested the code to replace the commas in the string with a space, which would be fine, but apparently he discovered a Google scripting problem that would only allow for the first comma to be replaced and ignore the rest. Great knowledge never-the-less.
I ended up using a formula in an addition cell in the source sheet that looked like this:
=ArrayFormula(CONCATENATE(REPT(TEXT(H2:Q2,"mm/dd/yyyy hh:mm a")&CHAR(10),H2:Q2>0)))
This formula wrote all the date/time entries provided by the form entry into one cell of the source sheet and ONLY the number of entries (1-10). I then wrote that single cell to the target sheet via the script.
Thanks to #swimmingwood and #MickATX for trying to help me, both provided worthy knowledge.
I've read a couple of strange answers here...
If you write an 2D array to a sheet it will obviously be written accross multiple cells... commas are definitely not the issue but the nature of the object is.
Simply convert your array into a string using .toString() or .join() (the latter providing the advantage you can choose the separator to use) and setValue() (without S) at the place you want.
the commas you see in the logger are only typographic representation of array elements separators...
And, last point : the .join() or .toString() methods return new variables, they don't modify the original value so when you write classDate.toString(); you are not doing anything ...
you should write it like this :
classDateAsAString = classDate.toString();
finally your code :
function CopyIt(){
//Establishing source and target sheets
var source_spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
var target_spreadsheet = SpreadsheetApp.openById("0AhCv9Xu_eRnSdHpLTkc0d1ZURUtyTU9oRjdFbmpMUFE");
// Get source and target sheets - can be the same or different
var sourcesheet = source_spreadsheet.getSheetByName("Form Responses");
var targetsheet = target_spreadsheet.getSheetByName("Work_Orders");
//Get row of last form submission
var source_last_row = sourcesheet.getLastRow();
// Check for answer to Do you need a Flyer Created? If No, end now. If Yes, continue.
var check = sourcesheet.getRange("T"+(source_last_row)).getValue();
if (check == 'Yes') {
//Pulling date(s) from the users form entry (source sheet) into an array
var daterange = sourcesheet.getRange("H"+source_last_row+":Q"+source_last_row);
//Getting the values of the array
var classDate = daterange.getValues();
var source_range6_values = classDate.join(' & ');// using & as separator for example
// Get the last row on the target sheet
var last_row = targetsheet.getLastRow();
//Setting the target cell in the Marketing Work Order sheet
var target6 = targetsheet.getRange("U"+(last_row+1));
// Adding a new row in the target sheet
targetsheet.insertRowAfter(last_row);
//Inserting the values of source_range6_values into the target sheet. Unfortunately it does not enter the data into the same field and it's in military time.
target6.setValue(source_range6_values);
Logger.log(source_range6_values);
}
}
Now if you want to format the dates in a more civilized way, that should be handled a bit differently... let me know if you still need it / want it.