Convert text format to a value format - google-sheets

I am looking to create a script that will automatically convert a phone number that is cut & pasted into Google Sheets. The phone number is in a text format and I need to change it into a value. Currently, I have to have an additional column(s) for each pasted phone number that converts it. I would like to eliminate having these extra columns.
The formula I am using to do the converting are:
Column C:
=IF(ISBLANK(A3)," ",(VALUE(REGEXREPLACE(A3, "[-]", ""))))
Column D:
=IF(ISBLANK(B3)," ",(VALUE(REGEXREPLACE(B3, "[-]", ""))))
I'm very new to scripts and just starting to learn about it. Any help would be much appreciated. Thank you.
Shared Link

I think what you are looking for is the onEdit-trigger. There is quite a good video on youtube explaining the basics, as well as the general documentation for the onEdit trigger.
I'm no Google AppScript expert, so all I can give you is a sample script that work for Cell A3. I leave it up to you to complete the code and build something that will work with all your cells. ;) The code should be self explaining - especially after watching the linked video above. Most of the code is basic Javascript, so it should be simple to understand.
// source code example for cell A3
function onEdit(e) {
var range = e.range;
var spreadSheet = e.source;
var sheetName = spreadSheet.getActiveSheet().getName();
var column = range.getColumn();
var row = range.getRow();
var inputValue = e.value;
// column 1 is "A", so column 1, row 3 is Cell "A3"
if (sheetName == "Sheet1" && column == 1 && row == 3) {
var number = inputValue.replace(/[-]/, '');
SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet1").getRange("A3").setValue([number]);
}
}

Related

Google Sheets: Tranfer(convert) a text of a formula from one cell to a proper formula in another cell - IDIRECT does not work

The question was raised several times with no result - INDIRECT does not work in this case.
In Excel EVALUATE function may help, but only using VBA, what also not very usefull.
Range A3:A6 contains conditions, Range B3:B6 - corresponding formulas's texts, E1 contains Condition Selector (Data Validation List in this case).
The formula in D9:D12: =indirect("B"&MATCH($E$1,A:A,1))
The question is - how to transfer(convert) the text from B3:B6 to D9:D12, to make them proper formulas?
Please, see a screenshot under this link:
converting text string into valid formula is possible only with script:
function onEdit() {
var sheet = SpreadsheetApp.getActive().getSheetByName("Contants"); // sheet name
var src = sheet.getRange("C2"); // The cell which holds the formula
var str = src.getValue();
var cell = sheet.getRange("C10"); // The cell where I want the results to be
cell.setFormula(str);
}
also keep in mind that your string needs to look exactly as formula with = sign in front. see: https://stackoverflow.com/a/60981768/5632629
Player0 - have my sincere thanks - it is really very simple, light and working solution. It works much better, than it made in Excel with it's Evaluate() function.
My final code for my particular example was the following:
function onEdit() {
var sheet = SpreadsheetApp.getActive().getSheetByName("Sample"); //
sheet name
var rowNoCell = sheet.getRange("F1");
var rowNo = rowNoCell.getValue();
var src = sheet.getRange("B"+rowNo); // The cell which holds the formula
var str = src.getValue();
var cell = sheet.getRange("D9:D12"); // The cell where I want the r
esults to be
cell.setFormula(str);
}
It takes corresponded to Condition, selected in F1, cell in the range B3:B6 and post the formula to the range D9:D12.
F1 contains =MATCH($E$1,A:A,1) to link the condition in F1 with values in A3:A6
The only thing that the formula in B3:B6 range has to be a string, without "=" in front.
Thanks a lot once again - the problem solved!
Screenshot

Google Sheets Script to Conditionally Format Cells in Rounds Using Random Number Generator

I am attempting to create a virus-simulation in Google Sheets for a high school unit on exponential functions. I would like to set R0 and then simulate spread each day by running a script that:
-- reads a range of rows and columns (each cell simulates a person)
-- leaves the cell alone if it has already been infected (i.e., changed color)
-- randomly changes the color of the appropriate number of cells using a random number generator and the equation R0^N, where N is the number of days
This is my first script in Google Sheets, and it is frustrating. I am feeling the novice frustration. Below is my current iteration. Does anyone have suggestions
function ViralSpread() {
var sheet = SpreadsheetApp.getActive().getSheetByName("ModelingTransmission");
var range = SpreadsheetApp.getActive().getRangeByName("People");
var values = range.getValues();
i = 1;
values.forEach(function(row) {
j=1;
row.forEach(function(col) {
j++;
var testrange = SpreadsheetApp.getActiveSheet().getRange(i,j);
var testvalue = testrange.getValues();
var newdata = [j];
testvalue.setvalues(newdata);
});
i++;
});
}

