I am trying to create a function within google app scripts that parses a specific value from and places that value within my google spreadsheet - google-apps-script

function getEarnings() {
var url = 'http://finviz.com/quote.ashx?t=ntct';
var text = UrlFetchApp.fetch(url)
var pageHtml = text.getContentText();
var doc = XmlService.parse(pageHtml);
var 1yrReturns = getElementsByClassName();
var sheet = SpreadsheetApp.getActive(EQUITY DB);
var rows = sheet.getDataRange();
var numRows = rows.getNumRows();
return (doc);
}
This is what I have thus far but I got stuck on XmlService portion of the code, this is for a very important class so PLEASE HELP!

It is easier to use importhtml. Enter this in the cell of your spreadsheet that you want 25.6% returned to:
=ArrayFormula( SUBSTITUTE( index(importhtml("http://finviz.com/quote.ashx? t=ntct","table",11),4,6) , "*" , "" ) )
To explain, if you enter the following, it will return the entire table:
=importhtml("http://finviz.com/quote.ashx?t=ntct","table",11)
index lets you pick the value you want from the table. In this case row 4, column 6 (the ,4,6). You can get any value from the table by its row and column.
The data is returned with asterisks before and after. The substitute replaces "*" with "".
I hope this helps.

Related

How to copy cell value to another sheet base on criteria (Apps Script)

I'm trying to write some Apps Script to pull only the email addresses which match from an array of companies into another sheet for processing. This should also remove the #company.com extension and leave me with just the username.
So on Sheet 1:
In Column E, we have the Company names under Header: "Company"
In Column D, we have the Email Addresses under Header: "Emails"
On Sheet 2:
In Column A, we need the Username result under Header: "Username"
Currently the below script which should have 2 results, comes back with:
this
Any help with this would be immensely appreciated as I'm losing my mind.
Thank you!
function pullUsernames() {
//Get Sheet1
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Sheet1");
//Set Values for Search
var valuesToWatch = ['Company1','Company2'];
var range = sheet.getRange(2,5,sheet.getLastRow()-1).getValues();
var emails = sheet.getRange(2,4,lr-1).getValues();
//For Loop to match values, etc.
for(var i=0; i < range.length; i++){
if(valuesToWatch.indexOf(range[i][0])){;
var targetSS = SpreadsheetApp.openById("1hpIIgkXMgrlOfYqfS4A3ro8BFQB02dAy5G40Y7vUI2c").getSheetByName("Sheet2");
var targetRange = targetSS.getRange(i+1,1,targetSS.getLastRow(),1);
var usernames = String(emails[i][0]).replace("#company.com", "")
targetRange.setValue(usernames[i][0]);
} //if
} //for
} //Function
There were a bunch of issues in your code and I decided to optimize them. Feel free to modify the code if needed.
Issues:
Both range and emails can be fetched together instead of separate
Brought targetSS outside the loop since it is only static based on your issue
I don't quite get your getRange, I assume you want to append the usernames on the last row? If so, then use appendRow instead.
Since I didn't use the array index now, I used includes instead to check if the data is in valuesToWatch.
Your email string manipulation is quite hard coded so I replaced it with a better solution, removing anything but the characters before #.
Code:
function pullUsernames() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Sheet1");
// update your targetSS, made it under same ss for easier testing
var targetSS = ss.getSheetByName("Sheet2");
// set values for search
var valuesToWatch = ['Company1', 'Company2'];
// get email and company columns in one go
var data = sheet.getRange(2, 4, sheet.getLastRow() - 1, 2).getValues();
// each row of data contains email and company formatted as [email, company].
data.forEach(function ([email, company]){
if(valuesToWatch.includes(company))
// remove anything from # onwards from email and append at last row
targetSS.appendRow([email.substring(0, email.lastIndexOf("#"))]);
});
}
Sample Data:
Sample Output:

String ranges in Google Apps Script

