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

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

Related

Retrieving a row and adding it into another character sheet tab does not carry its properties

I am using Google-sheet as my database & google API request.
let rows: GoogleSpreadsheetRow = getSomeRows()
let row = rows.filter(...)
let index = (await this.memo.addRow(row)).rowIndex
addborders(this.memo, index, 0)
You can see the task are simple, Retrieve a row, store it into the variable and finaly add all the information at the end of another google sheet tab with the help of .addRow(). What I was expecting is for it to keep all its cells properties but what I got is a row added in RAW meaning there are no borders, padding etc so I resolve this by adding them manually with my small function I created called addborders.
The code is working perfectly fine but the only thing I couldn't find is how to retrieve the cell history.
If anyone knows how to do it, would be very much appreciated & maybe it could carry the formatting properties too so i don't have to use my addborders function anymore while using .addRow().
Best Regards.

importdata undefined within googlescript

I have a Google Sheet where I am tracking various asset prices including crypto.
The easiest way to get crypto prices is by importing from cryptocurrencies.cc:
=importdata("https://cryptoprices.cc/AION/");
However, now my spreadheet is full of references to the cryptoprices.cc website. If it ever goes down or changes domain, I would have to replace the URL everywhere in my sheet, which is quite uncontrolled. So I thought about making a wrapper function:
function cryptofinance(token) {
return importdata("https://cryptoprices.cc/"+ token);
}
This returns an #Error! however: ReferenceError: importdata is not defined (line 94). I am assuming that you cannot call Google Sheet functions outside of the context of the Sheets cells, correct?
If not, what is the proper way to call importdata from within this function?
If yes, then what is the best alternative to retrieve the same information using javascript?
You cant use importdata like a formula at this place.
first you need to get cell refernce then
you need to put formula inside the setvalue() function;
var currentCell = SpreadsheetApp.getCurrentCell(); // Select cell here
currentCell.setValue('=importdata("https://cryptoprices.cc/"+ token)');
for select a range of cells you can use getRange() function
SpreadsheetApp.getRange(row,col).setValue('=importdata("https://cryptoprices.cc/AION/")');
change row, col with cells range.

Google Sheets Scripts: Can you get a range from a rangeId?

My google sheet has a cell on sheet1 that contains a link to a cell on sheet2. In my function, I am able to get the link url, but cannot figure out how to get a range from the rangeId:
var link = generatorSheet.getRange(currRow, 2)
var linkUrl = link.getRichTextValue().getLinkUrl()
Logger.log(linkUrl) // linkUrl = "rangeid=1843553975"
I've tried using getRangeByName and various other functions but keep getting a null value back, not a Range object.
Thanks in advance!
Edit: My overall goal in this is to iterate over each row in sheet1, where each cell in column 2 links to a cell in sheet2. I need to take the value from the cell in sheet2 and copy it into sheet3. In sheet1, there's a check box in column 1 of each row, so that's what I'm using to determine whether or not the linked to value will be copied. I'll have a button to kick off my function and populate sheet3, and it has to assume these links are already in place - they were done by hand prior
When you create an hyperlink to a range using the user interface, you are facing this issue. I think you may have to change the way of designing the hyperlink and try to define it by the formula
=hyperlink("#gid=123456789&range=A2","go to ...")
and then you will retrieve the range by
Logger.log(linkUrl.match(/(?<=range=).*/g))
For documentation purposes,
This is a url hash fragment:
#rangeid=1843553975
The id seems to be created, when inserting a link to a range using the user interface. This is distinctly different from a namedRange When clicked, it's appended to the url in the browser, i.e.,https://docs.google.com/spreadsheets/id/edit#rangeid=1843553975. Once appended, through onpopstate javascript event, the range linked to the id is highlighted in the browser/app.
NamedRanges has a similar workflow. It also provides a rangeid=<10 digit ID>. But, it also has a name attached to it. But even in this case, the rangeid is not retrievable, though Sheets API provides a obfuscated range id.
There was a feature request made to Google, but it was made obsolete, because of lack of response on the part of the requestor:
https://issuetracker.google.com/issues/162810351
You may create a new similar issue there with a link to this answer. Once created, link the issue here.
Other related trackers:
https://issuetracker.google.com/issues/129841094
https://issuetracker.google.com/issues/134986436

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.

Categories