How can I highlight (mark) the active row in google sheets?

The conditional formatting does not help with that. I tried many scripts that are published online but non of them works.
Same issue is here: https://support.google.com/docs/thread/4469470?hl=en
Answer:
Unfortunately, this is not possible to do.
More Information:
The main reaason that thids can't be done is that the Sheets API nor Google Apps Script have listeners for when the active cell on a sheet changes. There are also no clicker or button press listeners, if the clicks or button presses do not make an edit or change to the Sheet.
Testing & Reasoning:
I had a mess around with Apps Script to see if I could create some sort of workaround, though this ended up with encountering other obstacles.
There is a way of making the background of the active row change colour, which can be easily done in Apps Script with something like:
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var currRow = ss.getActiveCell().getRow();
sheet.getRange(currRow + ":" + currRow).setBackground("#F4C2C2");
Knowing this, and knowing that I couldn't call a trigger from just a click, I created a Sheets add-on instead with with a JavaScript function embedded in the of the HTML document which calls the Apps Script method at a specific time-interval:
<script>
function poll() {
setInterval(update, 500);
}
function update() {
google.script.run.rowHighlighter();
}
</script>
with the following rowHighlighter() function inside the code.gs file:
function rowHighlighter() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var currRow = ss.getActiveCell().getRow();
var l = PropertiesService.getUserProperties().getProperty("currRow");
if (l) {
sheet.getRange(l + ":" + l).setBackground("#FFFFFF");
}
sheet.getRange(currRow + ":" + currRow).setBackground("#F4C2C2");
PropertiesService.getUserProperties().setProperties({"currRow": currRow});
}
I thought it might be possible to call this function from within the sidebar of the Sheets add-on and use the PropertiesService class of Apps Script to store the currently selected row so that when clicked elsewhere the colour could be reset.
While this appeared to have positive results, this only lasted a few seconds - unfortunately after this the Apps Script quotas get hit and the errors in the console as seen from the Apps Script editor end show that some throttling is needed so not so many Apps Script requests are made. Of course, while this is something that you could do, increasing the interval at which the update() function is called in the add-on <body> reduced the real-timeness of the application and the whole functionality breaks.
In short; this can't be done. Both Apps Script and the Sheets API lack the functionality, and trying to build something that emulates it yourself will end in you using all your quota as the account limitations are hit.
References:
Google Apps Script - Extending Google Sheets
G Suite Developer - Extending Google Sheets with Add-ons
Google Apps Script - Properties Service
Docs editors herlp - Highlight (or mark) the row the current cell is on
function onSelectionChange(e){
const range = e.range;
const sheet = range.getSheet();
const currRow = range.getRow()
const maxRows = sheet.getMaxRows();
const maxColumns = sheet.getMaxColumns();
sheet.getRange(1, 1, maxRows, maxColumns).setFontWeight("normal");
sheet.getRange(currRow, 1, 1, maxColumns).setFontWeight("bold");
}
Regarding Devendra Pathak's solution, how do we tell the script to not act on selections where it is the selected range is lower than row 5? For example, click on A6, the script executes. Click on A1, no changes, A6 remains highlighted. Click on D7, the script executes. Row 6 formatting becomes normal, and row 7 gets the special formatting. As well, how does the script know to only format up to column 7?
Variation below.
https://docs.google.com/spreadsheets/d/1R4GPipk9FyucRcKeXcosbKmXxUTGmuaoQDaUoVDVorU/edit#gid=0
//Seeking: Act only when range is row 6 or higher
Highlight row and column of cell where the mouse is clicked:
function onSelectionChange(e) {
const range = e.range;
const sheet = range.getSheet();
const maxRows = sheet.getMaxRows();
const maxColumns = sheet.getMaxColumns();
sheet.clearConditionalFormatRules();
var formula = '=A1<>"1239"';
//---------------------------------------------------------------
//RULE1
var range1 = sheet.getRange(range.getRow(), 1, 1, maxColumns);
var rule1 = SpreadsheetApp.newConditionalFormatRule()
.whenFormulaSatisfied(formula)
.setBackground('lightgray')
.setBold(true)
.setRanges([range1])
.build();
var rules1 = sheet.getConditionalFormatRules();
rules1.push(rule1);
sheet.setConditionalFormatRules(rules1);
//---------------------------------------------------------------
//RULE2
var range2 = sheet.getRange(1, range.getColumn(), maxRows, 1);
var rule2 = SpreadsheetApp.newConditionalFormatRule()
.whenFormulaSatisfied(formula)
.setBackground('lightgray')
//.setBold(true)
.setRanges([range2])
.build();
var rules2 = sheet.getConditionalFormatRules();
rules2.push(rule2);
sheet.setConditionalFormatRules(rules2);
}

