I'm desperately trying to learn to "think" in this language (my native coding language is VBA/ASP).
Here is a very basic example that simply reads the contents of a specific cell in Sheet1 and then assigns that value to a variable named rngVal
var ss = SpreadsheetApp.getActiveSpreadsheet();
ss.setActiveSheet(ss.getSheetByName("Sheet1"));
var rngVal = ss.setActiveSelection("A1").getValues();
When I attempt to deconstruct this very simple 3-line piece of code (in the interest of understanding it's purpose), I admit to being rather perplexed.
Here's why:
When I insert a msgbox after each line, I get this:
var ss = SpreadsheetApp.getActiveSpreadsheet(); = "Spreadsheet"
ss.setActiveSheet(ss.getSheetByName("Sheet1")); = "Spreadsheet"
var rngVal = ss.setActiveSelection("A1").getValues(); = The cell value
What is "Spreadsheet"?
How is this helpful(?) and how can I use it for the benefit of navigating the worksheet and reading/writing values within it?
That's 2 lines of code that does what(?), and for what benefit?
(I'm not trying to be combative, I'm just trying to understand so that I can learn to "think" in this language)
Secondly:
In the first line, what am I get ting?
In the second line I'm first set 'ting, and then I'm get 'ting? (I'm very confused about what that line is actually doing)
In the third (last) line there is more set 'ting and get 'ting, although this time it's not nested.
This is very basic code (functionally), but I'm having trouble grasping it's logic in terms of how to "think" using that logic.
Is there anyone out there who would be kind enough to show some patience and help me by describing the step by step logic of this simple code of selecting a cell, capturing it's value, and then assigning it to a variable?
Please understand, that when I "think" of how to do that very simple task, I can do it in one very concise line (in VBA)...
rngVal = Sheets("Sheet1").Range("A1").Value
...therefore I am really confused by all of the "Spreadsheet" stuff and the need for 3 lines filled with set's and get's.
Anyone? Please?
Hmm somehow the correct answer (my other one) got voted down. Again its pointless to do setactiveselection, there is no need to change the selected cell it just makes your code slower.
Google uses Javascript Classes to represent these different Objects.
I've split line 3 into two parts to help with my explanation. Please compare:
var ss = SpreadsheetApp.getActiveSpreadsheet();
ss.setActiveSheet(ss.getSheetByName("Sheet1"));
var rng = ss.setActiveSelection("A1");
var val = rng.getValues();
Each line above returns a different class of Object. The first line returns an Object with class Spreadsheet, the second line returns an object of class Sheet, the third line returns an object of class Range, and the final line returns an object of class Object.
Take a look here for documentation on the various actions (methods) that can be performed on/with the different classes of objects. When I'm building a Google App, I live on that webpage.
To compare the above with the code you understand from VBA, this line:
rngVal = Sheets("Sheet1").Range("A1").Value
Could be written in Javascript in one line as follows:
var ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet1").setActiveSelection("A1").getValues();
Hope that helps. Let me know if you have questions.
You guys are doing it more complex than neeeded. No need to mess with selection.
Getactivespreadsheet ().getsheetbyname ("x").getrange ("a1").getValue () also works.
Related
This question already has an answer here:
Cannot find method getRange(number,number)?
(1 answer)
Closed 5 months ago.
I am really sorry.. this is probably going to be the dumbest question you have seen in a good long time, if not ever... LOL I have been pulling my hair out on this for two hours and for the life of me I can't figure out what I am doing wrong...
This is stupid simple. It is a simple SpreadsheetApp.getRange() using the alternate parameters instead of your the usual "A1" reference. I am sure I am screwing up the syntax, but for the life of me I can't seem to figure out or find what it is that I am doing wrong...
This ties in with a larger project, of course, but for the sake of simplicity, this is what I currently have:
function test() {
var teamSheet = SpreadsheetApp.getActive();
teamSheet.getRange("25,25").activate();
teamSheet.getCurrentCell().setValue("Stuff");
};
All I want it to do there is go to Y25 and put in the word "Stuff". This is eventually going to end up in a loop where both the Row and Column values are increasing with each iteration - hence why I am using the alternate parameters instead of just entering "Y25".
I have tried in single quotes, double quotes, no quotes, square brackets, R[25]C[25], on and on... The error message I am getting is either Exception: Range not found or Exception: The parameters (String,number) don't match the method signature for SpreadsheetApp.Spreadsheet.getRange.
I appreciate this is a bit of a waste of your time and I am likely making some stupid, silly mistake - but I don't see it and I am loosing my mind on this... Please help!!
The script you provide always goes to A25 because the current cell of an active range is always the upper left corner. It's the same as this one.
function test() {
const ss = SpreadsheetApp.getActive();
ss.getRange("25:25").activate()
ss.getCurrentCell().setValue("A25");
};
I don't understand why you would want to but you could right it like this:
function test() {
const ss = SpreadsheetApp.getActive();
ss.getRange("Y25:25").activate()
ss.getCurrentCell().setValue("Y25");
};
And then it would go to Y25 and put "Y25" there or just as easily
function test() {
const ss = SpreadsheetApp.getActive();
ss.getRange("Y25").activate()
ss.getCurrentCell().setValue("Stuff");
};
If this does not answer your question let me know. Perhaps you should ask it in the context of how you wish to apply it.
I want to take the text for a document and save it as a variable. I looked in the documentation and found "getText" something I think shall work. https://developers.google.com/apps-script/reference/document/footnote-section#gettext
I just get a problem when I try using it, because it's not a pre built function it gives the error massage "TypeError: Cannot read property 'getText' of null". So I looked at some more into it and noticed I needed Authorization:
"Scripts that use this method require authorization with one or more of the following scopes:
https://www.googleapis.com/auth/documents.currentonly
https://www.googleapis.com/auth/documents"
So how do I get the required authorization, do I need to do something different or is there another way i could do it?
It's just going to run on some of my docs for fun to se what funny things I am able to do with the program.
(New to programing, now the basics but just trying to see if programing is something for me)
Thanks in advance
Given with this sample document
You can start with this sample code below.
Code:
function myFunction() {
var body = DocumentApp.getActiveDocument().getBody();
var text = body.editAsText();
Logger.log(text.getText()); // returns all text in document ("Hey, search for me!!! I am <here>!!")
// 1. Regular expression (exec)
var regExp = new RegExp("<\(.*\)>", "gi"); // "i" is for case insensitive
var search = regExp.exec(text.getText())[1];
Logger.log(search); // returns "here"
// 2. (search)
Logger.log(text.getText().search(/here/)); // returns the index where the string was found, or -1 if not found
}
Output:
Note:
getText will return the text of the Class Text.
If you want to get a specific pattern from the document, you need to use Regular expression. I prefer the exec method. See usage for more details
For the authorization, you only need to click allow. I assume you are using apps script due to the tag.
I am currently working on external app using Google Sheets and JSON for data transmission via Fetch API. I decided to mock the scenario (for debugging matters) then simple JSON comes from my external app through prepared Code.gs to be posted on Google sheets. The code snippet I run through Apps-scripts looks like this:
function _doPost(/* e */) {
// const body = e.postData.contents;
const bodyJSON = JSON.parse("{\"coords\" : \"123,456,789,112,113,114,115,116\"}" /* instead of : body */);
const db = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
db.getRange("A1:A10").setValue(bodyJSON.coords).setNumberFormat("#"); // get range, set value, set text format
}
The problem is the result I get: 123,456,789,112,113,000,000,000 As you see, starting from 114 and the later it outputs me 000,... instead. I thought, okay I am gonna explicitly specify format to be returned (saved) as a text format. If the output within the range selected on Google Sheets UI : Format -> Number -> it shows me Text.
However, interesting magic happens, let's say if I would update the body of the JSON to be parsed something like that when the sequence of numbers composed of 2 digits instead of 3 (notice: those are actual part of string, not true numbers, separated by comma!) : "{\"coords\" : \"123,456,789,112,113,114,115,116,17,18\"}" it would not only show response result as expected but also brings back id est fixes the "corrupted" values hidden under the 000,... as so : "{"coords" : "123,456,789,112,113,114,115,116,17,18 "}".
Even Logger.log() returns me initial JSON input as expected. I really have no clue what is going on. I would really appreciate one's correspondence to help solving this issue. Thank you.
You can try directly assigning a JSON formatted string in your bodyJSON variable instead of parsing a set of string using JSON.parse.
Part of your code should look like this:
const bodyJSON = {
"coords" : "123,456,789,112,113,114,115,116"
}
I found simple workaround after all: just added the preceding pair of zeros 0,0,123,... at the very beginning of coords. This prevents so called culprit I defined in my issue. If anyone interested, the external app I am building currently, it's called Hotspot widget : play around with DOM, append a marker which coordinates (coords) being pushed through Apps-script and saved to Google Sheets. I am providing a link with instructions on how to set up one's own copy of the app. It's a decent start-off for learning Vanilla JavaScript basics including simple database approach on the fly. Thank you and good luck!
Hotspot widget on Github
I have a Google doc which was created in Word and imported. I want to locate a 'marker' in the text so that I can insert a table at that point. However, I am unable to progress because my script keeps falling over at the "findText()" point. I have looked at a number of answers to similar problems on here and used what I think are identical methods, but it still falls over!
Rather than post code here, it seems clearer to post a screenshot of exactly what I get when I attempt to run the script. The first two items in the execution log prove that a) the document is being opened correctly and b) that the body is being correctly identified. There is definitely a "$" sign later in the text, so why am I getting the error?
Script
var doc = DocumentApp.openByUrl("https://docs.google.com/document/d/###/edit");
var body = doc.getBody();
var tblLoc = body.findText("$");
console.log(tblLoc)
Modification points:
From your following image,
I thought that the reason of your issue is due to $ of body.findText("$").
In this case, I think that it is required add \\ like body.findText("\\$")
The method of findText() returns the object of DocumentApp.RangeElement. So when you use console.log(tblLoc) and when the value is retrieved, {} is shown in the log.
When you want to see the retrieved value, for example, you can use console.log(tblLoc.getElement().asText().getText()).
When above points are reflected to your script, it becomes as follows.
Modified script:
const doc = DocumentApp.openByUrl("https://docs.google.com/document/d/###/edit");
const body = doc.getBody();
const tblLoc = body.findText("\\$");
console.log(tblLoc.getElement().asText().getText())
Reference:
findText(searchPattern)
My problem is:
const answers = sheet.getSheetValues(2, 2, sheet.getLastRow()-1, sheet.getLastColumn()-1); // Get the information from the sheet
formResponse[i].withItemResponse(items[19].asCheckboxItem().createResponse( answers[i][17])); // add a response to formResponse ,it is a checkbox item
answers[i][17] is an object actually. It has the value "FALSE". I get this error:
Cannot find method createResponse(string).
Even if i write false/true or "false"/"true" or something else , createResponse rejects it with error. When i use boolean i take the same error with the boolean version.
How should i add the checkbox as a response ? Thanks in advance.
I solved the problem with a weird way. Code:
if(answers[i][17] == true)
formResponse[i].withItemResponse(items[19].asCheckboxItem().createResponse( new Array(items[19].asCheckboxItem().getChoices()[0].getValue() )));
The reason behind this:
You need to give the string array, not string itself. And string must be the checkbox title, not true or false. Because we could add more than one checkbox and when it comes to checkboxes responses, how could we choose which one is true or false? So i took the choices and since i have one choice, instead of making it string array in a loop i decide to use only the first item. Since i have one item, array has one element. But it is choice array, so i took the first string and i put it in a new array. Here it is, you have a string array. For multiple checking, you can create a loop that iterates the choice array and add their value(which is string) to a new array. Like:
var strArray = new Array(choiceArray.length);
for(var i=0; i < choiceArray.length; ++i)
strArray[i] = choiceArray[i];
And you can disable some of the for letting it unchecked. It is just a way, you can do more efficient versions.
PS: I think that google apps script has things that enforce the developers to write non-efficient and too many lines of codes. But at the end, the fundamental system is working great and actually if some of us decide to use another language or framework, it could be much slower.