dynamic values in websites and docs - google-apps-script

Let's say my company has a website and it includes various text. One of the texts it includes is the name of my Director of HR. His/her name could appear 20 or 30 times in various pages and documents on our website. And, should there be a change and I hire a new Director of HR, someone'd have to do manually change those 20 or 30 values.
There's got to be a better way to do that. One option is a scrub the website of personal data in all instances but one, "Contact the Director of HR," and then have the one value "the director of HR is..." and hyperlink all the instances of the Director of HR to the Staff page. But I'm interested in dynamic values.
To begin with, let's say I have this Google Doc and this Google Sheet. How would I get the value on the Google Doc to change when I change the value on the Google Sheet?

You can generate a Doc from a Sheet using apps script.
You'll go to Tools -> Script Editor in your Sheet.
Every time you run this script it will generate a new Doc with the value present in your sheet.
function myFunction() {
var doc = DocumentApp.create('HR Sheet');
var data = SpreadsheetApp.getActive().getDataRange().getValues()
var body = doc.getBody();
body.appendParagraph(data[1][1]);
}
If you run this script it will generate a new sheet and put the name of the HR Director on the sheet.
Helpful Link:
Google Docs documentation with scripting

You want to do the following:
Get a list of ROLES and NAMES from a Sheet.
For each ROLE/NAME pair, look for a specific value in a Google Doc, and replace that value with the corresponding NAME.
You can use replaceText(searchPattern, replacement) to achieve this. It could be something like this:
function findAndReplace() {
// Get "Sheet1", where data is:
var sheet = SpreadsheetApp.openById("your-spreadsheet-id").getSheetByName("Sheet1");
// Get the document body:
var doc = DocumentApp.openById("your-doc-id").getBody();
// Get the "ROLE/NAME" values:
var values = sheet.getRange(2, 1, sheet.getLastRow() - 1, 2).getValues();
// For each "ROLE/NAME" pair, replace text:
values.forEach(row => body.replaceText("{{" + row[0] + "}}", row[1]));
}
Note:
In this sample, the values to look for in the Doc are built using each corresponding role, with this pattern: {{your-role-name}}. [ is a special character for regex, so I think using {{ is more appropriate for this situation.
Reference:
Body.replaceText(searchPattern, replacement)

These answers were great re: Google Docs (which was the question I asked). But re: Website, I found this really useful plugin, TablePress, and the extension, Single Cell Content Shortcode. Populating my Director of HR in a Wordpress Page is as easy as using the shortcode [table-cell id=1 cell=C3 /].
I'm playing with autorefresh now, which'd repopulate the uploaded Sheet from the URL regularly, so I couldn't have to reupload the Google Sheet every time.
Looks like it'll work 100% for my purposes of populating Google Sheet values on Wordpress pages.

Related

How do I pull sec.gov interactive EDGAR data into google sheets?

I am trying to pull data from Sec.gov's EDGAR system for specific financial statements of specific filings for specific companies.
The first problem I am having in doing this is trying to figure out how to generally pull data from, for example, this link into a table in google sheets: https://www.sec.gov/cgi-bin/viewer?action=view&cik=320193&accession_number=0000320193-20-000096&xbrl_type=v#
The second problem I am having is trying to pull such data, but from specific financial statements (like the statements of cash flows) in the "financial statements" section, as the link above only brings me to the cover page of the filing, and each separate tab does not have separate links.
I am new at scripting within google sheets and am struggling to even find how to start at such a script that can do the above. This script I found on reddit (https://www.reddit.com/r/googlesheets/comments/bbousq/help_with_a_script_that_fetches_data_from_secgov/) is the closest script I have found online for what I am trying to do; however, I am unable to make it work and I am unsure how to do so:
function secData(company, tablenum) {if (!company)
company = 'TROV';
var url = "https://www.sec.gov/cgi-bin/browse-edgar?CIK=" + company + "&owner=exclude&action=getcompany";
var result = UrlFetchApp.fetch(url).getContentText();
var reg = /<a href="\/cgi-bin\/viewer.+?cik=(\d+).+accession_number=([\d|-]+)/.exec(result);
var cik = reg[1];
var accession = reg[2];
return 'https://www.sec.gov/Archives/edgar/data/' + cik + '/' + accession.replace(/-/g, '') + '/R'+tablenum+'.htm';
}
Which uses this formula in the sheet itself:
=IF(NOT(ISBLANK(G1)), importhtml(secData(G1,4),"table",1), "")
Where:
company = company name/ticker
tablenum = number of financial statement table (3 might = balance sheet)
Overall, I am wondering how to pull sec.gov interactive EDGAR data into google sheets and am hoping someone can help me do so?
You have an Excel document link on every page. You download that and convert it to Sheets, it's fairly easy. Here's a snippet to get you started.

How to copy Table from a Spreadsheet to a Google Doc as `link to Spreadsheet`?

When users copy a range manually from a spreadsheet and paste it into a Google Doc, it prompts the option to "link to spreadsheet" and "paste normally".
I needed to do the functionality of "linked to a spreadsheet using google apps script"
Use case context
We have a spreadsheet with a table we are trying to copy to our final document where the user can add additional stuff.
So if for any reason some value needs to change in the spreadsheet, our users just want to simply refresh the table data.
Answer
This is not possible without a workaround.
In the table object in the documentation there is no method for inserting a table with a "link to spreadsheet" as there is in the UI. Seeking in the table object in the Docs API there is nothing exposed there either. You could file a feature request for this in the Issue Tracker, at the moment, I can see no feature requests for this.
A potential avenue for a workaround
Any workaround will not be as seamless as the UI, though if you want to automate the inserting of a table from a specific source, here is an example of that.
Please note that this is only a starting point. You should experiment with this and then if you need more features and run into problems, you should ask new questions about the specific problems your are having.
Introduction and initial steps
This script will take a table from a Sheet. This table should be the only thing in the sheet. The way the script is set up, is that it uses getDataRange which automatically selects all the data in a Sheet. You can modify this for your use case depending on how your spreadsheet is set up.
Then it will append the table to the end of the document. You can modify this depending on your needs. It will keep most of the formatting.
The styles will not match exactly, though again, this is something you can iron out the details depending on your use case.
Instructions
Get the id number of the spreadsheet and document
Create a script file
Copy this function:
function appendTable() {
// Replace these values with your Sheet ID, Document ID, and Sheet Name
let ssId = '<your spreadsheet id>' // REPLACE
let docId = '<your document id>' // REPLACE
let sheetName = '<your sheet name>' // REPLACE
// Sheet
let range = SpreadsheetApp.openById(ssId).getSheetByName(sheetName).getDataRange()
let values = range.getValues();
let backgroundColors = range.getBackgrounds();
let styles = range.getTextStyles();
// Document
let body = DocumentApp.openById(docId).getBody();
let table = body.appendTable(values);
for (let i=0; i<table.getNumRows(); i++) {
for (let j=0; j<table.getRow(i).getNumCells(); j++) {
let docStyles = {};
docStyles[DocumentApp.Attribute.BACKGROUND_COLOR] = backgroundColors[i][j];
docStyles[DocumentApp.Attribute.FONT_SIZE] = styles[i][j].getFontSize();
docStyles[DocumentApp.Attribute.BOLD] = styles[i][j].isBold()
table.getRow(i).getCell(j).setAttributes(docStyles);
}
}
}
Run the script!
Design how you want the user to run this and maybe set this up an add-on. Though this is out of the scope of this question.
References
Main Apps Script Page
Sheets Reference
SpreadsheetApp
getDataRange
getTextStyles - get the format from the sheet.
DocumentApp
Apps Script Docs Table
Doc Enum Attribute - for styling the table in Docs.

How to get a list of comments and replies from a docs and add content to a sheet? [duplicate]

Today I have a question about Google Apps Scripts, specifically for Spreadsheets. I've already looked at the documentation here (yes, documentation on a Sheet within a Spreadsheet), but I haven't been able to find what I'm looking for. Here's the sitch:
1.) When a cell is edited in a Google Spreadsheet, the function I have SETS a NOTE using the function (yes it says cell.setComment(), but in reality it creates a Note. Thanks for being consistent, Google!):
function onEdit() {
var doc = SpreadsheetApp.getActiveSpreadsheet();
var sheet = doc.getActiveSheet();
var cell = sheet.getActiveCell();
cell.setComment("Last modified: + (new Date()));
}
2.) Notes have been 'replaced' by Comments as of... September 5th, 2012? Maybe? I would rather use those instead.
3.) For both types of 'cell notation', there exist functions only to SET the Note/Comment, and not ADD (according to the documentation).
4.) I would like to reference or write a function that has the capability to ADD a new Note/Comment (preferably Comment, they are more easily read), instead of setting the Note/Comment.
5.) You can MANUALLY add a Note/Comment through the GUI in the Spreadsheet itself (right-click a cell and select "Insert Note" or "Insert comment". Because these right-click functions exist leads me to believe that we could write a script to do the same thing, but have it be called auto-magically when the cell has been edited.
6.) This function will be used to keep track of cell revision history. I know that I can create a new spreadsheet and send the revision history to that new spreadsheet easily, but considering that I have 10 spreadsheets that need to be tracked, I would rather not have 10 new spreadsheets to keep track of history. Keeping it in the same spreadsheet will keep things simple.
If anyone could help me out, it would be greatly appreciated!
There is no way to manipulate Comments via Spreadsheet Services - see Issue 36756650. (Star it if you wish.)
Instead, all the "Comments" methods work on Notes.
The following method will append a new "Modified" timestamp to any existing one - not quite as nice looking as an actual Comment would be, unfortunately.
function onEdit() {
var sheet = SpreadsheetApp.getActiveSpreadsheet();
var cell = sheet.getActiveCell();
var comments = cell.getComment();
// Newline works in msgBox, but not in Note.
comments = comments + "\\nModified: " + (new Date());
//Browser.msgBox(comments);
cell.setComment(comments);
}
Updated answer for dic 2018:
Now Google supports the setNote(String) and setNotes(Object[]) method in the Range class.
the getComment() and setComment() methods no longer exist.
Using Google Drive API in Google Apps Script, we could create Comments in a Google Document.
And after a test, I confirm you can also do it in a Spreadsheet (which is normal because Comments depends only on Drive API)
function insertDriveComment(fileId, comment, context) {
var driveComment = {
content: comment,
context: {
type: 'text/html',
value: context
}
};
Drive.Comments.insert(driveComment, fileId);
}
Keep in mind that you cannot attach programmatically the comment to a cell (or to words in Google Document), because anchors for Document and Spreadsheet Comments are proprietary (check the video at the bottom of the page here)
Hope it could help.
Now you can use setNote() and getNote()
var sheet = SpreadsheetApp.getActiveSpreadsheet();
var cell = sheet.getActiveCell();
var comments = cell.getNote();
cell.setNote(comments);

