In my Google Apps Script I an appending a row to my spreadsheet. In this row being appended, I am trying to insert a string of value '0102', however when inserted it converts to the number 102. Is there any way to insert a value into sheets with Google Apps Script that will not format these types of numbers into integers but leave them as strings?
You need to format the cell as plain text before setting its value. From this answer, the (seemingly undocumented) trick is setNumberFormat('#STRING#'). For example,
sheet.getRange("A1").setNumberFormat('#STRING#').setValue('0102');
formats cell A1 as plain text, and sets the value '0102', which will remain a string.
Unfortunately, appendRow, being an atomic operation of adding a row and inserting values, does not leave room for formatting. So you'll need something more verbose, for example
sheet.insertRowAfter(sheet.getLastRow());
var range = sheet.getRange(sheet.getLastRow() + 1, 1, 1, 3);
range.setNumberFormats([['', '', '#STRING#']]).setValues([['Boston', 'MA', '02201']]);
This code adds a row and fills the first three cells in it with Boston MA 02201, keeping the ZIP code 02201 as a string.
Thought I would add in my own solution that I had with this same issue.
The fix that I found is that if you add a ' character in front the value that you're trying to insert it will force it to remain as a string.
sheet.appendRow(["Boston", "MA", "'02201"])
Related
I am attempting to create documentation from an export of data that gives me a jumbled mess all in one cell that I need to clean up and extract certain bits from.
Here is an example:
[{"label":"Native Invoice","value":"native_invoice","displayOrder":0,"hidden":false,"readOnly":false},{"label":"Data Sync","value":"data_sync","displayOrder":1,"hidden":false,"readOnly":false}]
All of this is in one cell, and I need to have only the following information in their own individual rows:
Native Invoice
Data Sync
This example only has 2 values, but some that I am working on have hundreds, and it is taking far too long to manually copy and paste the values I need into their own cells.
Note: I am working in Google Sheets exclusively.
If I'm understanding you correctly, you want to pull anything after "label": without quotes. If that's the case, and if you are open to a formula instead of a script, supposing that your raw-data block were in A1, place this in B1:
=ArrayFormula(IFERROR(QUERY(FLATTEN(REGEXREPLACE(IF(NOT(REGEXMATCH(SPLIT(REGEXREPLACE(A1,"label.:.([^"&CHAR(34)&"]+)","~|$1~"),"~"),"\|")),,SPLIT(REGEXREPLACE(A1,"label.:.([^"&CHAR(34)&"]+)","~|$1~"),"~")),"\|","")),"WHERE Col1 Is Not Null")))
Here is how a custom function can look like:
function parse(txt) {
var jsn = JSON.parse(txt);
return [jsn[0].label, jsn[1].label];
}
Here is how it works:
You put the data into cell A1, put the formula =parse(A1) into the cell B1, and get the results in cells B1 and B2.
Update
If you want to get labels from all objects of the data, here is another variant of the function:
function get_labels(txt) {
return JSON.parse(txt).map(x => x.label); // get 'label' from all the objects
}
It works about the same way:
I'm looking to set a column to format 000, which will display the zeros at begenning.
So, if a cell displays "3", I want that the script will set it to display "003".
This column is located in BDD tab, 13th column starting from the second row.
function FormattingGpeTrait() {
const sheet = SpreadsheetApp.getActiveSheet().getSheetByName("BDD").getRange(2,13)
sheet.setNumberFormat('000')
Modification points:
The method of "getSheetByName" is for Class Spreadsheet. In your showing script, you try to use it to Class Sheet. By this, an error occurs. This has already been mentioned in the comment. Ref
From 13th column starting from the second row., I thought that you might have wanted to set the number format of 000 to "M2:M". In your showing script, the number format is set to only a cell "M2".
If you want to set the number format to the cells "M2:M" of the sheet name of "BDD", how about the following modification?
Modified script:
function FormattingGpeTrait() {
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("BDD");
sheet.getRange("M2:M" + sheet.getLastRow()).setNumberFormat('000');
}
When you run this script, the number format of "000" is set to the cells "M2:M" of "BDD" sheet.
If you want to set the number format to the "M2:M", please modify getRange("M2:M" + sheet.getLastRow()) to getRange("M2:M").
References:
getActiveSpreadsheet()
getSheetByName(name)
The easiest way to get a range on a named sheet is to include the sheet name in the range reference, like this:
function formattingGpeTrait() {
SpreadsheetApp.getActive().getRange('BDD!M3:M').setNumberFormat('000');
}
I think that you can't use the standard number formats as they all will only evaluate your value to a real number value where '003' in reality is equal to '3' from a numeric sense.
You have two real options which is to either store the value in a Text column as "003" or prepend the value with an apostrophe "'003" which is basically the same as storing it as Text but the column can remain numeric.
You can create a custom number format for a cell/column to also do this but I am not certain how to accomplish this programatically. Basically, this is still going to end up like the Text variations I mention above, only you have a named format you can call. The data will still be stored as Text.
I have a document consisting of five different worksheets. These sheets contain tables of five columns and in excess of 400 rows each. I am trying to replace specific text strings found in these tables with other text strings. To this end, I've created another sheet with another table ($replacement-table), containing the strings I want to replace in one column and the strings I want to replace them with in another column. The number of strings to be replaced in excess of 500, and I'm not certain that they all crop up somewhere in the other sheets.
While I could do it manually, I'd rather come up with a way to automate it. Therefore, I'm looking for a script that looks up whether the value in A2 of $replacement-table shows up anywhere else in the document, and if so, replaces it with the value found in B2 of $replacement-table. The same goes for A3 and B3, A4 and B4, and so on and so forth.
Sadly, I don't even have a starting point, as I'm not experienced in either the syntax or the functions required to tell Google Sheets what I want it to do. Any ideas (or even obvious/plug-and-play solutions?) on how to achieve my goal of replacing a wide selection of strings found in five different tables with the corresponding strings arranged in a certain table?
Here's a simple example that might help.
function replMyText(){
var ss=SpreadsheetApp.getActive();
var sh=ss.getSheetByName('replacements');
var rgtxt=sh.getRange('A1:A7');//text to replace
var rgrep=sh.getRange('D1:E5');//replacement table
var txtA=rgtxt.getValues();
var repA=rgrep.getValues();
for(var i=0;i<txtA.length;i++){
for(var j=0;j<repA.length;j++){
if(txtA[i][0]==repA[j][0]){
txtA[i][0]=repA[j][1];
}
}
}
rgtxt.setValues(txtA);
}
Here's an image of my test sheet:
I need to put a formula into a cell in each new row added to a Google Sheets. I have this working in VBA but not been able to build it correctly in Script.
I loop through i rows until lastrow. In cell J, I want this formula inserted:
var Discount = '=IF(ISBLANK("F"+i,,IF(ISNUMBER(FIND("CM","B"+i)),IF("C"+i>"F"+i,150,0),0))';
I use this method to add the row:
var dtaCollect = ["","",StartDate,CustomerName,Monthly,"",Discount,LateFee,TotalPaid,Commission,Note,Referral];
target_sheet.appendRow(dtaCollect);
i++;
} else {
i++;
}
}
However, the formula is written exactly as above, without i substituted with the iteration value. As a result I get #ERROR! in the cell. I've tried INDIRECT and concat.
How can I fix this?
The value i isn't being substituted in your string because it's just text. You need to break it out of the string, and be more careful with your use of quotes to ensure you end up with a viable formula. This would work:
var Discount = '=IF(ISBLANK(F'+i+',,IF(ISNUMBER(FIND("CM",B'+i+')),IF(C'+i+'>F'+i+',150,0),0))';
Since you're using A1Notation, a simple JavaScript String.replace() should be all you need to provide a more readable solution:
var Discount = '=IF(ISBLANK(F%row%,,IF(ISNUMBER(FIND("CM",B%row%)),IF(C%row%>F%row%,150,0),0))'
.replace(/%row%/g, i.toString());
Explanation:
replace() will find regexp or substring matches, and replace them with a new substring.
in this case, we're looking for a regexp; the g flag means we'll look for all occurrences of "%row%" and replace them with the value of i.
We've used the % as bookends, to make the replaceable text stand out clearly - just a convention, not a requirement.
Note: You didn't show how you used INDIRECT, only mentioned that you tried it. It is an alternative here, and might be preferred as you could simply copy a formula from an existing cell without worrying about adjusting the references.
I am trying to come up with a script that will simply capture the value of a cell and paste that value in another cell. The cell value it is capturing is a simple, unformatted cell containing the number 32. My code below works but the result is not 32 in the target cell. Instead, the result is [[32.0]]. Can someone help me understand what it is adding the brackets and the .0?
function test(row) {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();// Define active sheet
var amountdue = sheet.getRange("A30").getValues();// Capture amount due
sheet.getRange("B30").setValue(amountdue);// Paste amount due
}
The function that you are using "getValues()" is intended to capture more than one cell. As this function is designed to capture a table it give in output a result that is not the value of one cell but the value of several cells. to display them we need to store them in something that it's easily accessible and structured : an array.
The array is represented as: [cell1Value, cell2Value, cell3Value, ...] .
As there may have more than one row we store each row in an other array: [row1, row2, row3, ...]. so in the end it's something like that:
[ [row1Cell1, row1Cell2, ...], [row2Cell1, row2Cell2, ...] ]
You don't want these brackets, change "getValues()" for "getValue()" without "s".
Or when you set the value use:
amoutdue[0][0]
the first [0] is to say I want the first row (we start at 0) and the second [0]... you already guessed is for the first cell.
I suppose that you are getting the ".0" after "32" because as you are trying to set the array of array in a cell. Javascript don't know how to handle that and try to transform the array of array in full text.