Google Spreadsheet move row to new sheet based on cell value

I am new at this so still trying to figure how everything works.
I have a sheet that collects responses from a Google Form. Based on the answer to one of those questions I would like the row from that sheet to move to a different sheet document all together (not a sheet in the same document).
I have it set on a time based trigger every minute so as new responses come in it would kick them over to the correct document and then delete the row from the original spreadsheet.
I have been able to get part of the way there. I would like for it to take the row, columns A through E, move those to the correct document, find where the next open row is and place the data in columns A through E on the new document.
Where my issue is coming in at the moment is when the row is moved to the new document. I have formulas saved in columns G - Z on the destination page. It is finding the last row with a formula and placing the row after that (which is at the very bottom of the page). I am pretty sure this has to do with using an array? But I may be wrong. Is there a way to just have that look at the destination page column A-E, find the next blank row, and copy A-E from the original file to the new page?
arr = [],
values = sheetOrg.getDataRange().getValues(),
i = values.length;
while (--i) {
if (value1ToWatch.indexOf(values[i][1]) > -1) {
arr.unshift(values[i])
sheetOrg.deleteRow(i + 1)
sheet1in.getRange(sheet1in.getLastRow()+1, 1, arr.length, arr[0].length).setValues(arr);
};
I have multiple If statements each with some changes to the "valueToWatch" and the "Sheet1in" for different values and destination pages. If that information helps at all.
You can find the last cell in a column with data in it like this:
function findLastValueInColumn() {
var column = "A"; // change to whatever column you want to check
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheets()[0];
var lastDataRow = sheet.getDataRange().getLastRow();
for (var currentRow = lastDataRow; currentRow > 0; currentRow--) {
var cellName = column + currentRow;
var cellval = sheet.getRange( cellName ).getValue();
if (cellval != "") {
Logger.log("Last value in Column " + column + " is in cell " + currentRow);
break;
}
}
}
You can then use this function to figure out where to start your new data.

Google spreadsheet script for insert new row based on value of cell

Spreadsheet data looks like this
function myFunction()
{
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sh = ss.getSheetByName('Active Listeners');
sh.insertRowBefore(15551)
}
As i have large range of rows that could be work on. If the value of the range matches with "Apr 9" then insert row before to that. Could anyone help me to get that.
A 'for loop' to cycle through your rows from the bottom would almost do the trick. The loop inserts a row after each row specified by i. Keep in mind you'll need a different solution if your Apr 9 column is formatted as a date. This works for plain text only. You can select the column and change to plain text with "Format > Number > Plain Text" on the menu.
function myFunction() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sh = ss.getSheetByName('Active Listeners');
//var shlen = sh.getDataRange().getLastRow(); //returns integer last row
var shlen = Browser.inputBox("Enter Last Row of Preferred Range", Browser.Buttons.OK_CANCEL);
var ecell = sh.getActiveCell().getA1Notation();
You may need a different dataRange (below), I've just grabbed the parameters of data in your whole sheet (above), then grabbed a range specified in A1 notation of "A1:B[number reference of bottom row]" The modification may be that you need "B1:C" + [shlen] or whichever other range.
if (shlen >= 1) {
var dataRange = sh.getRange("A1:A" + shlen).getValues();
for (var i = shlen; i > 0; i--) {
var row = dataRange[i-1];
if (row[0] == "Apr 9") {
sh.insertRowAfter(i-1)
}
}}
}
Someone more knowledgeable than me can pitch in if they have a better answer, but my only solution (which should be ok if it's a one-of) would be to just repeat the script a few times, starting at the row of your choice each time. Select cell A1 and then press "control (or command) + down arrow". It will take you to the first gap, which should be where the previous script ended. Remember the row number you're up to and plug that in the input box when you run the script again. Might take a few iterations but you'll get there.
If this process is going to be done repeatedly then best of luck in finding a solution :)

Resources