Reputation: 4226
I am trying to extract a text string from a formula in Google Spreadsheets. Specifically, I have a column with HYPERLINK
formulas from which I'd like to use a custom function to create another column with the extracted text of the formula, so that calling the function on a cell with =HYPERLINK("https://twitter.com/jrosenberg6432/status/617013951184957440")
would return https://twitter.com/jrosenberg6432/status/617013951184957440
in another cell.
I found this very helpful function from this help forum:
/** Extract a text string in double quotes from the formulas in selected cells
*/
function replaceFormulasWithFirstQuotedTextStringInFormula() {
// Goes through all the cells in the active range (i.e., selected cells),
// checks if a cell contains a formula, and if so, extracts the first
// text string in double quotes in the formula and stores it in the cell.
// The formula in the cell is replaced with the text string.
// see https://productforums.google.com/d/topic/docs/ymxKs_QVEbs/discussion
// These regular expressions match the __"__ prefix and the
// __"__ suffix. The search is case-insensitive ("i").
// The backslash has to be doubled so it reaches RegExp correctly.
// https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/RegExp
var prefix = '\\"';
var suffix = '\\"';
var prefixToSearchFor = new RegExp(prefix, "i");
var suffixToSearchFor = new RegExp(suffix, "i");
var prefixLength = 1; // counting just the double quote character (")
var ss = SpreadsheetApp.getActiveSpreadsheet();
var activeRange = ss.getActiveRange();
var cell, cellValue, cellFormula, prefixFoundAt, suffixFoundAt, extractedTextString;
// iterate through all cells in the active range
for (var cellRow = 1; cellRow <= activeRange.getHeight(); cellRow++) {
for (var cellColumn = 1; cellColumn <= activeRange.getWidth(); cellColumn++) {
cell = activeRange.getCell(cellRow, cellColumn);
cellFormula = cell.getFormula();
// only proceed if the cell contains a formula
// if the leftmost character is "=", it contains a formula
// otherwise, the cell contains a constant and is ignored
// does not work correctly with cells that start with '=
if (cellFormula[0] == "=") {
// find the prefix
prefixFoundAt = cellFormula.search(prefixToSearchFor);
if (prefixFoundAt >= 0) { // yes, this cell contains the prefix
// remove everything up to and including the prefix
extractedTextString = cellFormula.slice(prefixFoundAt + prefixLength);
// find the suffix
suffixFoundAt = extractedTextString.search(suffixToSearchFor);
if (suffixFoundAt >= 0) { // yes, this cell contains the suffix
// remove all text from and including the suffix
extractedTextString = extractedTextString.slice(0, suffixFoundAt).trim();
// store the plain hyperlink string in the cell, replacing the formula
cell.setValue(extractedTextString);
}
}
}
}
}
}
/** Add a custom menu to the active spreadsheet, containing a single menu item
* for invoking the replaceFormulasWithFirstQuotedTextStringInFormula() function.
* The onOpen() function is automatically run when the spreadsheet is opened.
*/
function onOpen() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var entries = [{
name : "Replace formulas with text strings",
functionName : "replaceFormulasWithFirstQuotedTextStringInFormula"
}];
ss.addMenu("Extract", entries);
}
But, this function replaces the original cells with the extracted text, rather than retaining what is in the original cells and returning the output in another column.
I tried to edit the code but am a Javascript novice so thought to ask despite this possibly being a minor edit to it.
Upvotes: 0
Views: 2011
Reputation: 190
That post on the help forum is old. Here is a working solution. Tested it myself. Hope it helps. Feel free to message me for questions (I don't have enough reputation to comment yet lol).
function myFunction() {
var formulas = SpreadsheetApp.getActiveRange().getFormulas();
var toPut = SpreadsheetApp.getActiveRange().offset(0, 1, SpreadsheetApp.getActiveRange().getNumRows(), 1);
var extracted = [];
for(var index in formulas){
var array = formulas[index];
for(var formulaIndex in array){
Logger.log("f:" + array[formulaIndex]);
extracted.push([array[formulaIndex].substring(array[formulaIndex].indexOf('"')+1, array[formulaIndex].lastIndexOf('"'))]);
}
}
toPut.setValues(extracted);
}
function onOpen(e){
SpreadsheetApp.getUi().createMenu("Testing").addItem("myFunc", 'myFunction').addToUi();
}
Upvotes: 1
Reputation: 1018
You can try this:
cell = activeRange.getCell(cellRow, cellColumn);
var output_cell = activeRange.getCell(cellRow, (cellColumn + 1));
//Or put in the column number in which u want the output to be put
cellFormula = cell.getFormula();
.
.
.
//(Keep the rest of the code as it is)
Then, instead of writing cell.setValue(extractedTextString);
in your function,
do this:
output_cell.setValue(extractedTextString);
So, what I am trying to do here is to put the new values in the column next to your original column.
Hope it works :)
Upvotes: 1