I have a sheet that I need to get values from and set in a new sheet, one of these values requires me to slice string value at indices 20,26. I can achieve this using .getValue().slice(20,26) and .setValue(). However, the same data is set in all rows, which is to be expected since I am only getting a single cell of data. To resolve this I tried a for loop which failed.
When I attempt .getValues().slice(20,26) it returns an empty array which throws the following error: The number of rows in the data does not match the number of rows in the range. The data has 0 but the range has 20.
My code is below and I welcome any guidance.
function pj() {
// Get Active spreadsheet.
var sheet = SpreadsheetApp.getActiveSpreadsheet();
//Get last row processed and update
var startRow =sheet.getSheetByName("Index").getRange("A1").getValue();
startRow++;
// Get payments sheet.
var paymentSheet = sheet.getSheetByName("Payments");
var clientSheet = sheet.getSheetByName("Client Details");
var lastRow = paymentSheet.getLastRow();
//Inputs
var firstName = paymentSheet.getRange(startRow, 3, (lastRow-startRow+1), 1).getValues();
var lastName= paymentSheet.getRange(startRow, 4, (lastRow-startRow+1), 1).getValues();
var paymentId = paymentSheet.getRange(startRow, 14, (lastRow-startRow+1), 1).getValues().slice(20,26);
}
//Outputs
clientSheet.getRange(2,1,(lastRow-startRow+1),1).setValues(firstName);
clientSheet.getRange(2,8, (lastRow-startRow+1),1).setValues(paymentId);
//Update the last row processed
sheet.getSheetByName('Index').getRange("A1").setValue(lastRow);
}
Please see image of the sheet I am working with, as you will see column N contains a payment ID, which holds a unique identifier for the client that I need to extract in order to upload this data into Salesforce. It seems the issue is that Logger.log is reporting the string correctly as it goes through the array, but is reporting the length as 1. I've tried changing the format of that column various ways, Text, Number etc but it doesn't seem to make any difference to the reported length. I'm assuming this is why the split function isn't working, but I'm not sure why it's happening?Sheet
I guessed at a lot of this but it should look similar to this:
function pj() {
var ss=SpreadsheetApp.getActive();
var isht=ss.getSheetByName("Index");
var startRow=isht.getRange("A1").getValue()+1;
var psht=ss.getSheetByName("Payments");
var csht=ss.getSheetByName("Client Details");
var lastRow=psht.getLastRow();
var prg=psht.getRange(startRow,1,psht.getLastRow()-startRow+1,14);
var pvals=prg.getValues();
pvals.forEach(function(r,i){
csht.getRange(i+2,1).setValue(r[2]);
csht.getRange(i+2,2).setValue(r[3]);
csht.getRange(i+2,8).setValue(r[13].slice(20,26));
});
isht.getRange("A1").setValue(csht.getLastRow());
}

Lookup cell reference of given value

I have a spreadsheet with hundreds of rows and Column A is a unique record number.
I would like to learn to be able to find cell reference based on the inputted unique record number.
For example if in Call A1, I enter value 11, ho can I retrieve cell row (eg: 17) using google script.
Thank you for help
Taizoon
You can build a simple and small Ui that does a "search" in your first column and activates the found cell (and the whole row). An example is shown below, You have an option to use it repeatedly (like it is now) or just once by changing one line of code, see comment at the end of the handler function. :
function showInSheet() {
var app = UiApp.createApplication().setTitle('Search and Select').setWidth(250).setHeight(60);
var panel = app.createVerticalPanel();
var searchHandler = app.createServerHandler('searchRow').addCallbackElement(panel);
var Hpanel = app.createHorizontalPanel();
var search = app.createTextBox().setName('search').setId('search').setWidth('70').addKeyUpHandler(searchHandler);
var warning = app.createHTML('incomplete or invalid entry').setId('warning').setStyleAttributes({'padding-left':'10px','background':'yellow','fontSize':'8pt'}).setVisible(false);
app.add(panel.add(Hpanel.add(search).add(warning)));
SpreadsheetApp.getActive().show(app);
}
function searchRow(e){
var app = UiApp.getActiveApplication();
var item = e.parameter.search;
var sh = SpreadsheetApp.getActiveSheet();
var data = sh.getRange(1,1,sh.getLastRow(),1).getValues().join().split(',');// the 2D array is "flattened" and splitted to get a 1D array
Logger.log(data.length);
var idx = data.indexOf(item);// in a "simple" array we can use this array function more easily to seach in it ;-)
Logger.log(idx);
if(idx>data.length || idx==-1){app.getElementById('warning').setVisible(true) ; return app};
idx++;// increment because rows count from 1 instead of 0 in arrays
var itemRange = sh.getRange(idx,1,1,sh.getMaxColumns());
sh.setActiveSelection(itemRange);
// return app.close();// can be replace by next line (uncommented)
app.getElementById('search').setText('');app.getElementById('warning').setVisible(false);return app;
}

search spreadsheet column for text in a string and return a result in another column

