How to output a text file in google apps script - javascript

I am using Google scripts to try and output 2 .txt files by reading in the information from Sheet 1.
I want my files to look like below one for just titles and the other for footnotes:
Therefore the ‘|’ character in the footnote column needs to split onto a new line with the same program name listed as above.
The attached sheet is a basic example, but I need guidance which would also work if the footnote column had multiple ‘|’ characters.
Any help is appreciated.

Solution
Use the split() JS String method to obtain your strings in a single array.
When obtaining the values from a Spreadsheet the Apps Script methods will arrange them in multidimensional Arrays using this fashon: sheet[rows][columns].
In this example I will use the 3rd column, but you can of course adapt this method to whatever column serves you best:
function splitter() {
var ss = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var thirdColumnValues = ss.getDataRange().getValues().flatMap(row => row[2].split('|'));
var text = thirdColumnValues.join("\n"); //Just concatenate the values with the "return" symbol
}
Reference
getValues()
JS String

Related

How do you extract urls from a column of cells containing linked text with numeric values in Google Sheets?

Edit/Update: This question is helpful for the specific use case where you are trying to extract urls from cells containing numeric values with linked URLs.
I have a spreadsheet with a column of cells copied from a website containing text with linked urls (i.e. the urls are not stored within a hyperlink formula). Here is a sample spreadsheet. I would like to extract the urls from the linked text (column A) into a new column in the spreadsheet.
Last year (2020) I found the custom function javascript code shared in the comments of this other StackOverflow question which worked well. However when I tried this with a new spreadsheet yesterday, this code was no longer working -- instead of returning the url, it returns nothing. There is no error message, it just returns an empty value.
Other things I've tried:
I was able to successfully retrieve the url in some cases by using this other javascript function:
function GETLINK(input) {
return SpreadsheetApp.getActiveSheet().getRange(input).getRichTextValue().getLinkUrl();
}
But it only worked correctly on cells where the text was not formatted as a number AND it requires entering the input as either a firm cell reference by putting it in quotes i.e. =getlink("A2") or by spelling out the address, i.e. =getlink(ADDRESS(ROW(A2), COLUMN(A2)))
I would like to figure out what has broken with the original code, which does not require these additional workarounds.
Explanation:
From the documentation, getRichTextValue() will return null if the value of the cell is not formatted as text. Most of the codes on the reference question use this method, so it returns error once getLinkUrl() is called. Thus the only workaround for this is to force text formatting by putting single quote before the cell value:
This should also work with linkURL().

Get accurate array of dates from sheet

I have a Google sheet with thousands of lines, each starting with a date. So:
2019-01-30
2019-01-30
2019-02-19
2019-03-06
2019-03-06
...
I need to get that column into a javascript array and then perform additional functions thereon. I know there is some issue with date indexing such that Google 2019-01-30 translates to javascript 2019-01-29 and a logger on the code confirms this.
How can I get that entire column into the Google Apps Script javascript (using dataSheet.getRange().getValues()) and have that be accurate to what is on the sheet? The only way I know is to individually go through each element of the array and add 1. That feels like a bad way to get around it.
Alternatively, am I better off just leaving it as-is and, when I need to output a date from the javascript to the sheet, add 1 at that point?
Get dates in a flat array
function getColumnOne() {
const startrow=2;
const ss=SpreadsheetApp.getActive();
const sh=ss.getActiveSheet();
const rg=sh.getRange(startrow,1,sh.getLastRow()-startrow+1,1);
var dateA=rg.getValues().map(function(r,i){return r[0];});
return dateA;//returns a flat array
}

Automate converting text to rows and columns (Google Sheets)

I'm trying to convert order form data submitted from a Squarespace website from the following format to a table with 4 columns:
Store,Item,Quantity,Details;Store2,Item2,Quantity2,Details2; (etc...)
Commas separate columns while semi-colons separate rows.
All the methods I've tried so far have been successful in splitting the data into the desired form, but the problem occurs when new data is added. When the form is submitted, it creates a new row in the next available empty row. I can't seem to find a way to automate the process without receiving cyclical dependency errors, since each order can have any amount of item entries.
Example spreadsheet:
https://docs.google.com/spreadsheets/d/1ZEWtmMiWO0Us76Z7o7GB7Salw1Rl_-1PhK6GzeOD0GM/edit?usp=sharing
The above example splits the data as desired. I cannot figure out how to make it work with the data added as a new row. I would also like to continue using sheets for its cloud functionality.
Any advice is appreciated, including entirely new ways of processing the data, whether with a script, a different remotely accessible order processing app compatible with Squarespace forms, or natively within Sheets.
You want to achieve the following conversion.
Sample formula:
=ARRAYFORMULA(SPLIT(TRANSPOSE(split(A4,";")),","))
In this formula, the cell "A4" has the input value.
You have already used the formula of =TRANSPOSE(split(A10,";")). In this answer, I used this.
For TRANSPOSE(split(A10,";")), the value is splitted with , using SPLIT and ARRAYFORMULA.
Result:
Sample script:
When you want to use Google Apps Script, you can also use the following script.
function myFunction(value) {
const values = value.split(";");
return values.splice(0, values.length - 1).map(e => e.split(",").map(f => isNaN(f) ? f : Number(f)));
}
In this case, please copy and paste the script to the script editor, and put the custom function of =myFunction(A4) to a cell.
The same result with above formula can be obtained.
References:
SPLIT
ARRAYFORMULA
split()
map()

