How to get validation pattern from Google Form item - google-apps-script

In Google Forms, a question/item of class TextItem can have a validation pattern set (i.e., the response must match the pattern to be accepted by the form) by doing something like:
var textValidation = FormApp.createTextValidation()
.requireTextMatchesPattern(my_regex_pattern)
.build();
textItem.setValidation(textValidation);
I would like to read that pattern from an existing textItem (in order to have a script go through several questions with unique patterns and save them), but I cannot find any references to relevant methods or properties for validation rules, e.g. (made-up examples):
var existing_pattern = textItem.getTextMatchesPattern();
or
var existing_patern = textItem.getValidation.getTextMatchesPattern();
From what I can see, it looks like this is not actually possible, but that seems quite strange. Am I missing something?
Note: Using the Web interface, it's trivial to get the pattern for a given question/item. I'm specifically asking how to get it through a script.

Related

How to I save text from a document into a variable?

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.

Apps script JSON.parse() returns unexpected result, how can I solve this?

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

Problems with body.findText in Google apps script

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)

Calling Background colors from google sheets using Google sheets api is missing data

From a previous question linked here ( Previous Question ) I learned about Sheets.SpreadSheets.get calling a JSON of sheet data that would allow me to get the backgroundcolors of a sheet within my project. Id previously been doing this with var BackgroundColors = ActiveWeekSheet.getDataRange().getBackgrounds(); but was told that the JSON method would be a faster read/write method. They directed me to do some reading on Javascript objects but after that I'm still confused.
I've got the following code. TestArray = Sheets.Spreadsheets.get("1irmcO8yMxYwkcLaxZd1cN8XsTIhpzI98If_Cxgp1vF8"); which seems to call a JSON with sheet specific data. A logger statement of TestArray returns this: testArrayObject: {"properties":{"gridProperties":{"rowCount":1000,"columnCount":26},"sheetType":"GRID","index":0,"sheetId":0,"title":"Awesome"}}
Community members previously suggested I could then find the background colors at: sheets[].data[].rowData[].values[].cellData.effectiveFormat.backgroundColor
I've highlighted one of the cells yellow but when reviewing the above JSON i can't seem to find anything that references color. There definitely isn't any multileveling of the JSON to refer to sheets->data->rowData->values->celldata.effectiveFormat.backgroundColor.
What am I missing here? Do I need to format things someway? Am I not calling the right JSON to start with?
Thanks!
As written in the documentation,
By default, data within grids will not be returned. You can include grid data one of two ways:
Specify a field mask listing your desired fields using the fields URL parameter in HTTP
Sheets.Spreadsheets.get(spreadsheetId, {
ranges:"Sheet1!A1:A5",
fields:"sheets(data(rowData(values(effectiveFormat.backgroundColor))))"
})
Set the includeGridData URL parameter to true. If a field mask is set, the includeGridData parameter is ignored
Sheets.Spreadsheets.get(spreadsheetId, {
ranges:"Sheet1!A1:A5",
includeGridData: true
})
Field mask documentation:
In a nutshell,
multiple different fields are comma separated, and
subfields are dot-separated.
For convenience, multiple subfields from the same type can be listed within parentheses.
You may test the API here
There are optional parameters in the spreadsheets.get method that will give you that data, but you need to explicitly include them:
ranges – The ranges to retrieve from the spreadsheet.
includeGridData – The cell data within specified range.
This specifies a range of just one cell (A1 in Sheet1), but you can specify a larger range and navigate through the array if you need to.
var TestArray = Sheets.Spreadsheets.get(SS_ID, {ranges: "Sheet1!A1", includeGridData: true});
Really important that you keep in mind this returns a Color object with RGBA
values that range from 0-1, but elsewhere apps script uses hex color or the conventional 0-255 RGB values.

Understanding google spreadsheets set vs get logic

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.