Using google apps script and spreadsheet, I have been trying to do a simple thing but can't figure out the problem. I have a sheet, with a blank column and a column with text. The columns are not next to each other. I am trying to search for text in each cell in one column, and if the text is found, then set the value of the cell in the empty column as 'Yes'.
Example (sorry no code - I've gone round and round with it for hours, and what I have is so convoluted, it's best to just provide an example):
Column A with text Empty Column F
abcd efg hij
klmn opq rstu
vwxzy Yes
What is the simplest code to search Column A for 'xyz' and return a 'Yes' in Column F?
I've looked at and tried about a dozen different code examples online, and can't get any of them work. Appreciate any help with this!!
EDIT (Final hopefully) for my use (I have some backend utilities that get me the column number based on the header name, that code not included in this, fyi):
var sskey = SpreadsheetApp.openById('**********************')
function otherfunction(){
addCustomValue('POCs', 'Groups', 'Champion', 'Champion', 'Yes');
}
function addCustomValue(sheetNamestr, searchColnamestr, writeColnamestr, searchKeystr, writeValstr) {
var sheet = sskey.getSheetByName(sheetNamestr);
var searchColnum = MyUtilities.getColIndexByName(sheet, 1, searchColnamestr);
var writeColnum = MyUtilities.getColIndexByName(sheet, 1, writeColnamestr);
var data = sheet.getDataRange().getValues();
for (n=0; n<data.length; ++n) {
if (data[n][searchColnum-1].toString().match(searchKeystr)==searchKeystr){ data[n][writeColnum-1] = writeValstr};
}
sheet.getRange(1,1,data.length,data[0].length).setValues(data);
}
Thanks Serge! Now I can run this over my spreadsheets based on any columns and conditions!
This is a possible simple script that does what you need. (If your sheet contains formulas or custom function then it should be modified to take it into account)
function test(){
var sh = SpreadsheetApp.getActiveSheet();
var data = sh.getDataRange().getValues(); // read all data in the sheet
for(n=0;n<data.length;++n){ // iterate row by row and examine data in column A
if(data[n][0].toString().match('xyz')=='xyz'){
// if column A contains 'xyz' then set value in index [5] (is column F)
data[n][5] = 'YES'
};
}
Logger.log(data)
sh.getRange(1,1,data.length,data[0].length).setValues(data); // write back to the sheet
}
function myFunction() {
//Variable to keep track of the sheet
var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
//Start at row 1, end at the last row of the spreadsheet
for(var i=1;i<sheet.getLastRow();i++){
var value = sheet.getRange(i, 1).getValue();
//Compare the value of the cell to 'xyz', if it is then set column 4 for that row to "Yes"
if(value == 'xyz'){
sheet.setActiveRange(sheet.getRange(i, 4)).setValue('Yes');
}
}
}

writing delimited text as a string to a spreadsheet

i have a short script where i'm trying to grab data from a URL and write it to a sheet of an existing spreadsheet. the script is as follows:
function urlDataImport() {
var input = "https://reports.acc-q-data.com/clientreports/ecaldwell_201206192722/ecaldwell_20122722.txt";
// The code below gets the HTML code.
var response = UrlFetchApp.fetch(input);
var data = response.getContentText();
Logger.log(data);
var ss = SpreadsheetApp.getActiveSpreadsheet();
var ptSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("pt");
ptSheet.getActiveRange().setValues(data);
}
the information in data is tab delimited and shows up properly in the log but because it's a string i can't use .setValues to write it to the sheet pt and i'm not sure how to get the information from the URL in any other way.
i'm sorry for the rudimentary nature of this question but i'm very new to scripting so any help would be appreciated.
Updated Code:
function ptDataImport() {
var input = "https://reports.acc-q-data.com/clientreports/ecaldwell_201206192722/ecaldwell_2012062.txt";
var response = UrlFetchApp.fetch(input); // Get the data from the URL as an object.
var data = response.getContentText(); // Convet the object to text
var dataSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("pt"); // Get the sheet to write the data to
var rows = data.split('\n'); // Splits the text into rows
dataSheet.clear();
var dataSet = new Array();
for ( var i in rows){
dataSet[i] = rows[i].split('\t'); // Split the rows into individual fields and add them to the 2d array
}
dataSet.pop(); // Had a blank row at the bottom that was giving me an error when trying to set the range - need to make this conditional somehow
var numColumns = dataSet[0].length;
var numRows = dataSet.length;
var lastRow = dataSet[(numRows -1)];
dataSheet.getRange(1,1,numRows,numColumns).setValues(dataSet); // Get a range the size of the data and set the values
}
#Serge, I think Evan's question was different. Evan is concerned that the split does not take rows into consideration.
The solution to that is to use two splits. First,
var rows = data.split('\n');
And then
for ( var i in rows){
tmp = rows[i].split('\t'); // Use Serge's method if this doesn't work
/* Get the range here */
range.setValues([tmp]);
}
Range.setValues() takes a 2-D array as input.
I'm not sure what you want to do. If all you want to do is write data into a cell, then use this piece of code
ptSheet.getActiveRange().setValues([[data]]);
If you want to write each of the elements in data to a row in a spreadsheet, then you can use
var tmp = data.split(DELIMITER);
/* Get the correct range here */
range.setValues([tmp]);
Notice how you are creating a 2-D array in the first case and in the second case.
I guess the easiest thing to do is to convert those tabs in something else, commas for example, that's after all where the 'c' of csv comes from... you can then write it wherever you want.
Exemple :
commaString = tabString.replace(\t/g,',') ; should work but I'm not an expert in regEx... if I'm wrong someone will for sure correct it ;-)