Repeating a function down a list, without repeating code - google-docs

I've written a script in google docs to use =importXML function and return the value on its own rather than leaving the function there loading on opening and every hour slowing the thing down.
Basically it uses the data in row D (hidden), sticks the formula in B2, then, overwrites B2 with the value of the formula. I then wanted to repeat this going down the list but just didn't know how - currently I've just repeated the function and changed the cell ID, which I'm aware is a travesty. Could someone guide a noob on how to do it efficiently?
function pullValues()
{
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var cellref1 = sheet.getRange("D2");
var ID = cellref1.getValue();
var apistring = "http://api.eve-central.com/api/marketstat?usesystem=30000142&typeid=" + ID;
var command = "importxml(\"" + apistring + "\", \"/evec_api/marketstat/type/sell/min\")";
var cellref2 = sheet.getRange("B2");
cellref2.setFormula(command);
var val = cellref2.getValue();
cellref2.setValue(val);
}
https://docs.google.com/spreadsheet/ccc?key=0AjZlH_sGnj6vdDU4QWdyZTVTd2E4RUFXZnVEZlZJS3c#gid=0

You have to iterate through all rows in the spreadsheet using a for loop. There are many ways to do it, the following code is one of them:
function pullValues()
{
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getActiveSheet();
var startRow = 2; // First row of data to process
var lastRow = sheet.getLastRow(); // Last row of data to process
for (var i = startRow; i <= lastRow; i++)
{
var cellref1 = sheet.getRange("D" + i);
var ID = cellref1.getValue();
var apistring = "http://api.eve-central.com/api/marketstat?usesystem=30000142&typeid=" + ID;
var command = "=ImportXML(\"" + apistring + "\", \"/evec_api/marketstat/type/sell/min\")";
var cellref2 = sheet.getRange("B" + i);
cellref2.setFormula(command);
var val = cellref2.getValue();
cellref2.setValue(val);
}
}

Related

Get Last Column in Visible Views Index - Excel - Office-JS

I'm trying to filter the last column on a worksheet but I can't seem to get the Index of the column. To be clear, I need the index relative to the worksheet, no the range. I used VisibleView to find the Column, but there may be hidden rows, so my plan is to then load that column via getRangeByIndexes but I need the relative columnIndex to the worksheet.
I've tried a bunch of variations of the below, but I either get Object doesn't support 'getColumn' or columnIndex is undefined
Note: In the below example I've hardcoded 7 as that will be the last column relative to the VisibleView (Columns and rows are already hidden), but I'd like this to by dynamic for other functions and just returnthe "last visible column index".
var ws = context.workbook.worksheets.getActiveWorksheet()
var visible_rng = ws.getUsedRange(true).getVisibleView()
visible_rng.load(["columnCount", "columnIndex"])
await context.sync();
console.log('visible_rng.columnIndex')
console.log(visible_rng.getCell(0,7).columnIndex)
console.log(visible_rng.getColumn(7).columnIndex)
Well this method seems a bit hacky, please share if you know a better way! But, first thing I found was that getVisibleView only metions rows in the Description.
Represents the visible rows of the current range.
I decided to try getSpecialCells and was able to load the address property. I then had to use split and get the last column LETTER and convert this to the Index.
I also wanted the columnCount but this wasn't working w/ getSpecialCells so I polled that from getVisibleView and return an Object relating to Visible Views that I can build on the function later if I need more details.
Here it is:
async function Get_Visible_View_Details_Obj(context, ws) {
var visible_rng = ws.getUsedRange(true).getSpecialCells("Visible");
visible_rng.load("address")
var visible_view_rng = ws.getUsedRange(true).getVisibleView()
visible_view_rng.load("columnCount")
await context.sync();
var Filter_Col_Index = visible_rng.address
var Filter_Col_Index = Filter_Col_Index.split(",")
var Filter_Col_Index = Filter_Col_Index[Filter_Col_Index.length - 1]
var Filter_Col_Index = Filter_Col_Index.split("!")[1]
if (Filter_Col_Index.includes(":") == true) {
var Filter_Col_Index = Filter_Col_Index.split(":")[1]
}
var Filter_Col_Index = Get_Alpha_FromString(Filter_Col_Index)
var Filter_Col_Index = Get_Col_Index_From_Letters(Filter_Col_Index)
var Filter_Col_Index_Obj = {
"last_col_ws_index": Filter_Col_Index,
"columnCount": visible_view_rng.columnCount,
}
return Filter_Col_Index_Obj
}
Helper Funcs:
function Get_Alpha_FromString(str) {
return str.replace(/[^a-z]/gi, '');
}
function Get_Col_Index_From_Letters(str) {
str = str.toUpperCase();
let out = 0, len = str.length;
for (pos = 0; pos < len; pos++) {
out += (str.charCodeAt(pos) - 64) * Math.pow(26, len - pos - 1);
}
return out - 1;
}