How to create a script to merge several sheets in another one?

Sory for my English, this is not my strength!
I am working for a NGO that charges training sessions.
We have a google sheet that compiles datas about participants at each training days one by one in different spreadsheets.
So my yearly document is composed of something like 30 spreadsheets.
I would like to create one more spreadsheet that would merge all the data from other tabs in order to :
- be able to see quickly who has not payed yet his bill
- calculate the total amount made
I know I can do it by using the Filter function but it is really time-consuming for so many spreadsheets and if I add a training session I would have to change the formula. Moreover, I will be forced to do it each year.
So I would like to create a button to import all the data in a new spreadsheet.
You will find an example of the sheet with only 2 spreadsheets here :
https://docs.google.com/spreadsheets/d/1-RxzUGJFXnU3_mJ3Qj0MCTpwPTlnmgIT439AchyrRrE/edit?usp=sharing
I hope you would be able to help me!!
Thanks and happy new year :D
Merging Sheets in another sheet in same spreadsheet.
You will need the id for spreadsheet named 'CopiDdeFCCE' the other parameter will default to 'CopieDdeFCCE'.
function mergeSpreadsheet(ssid,shname){
var shname=shname || 'CopieDdeFCCE';
var ss=SpreadsheetApp.openById(ssid);//id of spreadsheet named 'CopieDdeFCCE' in your case
var sh=ss.getSheetByName(shname);//sheetname of sheet where other sheets are merged into again in your case its named 'CopieDdeFCCE'
if(!sht){ss.insertSheet(shname);}
var allshts=ss.getSheets();
for(var i=0;i<allshts.length;i++){
if(allshts[i].getName()!=shname){//do this for all sheets except shname
var shi=allshts[i];
var rg=shi.getDataRange();
var vA=rg.getValues();
shi.getRange(sh.getLastRow() + 1, 1,shi.getLastRow(),shi.getLastColumn()).setValues(vA);
}
}
}
Just to be clear.
What Google calls the spreadsheet is the file that contains all of the tabs (i.e. sheets).
In your first comment you said the following: I would like to merge all the 28 sheets of a file called "CopieDdeFCCE" to a new sheet of the same file.
But now in your question you say: I would like to create a button to import all the data in a new spreadsheet.
You stated in your last comment that your command looks like this: mergeSpreadsheet("1KC6kHcgtLZ93S4-r4wOwHFOG6Rq3mesGRKv26Ttnm9E","CopieDdeFFCE")
But clearly that's not the id of the example and the example does not have a sheet with that name.
So my question is: What exactly do you want?
Very sory I did not receive any notification of your reply because it was an edit and when I came to see if you wrote something I looked at the bottom of the site. :/
First of all, happy new year and thank you again for your help!!
Here are the precisions you asked :
1° Indeed, I would like to merge all the 28 sheets of a file called "CopieDdeFCCE" to a new sheet of the same file. To be more accurate, I give you the link of the exact location of the document with some examples of sheets: link.
2° Secondly, I will create a button to update all the data easily. But I think I know how to do that, so forget that question for now ;)
3° In the document I put enclosed, do we agree that the "id" is : 1KC6kHcgtLZ93S4-r4wOwHFOG6Rq3mesGRKv26Ttnm9E ??
Thanks again for all your time!

How to show in Google Form value from Google Spreadsheet

I have connected Google Spreadsheet with Google Form but I don't know, how can I include values from Spreadsheet to Form and display them (which will be in my scenario free left space for course registration).
explanation picture: https://drive.google.com/file/d/0B4HOotJEv18lLTNiY3ZmcGl3T3M/view?usp=sharing
Expected outcome: course has 30 free seats for students and I want to show in my Google Form, how many free seats lefts for course registration.
Many thanks for your help, also script example will be very welcome.
You can create the form in AppScript with Forms Service and set the questions and choices in the script. Within the script you can also reference a Spreadsheet, so you should be able to read the data from a spreadsheet and put it onto a form that way.
Haven't actually tried it, but it'd probably look something like:
var form = FormApp.create('New Form');
var item = form.addCheckboxItem();
var ss = SpreadsheetApp.openById("<ID>");
var val = ss.getRange(<RANGE>).getValue();
item.setTitle('Question ' + val + ' Question');
item.setChoices([
item.createChoice('ONE'),
item.createChoice('TWO'),
item.createChoice('THREE')
]);
You can also check out this Quickstart and Video.