Google spreadsheet search for part ,replace and delete

I'm trying to start a project using Tasker(an app developed for android) It has lots of useful plugins and I have stumbled upon google spreadsheet plugin.
With this plugin i can easily read from a spreadsheet.
But my problem is writing into the spreadsheet. I want to use the spreadsheet as a database for my tasker app.
This means it will write simple values to the Spreadsheet examples
A2 = Nexus5/off:1:8:1
A3 = Nexus6/on:2:3:4
I am now trying to script a search and replace within google scripts. And im getting stuck.
What i want it to do is if my Nexus5 turns on it will send to the spreadsheet in A1 Nexus5/on:1:8:1.
The script has to search for Nexus5/ in column A and replace the cell value with the new value. After that it has to delete A1 so new input can be put in. Beneath is the script i got so far it can search for an input I put in A1 and replace it in the list with test. But I can't seem to get it search just for the first part.
function replaceInSheet(sheet, to_replace, replace_with) {
//get the current data range values as an array
var values = sheet.getDataRange().getValues();
//loop over the rows in the array
for(var row in values){
//use Array.map to execute a replace call on each of the cells in the row.
var replaced_values = values[row].map(function(original_value){
return original_value.toString().replace(to_replace,replace_with);
});
//replace the original row values with the replaced values
values[row] = replaced_values;
}
//write the updated values to the sheet
sheet.getDataRange().setValues(values);
}
function onChange(e){
var sheet = SpreadsheetApp.getActiveSheet()
replaceInSheet(sheet,val,'test');
}
You want to use regexes to crack this nut. There is a comprehensive set of answers here.
In short, set your search to /^Nexus5\// (either with that raw regex declaration, or creating a new RegExp() object) & just use string.replace(), then write the updated values back as required.
e.g.
var myString = “Nexus5/1.2.3”;
var newValue = myString.replace(/^nexus5\/.+/i, “my new value”);
So, here we’re looking for a string beginning with “Nexus5/“ & replacing it with “my new value”. (^ anchors the search to the beginning of the string, .+ means 1 or more characters other than a line-end, we need to escape the slash - \/ - so it’s not interpreted as the end of the regex & the i after the pattern sets the search to case-insensitive.) We can now write newValue back to the source sheet however you need using the range.setValue() or range.setValues() method of the spreadsheet.

How to implement query function to use Google spreadsheet as a database?

I'm trying to use a spreadsheet as a database, where each sheet would be a table and the name of a person is used as a primary key (It seems not to be the best solution, but the good spreadsheet interface makes me prefer this solution rather than trying to use ScriptDB.)
And I want to do the following: When you select a name on a sheet and press a button on the menu I added, a function performs a search in another table and a screen and shows all the results of that query in the other table, showing properties records that only that table contains (later I want to add the possibility to generate a text file from a GDocs template).
My questions is:
1) Considering this screen/panel UI has a variable length (because the record number may vary in other tables), what is the best way to create this panel/UI in Google Apps Script? (I don't want to use the Logger.log because I want to add a button to convert the query into a file)
2) In addition to this solution (a search in the resulting 2D array):
function test(){ // to test the find function with an argument, 'any' in this case
var result = findItem('any');
if(result){Logger.log(result.getA1Notation())}else{Logger.log('no luck !')};
}
function findItem(item){
var ss = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var data = ss.getDataRange().getValues()
for(var n = 0;n<data.length;++n){
if(data[n].indexOf(item)>-1){ // this is a "strict" find, ie the value must be the entire search item. If you want to do partial match you should compare differently...
return (ss.getRange(n+1,data[n].indexOf(item)+1)); // if found return the range. note the +1 because sheets have 1 index while arrays have 0 index
}
}
return false;// if we come to the end of sheet without result...
}
There is an alternative method to perform queries like this?
THANKS for any help!
Create a UI instance. Then a scrollable panel inside a main panel is the best way of doing this and then using array's to search through the data. I typically create header body and footer panels with the body being scrollable

Categories