Read column wise values using XLSX

How to read Column wise values from excel using nodejs(node-xlsx) ? Please advise.
I want to read Col A data, then Col B and so on, if any data exists in other columns, then put data in array.
I am able to read A1, B1, A2, B2... this way but not A1, A2, A3... then B1, B2, B3... etc.
Sample column wise data
I did custom way but not able to go to col C dynamically.
const xlsxfile = require("xlsx");
var arr = [];
const spreadsheet = xlsxfile.readFile('./Code.xlsx');
const sheets = spreadsheet.SheetNames;
console.log('Sheet Names -- ' + sheets);
const firstSheetName = sheets[0];
const firstSheet = spreadsheet.Sheets[firstSheetName];
console.log(firstSheet);
for (z in firstSheet) {
if (z[0] === '!') continue;
//parse out the column, row, and value
var tt = 0;
for (var i = 0; i < z.length; i++) {
if (!isNaN(z[i])) {
tt = i;
break;
}
};
var col = z.substring(0, tt);
var row = parseInt(z.substring(tt));
for (; ; row++) { // looping over all rows in a column
const firstCol = firstSheet[col+''+row];
if (!firstCol) {
break;
}
let value = firstCol.w;
//console.log(value);
if (value)
if (!arr.includes(value))
arr.push(value);
else
continue;
else
break;
}
}
console.log('final array = '+arr);
I somehow achieved my goal in very bad way. In top most loop it's always trying to get A1, B1, C1 like that. But in between I hijacked and looping all rows.
So in that way, I am keeping one track of what's my last column and comparing in next is same column or new column. if same column, I am existing.
But is there any better way to get all values may be in array format column wise?
const xlsxfile = require("xlsx");
var arr = [];
const spreadsheet = xlsxfile.readFile('./Code.xlsx');
const sheets = spreadsheet.SheetNames;
console.log('Sheet Names -- ' + sheets);
const firstSheetName = sheets[0];
const firstSheet = spreadsheet.Sheets[firstSheetName];
console.log(firstSheet);
let earliercol = []; // keeping a track
for (z in firstSheet) {
if (z[0] === '!') continue;
//parse out the column, row, and value
let tt = 0;
for (let i = 0; i < z.length; i++) {
if (!isNaN(z[i])) {
tt = i;
break;
}
};
let col = z.substring(0, tt);
let row = parseInt(z.substring(tt));
if (earliercol.includes(col)) // checking current col already traversed or not
break;
earliercol.push(col); // assigning current col name
//var value = worksheet[z].v;
for (; ; row++) {
//const firstCol = firstSheet['A' + i];
const firstCol = firstSheet[col+''+row];
if (!firstCol) {
break;
}
let value = firstCol.w;
//console.log(value);
if (value)
if (!arr.includes(value))
arr.push(value);
else
continue;
else
break;
}
}
console.log('final array = '+arr);

How to loop values in a Google Sheets Node.js script?

I need to insert values in the next row after executing this script. The difference between the rows is 13.
How I would I loop this script so that after execution, the values appear in the next row?
// Google Sheets API
const GoogleSpreadsheet = require('google-spreadsheet');
const {promisify} = require('util');
const creds = require('./client_secret.json');
var counter = 0; // Used to debug cellnumber association
// Define Spreadhseet Scope
const cells = await promisify(sheet.getCells)({
'min-row': 1,
'max-row': 106,
'min-col': 1,
'max-col': 13,
'return-empty': true
});
// Get a list of all the cells and relate them to a counter for assigning variables
for(const cell of cells){
counter++;
console.log(`${counter-1} -- ${cell.row}, ${cell.col}: ${cell.value}`);
}
/* Assign all variables to related spreadsheet cell */
cells[17].value = value + '%';
cells[17].save();
cells[18].value = value + '%';
cells[18].save();
cells[19].value = value+ '%';
cells[19].save();
cells[20].value = value+ '%' ;
cells[20].save();
cells[21].value = value+ '%';
cells[21].save();
cells[22].value = value + '%';
cells[22].save();
}
sendToGoogleSpreadsheet();

XPages typeahead takes too long

When we try typeahead with ftSearch , it takes too long to complete (to be shown on the screen). ftsearch finishes at the same time
[0D88:000B-0B44] 30.12.2015 10:03:06 HTTP JVM: Start= 30.12.2015 10:03
[0D88:000B-0B44] 30.12.2015 10:03:06 HTTP JVM: Finish= 30.12.2015 10:03
But in the inputbox which has typeahead properties results return more then 5 seconds. I mean It takes too long.
is there any suggestion how to decrease the time
'fldDefName = inthe inputbox there is a option for ftSearch named "Var" colNumber = Column Number for results. I generally user [0]
function getTypeAheadList(vName,frmName,fldName,fldDefName,colNumber)
{
var searchView:NotesView = database.getView(vName);'
var query = "(FIELD Form CONTAINS "+ frmName + " AND FIELD " + fldName + " CONTAINS *" + fldDefName +"*)";
print("Query= "+query);
var searchOutput:Array = ["å","åå"];
var hits = searchView.FTSearch(query);
var entries = searchView.getAllEntries();
var entry = entries.getFirstEntry();
for (i=0; i<hits; i++)
{
searchOutput.push(entry.getColumnValues()[colNumber]);
entry = entries.getNextEntry();
}
searchOutput.sort();
var result ="<ul><li><span class='informal'></span></li>";
var limit = Math.min(hits,50);
for (j=0; j<limit; j++)
{
var name = searchOutput[j].toString();
var start = name.indexOfIgnoreCase(lupkey)
var stop = start + lupkey.length;
name = name.insert("</b>",stop).insert("<b>",start);
result += "<li>" + name + "</li>";
}
result += "</ul>";
return result;
Reduce the number of docs that will be returned by FTSearch to 50 with
var hits = searchView.FTSearch(query, 50);
Right now the search result might contain e.g. 5000 docs and it takes time to push them into searchOutput and to sort. You reduce the hints afterwards to 50 anyway...

number of rows of an ft searched view

I've a view on which I performed a search. I would like to know how many rows this view has after this search. I tried with rows = view1.getEntryCount();
But this gives the number of lines of the "original" view, not the result of my search.
edit
The following works but isn't verry efficient.
Any better idea ?
productTest=sessionScope.get("product");
landTest=sessionScope.get("country");
var length = view1.getEntryCount();
var entries = view1.getAllEntries();
var i = 0;
var rows = 0;
var currentEntry = entries.getFirstEntry();
while(i < length){
land = currentEntry.getColumnValues().elementAt(0);
prod = currentEntry.getColumnValues().elementAt(1);
if (land == landTest & prod == productTest)
{
rows++;
}
currentEntry = entries.getNextEntry();
i++;
}
viewScope.queryString = rows; `
I found this on my blog. Try if if it still works:
var entryCount = viewData.getEntryCount();
var viewControl = getComponent( 'viewControlId' );
var rowCount = viewControl.getRowCount();
// If search is active -> rowcount, else entrycount
var count = ( viewControl.getDataSource().getSearch() ) ? rowCount : entryCount;
please try
rows = view1.getrowlines

Resources