I'm trying to use Office.JS to insert some rows into a table, there's more to it but i'll try to keep it simple.
The idea is to type details about a product on various inputs and then submit it to the table creating a full row with everything i've written.
The problem is that i don't know how can i make unique IDs on Office.JS, i thought about getting the last ID on the table then just do something like:
ID = lastID + 1
But i don't know how to get the value from the last ID on the table (the documentation it's just incredibly hard for me to understand)
This is what i did so far:
function run() {
return Excel.run(function(context) {
var sheet = context.workbook.worksheets.getItem('Principal');
var mainTable = sheet.tables.getItem("Main");
var local = $('#local').val();
var tipo = $('#tipo').val();
var modelo = $('#modelo').val();
var notas = $('#notas').val();
var lote = $('#lote').val();
var custo = $('#custo').val();
var preco = $('#preco').val();
var estado = $('#estado').val();
var produto = [data, id, local, tipo, modelo, notas, lote, custo, preco, estado];
var id = ""
mainTable.rows.add(null, [produto]);
return context.sync().then(function() {
console.log(produto);
});
});
}
Every column that i have in it's sequence:
Date
ID
Local
Tipo
Modelo
Notas
Lote
Custo
Preço
Estado
The weird names are just because i'm brazilian.
(First time asking a question here)
Since the IDs are in their own column, you can just programmatically insert an Excel formula in each cell of the first column that adds 1 to the value of the cell above it.
For how to programmatically add a formula to a cell, see Ranges: Set values or formulas.
Related
you see, I have this code, it works in the next way, after a form submit, the data goes to a sheet called Responses, that data is sent to another sheet in the same spreadsheet, this one is called Store, i'm using another coz as you know, once you delete for example the answer set on row 1 by the form, the next value is put on row two, but i need to read the first row, so in my code whenever the data is on responses, is sent to Store's first row, after that is compared in another sheet calleh Termo, then all the data that is filtered in thermo that exist on Store, is used to create a Slides presentation.
The problem is the next, i need to delete the row on Store after the slide is created, so when the next form is submited, the Store's first row is empty and can ''store'' the new value, my problem is that in some way, it deletes the data on Store first, and then when it creates the presentation slide, is empty, all this using on form submi trigger, but when i execute in the editor both separately, it works...
const PRESENTATION_ID = '1Xkbhk5UvEeCqu6NsBdRD41ysvxv4aW2-upKyVKYJboA'; //hacer variable para redireccionar al slides correcto
//Para generar historial
var SOURCE_SPREADSHEET_ID;
const TARGET_SPREADSHEET_ID = "1VELwR-qZMbUSsK3_VUmz8x2FRULSiOy0UvAMMHdhPE4";
const SOURCE_SHEET_NAME = "Responses";
const TARGET_SHEET_NAME = "HISTORIAL";
var Comparador;
//Fin de variables pala generar historial
function moveData() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var s = ss.getSheetByName("Responses"); // Nombre de la hoja
Absoluto = "1";
Comparador = "1";
SOURCE_SPREADSHEET_ID = "1VELwR-qZMbUSsK3_VUmz8x2FRULSiOy0UvAMMHdhPE4"
//NAME_COL_INDEX = 6;
//NAME_COL_INDEX2 = 12;
var cell1 = s.getRange('AU1');
var value1 = cell1.getValue();
var value2 = Absoluto;
var cell2 = s.getRange('B1');
//VAriables para el segundo manejo
//fin
if (value1==value2){
var ss = SpreadsheetApp.getActive();
var dailySheet = ss.getSheetByName('Responses');
var appendSheet = ss.getSheetByName('Store');
var values = dailySheet.getRange("Responses!2:" + dailySheet.getLastRow()).getValues();
values = values.filter(e=>e[0]); //gets rid of blank rows. filters based on the first column (index 0).
appendSheet.getRange(appendSheet.getLastRow()+1,1,values.length,values[0].length).setValues(values);
Utilities.sleep(8000);
}
}
function generatePresentationData(){
//let sheet = SpreadsheetApp.getActiveSheet();
let sheet = SpreadsheetApp.openByUrl("https://docs.google.com/spreadsheets/d/1VELwR-qZMbUSsK3_VUmz8x2FRULSiOy0UvAMMHdhPE4/edit?resourcekey&pli=1#gid=1218501416").getSheetByName("Termo");
let marketData = getDataFromSheet_(sheet);
let chartFromSheet = getChartsFromSheet_(sheet);
let slides = getSlides_();
let masterSlide = slides[1];
masterSlide.duplicate();
writeDataToMinutaSlide_(slides, marketData);
function getDataFromSheet_(sheet){
let dataRange = sheet.getDataRange();
let data = dataRange.getValues();
data.shift();
return data;
}
function getChartsFromSheet_(sheet){
let charts = sheet.getCharts();
let chart = charts[0];
return chart;
}
function getSlides_(){
let presentation = SlidesApp.openById(PRESENTATION_ID);
let slides = presentation.getSlides();
return slides;
}
function writeDataToMinutaSlide_(slides, marketData){
let slideMinuta = slides[1];
let moveSlide = slides[1];
moveSlide.move(3);
for (let index = 0; index < marketData.length;index++){
slideMinuta.replaceAllText(`{{Accion${index}}}`,marketData[index][56]);
slideMinuta.replaceAllText(`{{Respo${index}}}`,marketData[index][57]);
slideMinuta.replaceAllText(`{{Date${index}}}`,marketData[index][61]);
slideMinuta.replaceAllText(`{{Area}}`,marketData[index][4]);
slideMinuta.replaceAllText(`{{Estacion${index}}}`,marketData[index][74]);
slideMinuta.replaceAllText(`{{Fecha${index}}}`,marketData[index][62]);
slideMinuta.replaceAllText(`{{Responsable${index}}}`,marketData[index][2]);
slideMinuta.replaceAllText(`{{Problema${index}}}`,marketData[index][9]);
slideMinuta.replaceAllText(`{{Duracion${index}}}`,marketData[index][10]);
slideMinuta.replaceAllText(`{{A${index}}}`,marketData[index][39]);
slideMinuta.replaceAllText(`{{N${index}}}`,marketData[index][40]);
slideMinuta.replaceAllText(`{{M${index}}}`,marketData[index][41]);
slideMinuta.replaceAllText(`{{E${index}}}`,marketData[index][42]);
slideMinuta.replaceAllText(`{{L${index}}}`,marketData[index][43]);
slideMinuta.replaceAllText(`{{I${index}}}`,marketData[index][44]);
slideMinuta.replaceAllText(`{{É${index}}}`,marketData[index][45]);
slideMinuta.replaceAllText(`{{Image${index}}}`,marketData[index][19]);
slideMinuta.replaceAllText(`{{Causa${index}}}`,marketData[index][11]);
slideMinuta.replaceAllText(`{{Motivo${index}}}`,marketData[index][12]);
slideMinuta.replaceAllText(`{{Raiz${index}}}`,marketData[index][69]);
slideMinuta.replaceAllText(`{{Subcausa${index}}}`,marketData[index][67]);
slideMinuta.replaceAllText(`{{Pilar${index}}}`,marketData[index][68]);
}
}
}
var ss = SpreadsheetApp.getActive();
var dailySheet = ss.getSheetByName('Store');
var values = dailySheet.getRange("Store!1:" + dailySheet.getLastRow()).getValues();
values.reverse().forEach((r,i)=>{
if (r=='del'){
sheet.deleteRow(values.length-i+1);
}
});
var source = ss.getRange("Store!A1:AT");
source.clear();
Does anyone know a way to make the clear rows function after the generate presentationslide? This is the Slide I'm generating whitin the data on Store
I have been attempting to create a Telegram bot that searches a preexisting database and outputs information based on search query, essentially I want the bot to just receive a text via Telegram that contains an invoice number and output all relevant information regarding that order (The entire row of information).
Since I am dealing with invoice numbers and tracking numbers, sometimes the bot is exporting incorrect information given the current script is not matching exact text or a specific column.
For instance, rather than searching and finding invoice number it picks up a partial match of tracking number and outputs the wrong information.
I would like to set it up to search a specific column, ie. Column 3 - "Invoice #" and then output the entire row of information.
Thanks in advance!
I have been working in Google App Script:
var token = "";
var telegramUrl = "https://api.telegram.org/bot" + token;
var webAppUrl = "";
var ssId = "";
function getMe() {
var url = telegramUrl + "/getMe";
var response = UrlFetchApp.fetch(url);
Logger.log(response.getContentText());
}
function setWebhook() {
var url = telegramUrl + "/setWebhook?url=" + webAppUrl;
var response = UrlFetchApp.fetch(url);
Logger.log(response.getContentText());
}
function sendText(id,text) {
var url = telegramUrl + "/sendMessage?chat_id=" + id + "&text=" + text;
var response = UrlFetchApp.fetch(url);
Logger.log(response.getContentText());
}
function doGet(e) {
return HtmlService.createHtmlOutput("Hi there");
}
function doPost(e) {
var data = JSON.parse(e.postData.contents);
var text = data.message.text;
var id = data.message.chat.id;
var name = data.message.chat.first_name + " " + data.message.chat.last_name;
var answer = "Hi " + name + ", please enter invoice number.";
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Orders");
var search_string = text
var textFinder = sheet.createTextFinder(search_string)
var search_row = textFinder.findNext().getRow();
var value = SpreadsheetApp.getActiveSheet().getRange("F"+search_row).getValues();
var value_a = SpreadsheetApp.getActiveSheet().getRange("G"+search_row).getValues();
sendText(id,value+" "+ value_a)
}
You want to find rows where the content in column 3 is exactly equal to your variable "text"
Modify your function doPost as following:
function doPost(e) {
var data = JSON.parse(e.postData.contents);
var text = data.message.text;
var id = data.message.chat.id;
var name = data.message.chat.first_name + " " + data.message.chat.last_name;
var answer = "Hi " + name + ", please enter invoice number.";
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Orders");
var range = sheet.getRange(1,1, sheet.getLastRow(), sheet.getLastColumn());
var values = range.getValues();
for (var i=0; i< values.length; i++){
var column3Value = values[i][2];
if(column3Value == text){
var rowValues = values[i].toString();
sendText(id,rowValues)
}
}
}
Explanations
The for loop iterates through all rows and compares the values in column 3 (array element[2] against the value of text
The operator == makes sure that only exact matches are found (indexOf() would also retrieve partial matches)
In case a match is found, the values from the whole row are converted to a comma separated string with toString() (You can procced the values differntly if desired)
Every row with a match will be sent to the function sendText() (you could alternatively push all rows with matches into an array / string and call sendText() only once, after exiting the for loop
I hope this answer helps you to solve your problem and adapt the provided code snippet to your needs!
I would look for a specific column where the order number is stored.
I`m not sure if it is the best way from performance side, but I think it should work.
function orderInformation(orderNumber){
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Orders");
//Gets last row in Orders sheet
var lastRow = sheet.getLastRow();
//Here you can change column where is order number stored
var orderNumberRange = sheet.getRange("A1:A" + lastRow);
//Gets all order number values
var orderNumbers = orderNumberRange.getValues();
//You can use indexOf to find which row has information about requested order
var orderLocation = orderNumbers.indexOf(orderNumber);
//Now get row with order data, lets suppose that your order information is from column A to Z
var orderData = sheet.getRange("A" + (orderLocation + 1) + ":Z" + (orderLocation + 1)).getValues();
//Now you have all data in array, where you can loop through and generate response text for a customer.
}
Sorry, I have not tested it, at the moment I don`t have time to make a test sheet, but this is the way I would do it and I think it should work.
I will test it maybe later when I will be able to make a test sheet.
I have a spreadsheet with 2 tabbed sheets. I am trying to run a macro so that when the user inputs a name in B2 of the 2nd sheet, it is matched with every instance of that name in the 1st sheet, column B. I then need to copy all of the data that appears in the matched cell's rows and have that pasted in the 2nd sheet starting with cell B3.
I have limited experience with VBA, but none with JS/Google-apps-script. Any help with how to write this would be greatly appreciated! Here is my first shot:
function onSearch() {
// raw data sheet
var original = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Form Responses 2");
// search for student sheet
var filtered = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Student Progress Search");
// retrieving the values in the raw data array of names
var searchColumn = 2;
var lr = original.getLastRow();
var searchRange = original.getRange(2,searchColumn, lr, 1).getValues();
// retrieving the name submitted on search
var inputName = filtered.getRange(2, 2).getValue();
// loop through all the names in the raw data and identify any matches to the search name
for (var i = 0; i < lr; i++){
var dataValue = searchRange[i];
var r = dataValue.getRow();
var line = [[r]];
var paste = filtered.getRange(3, 3);
// if the data is a match, return the value of that cell in the searched sheet
if (dataValue == inputName){ return paste.setValues(line);
}
}
}
Not sure if the built-in QUERY function would work for you. This here does exactly what you are looking for:
=QUERY(Sheet1!B:B,"select B where LOWER(B) like LOWER('%" &B2& "%')")
For example, if a user enters 'joe', the function will match any entry containing 'joe', regardless of case.
I´m iterating through the rows of my DataTable with the example I found here in documentation but I want to get the data of the second column, analyze that value and then set my processed value on that cell.
tablaProgDetalle.rows().every( function ( rowIdx, tableLoop, rowLoop ) {
// I suppose here goes the processing and the setting of the cells values.
});
SOLUTION
You can use row().data() inside the anonymous function to get and set row's data. Please note that variable this in inside the anonymous function refers to row being iterated.
var table = $('#example').DataTable();
table.rows().every( function ( rowIdx, tableLoop, rowLoop ) {
var data = this.data();
data[0] = '* ' + data[0];
this.data(data);
});
DEMO
See this jsFiddle for code and demonstration.
You can use rowID to do this; we can set rowID in rowCreated: callback of Datatable, or manually while inserting rows upon table creation. Here I am incrementing 3rd column value upon some event in my project.
//DOM only addition
var rowID = your rowID goes here;
var cols = Table.row(rowID).data();
var count = parseInt(cols[2]);
count = count + 1
cols[2] = count.toString();
Table.row(rowID).data(cols);
Using the code below I'm able to look through multiple sheets in a spreadsheet to find the first value that equals the selected cell. The only problem with this bit is: The cell with the value found is highlighted yellow, but the cell with the value found isn't selected. See code below for hopping through sheets. I can't get my head around this :)
Funny thing is that the code for highlighting and selecting a value does work when I'm not hopping through the list of sheets, see the best answer: Find value in spreadsheet using google script
function SearchAndFind() {
//determine value of selected cell
var sh = SpreadsheetApp.getActiveSpreadsheet();
var ss = sh.getActiveSheet();
var cell = ss.getActiveCell();
var value = cell.getValue();
//create array with sheets in active spreadsheet
var sheets = SpreadsheetApp.getActiveSpreadsheet().getSheets();
//loop through sheets to look for value
for (var i in sheets) {
//Set active cell to A1 on each sheet to start looking from there
SpreadsheetApp.setActiveSheet(sheets[i])
var sheet = sh.getActiveSheet();
var range = sheet.getRange("A1");
sheet.setActiveRange(range);
//set variables to loop through data on each sheet
var activeR = cell.getRow()-1;
var activeC = cell.getColumn()-1;
var data = sheets[i].getDataRange().getValues()
var step = 0
//loop through data on the sheet
for(var r=activeR;r<data.length;++r){
for(var c=activeC;c<data[0].length;++c){
step++
Logger.log(step+' -- '+value+' = '+data[r][c]);
if(data[r][c]==''||step==1){ continue };
if(value.toString().toLowerCase()==data[r][c].toString().toLowerCase()){
sheet.getRange(r+1,c+1).activate().setBackground('#ffff55');
return;
}
}
}
}
}
This code is able to search across multiple sheets, it is obviously based on your published code but uses a memory (scriptProperties) to keep the search value 'alive' when changing from one sheet to the next one and to know when to search for it.
It has 2 non-optimal aspects : 1° you have to keep searching up to the last occurrence before you can begin a new search.
2° : when it switches from sheet n to sheet n+1 it first selects cell A1 before finding the value occurrence.
I guess it should be possible to get rid of these issues but right now I don't find how :-)
Maybe the approach is simply not the best, I started from a simple one sheet script modified and complexified... that's usually not the best development strategy (I know), but anyway, it was a funny experiment and a good logic exercise ...
Thanks for that.
function SearchAndFind() {
//determine value of selected cell
var sh = SpreadsheetApp.getActiveSpreadsheet();
var ss = sh.getActiveSheet();
var cell = ss.getActiveCell();
var value = cell.getValue();
if(ScriptProperties.getProperty('valueToFind')!=''){value = ScriptProperties.getProperty('valueToFind')};
//create array with sheets in active spreadsheet
var sheets = SpreadsheetApp.getActiveSpreadsheet().getSheets()
var sheetNumber = sheets.length;
var currentSheet = ss.getIndex()-1;
Logger.log(currentSheet);
//loop through sheets to look for value
for (var i = currentSheet ; i<sheetNumber ; ++i ){
Logger.log('currentSheet = '+i)
//Set active cell to A1 on each sheet to start looking from there
SpreadsheetApp.setActiveSheet(sheets[i])
// sheets[i].getRange(1,1).activate();
//set variables to loop through data on each sheet
var activeR = cell.getRow()-1;
var activeC = cell.getColumn()-1;
var data = sheets[i].getDataRange().getValues()
var step = 0;
//loop through data on sheet
for(var r=activeR;r<data.length;++r){
for(var c=activeC;c<data[0].length;++c){
step++
Logger.log('sheet : '+i+' step:'+step+' value '+value+' = '+data[r][c]);
if(data[r][c]==''||(step==1&&i==currentSheet)){ continue };
if(value.toString().toLowerCase()==data[r][c].toString().toLowerCase()){
sheets[i].getRange(r+1,c+1).activate().setBackground('#ffff55');
ScriptProperties.setProperty('valueToFind',value);
return;
}
}
}
cell = sheets[i].getRange(1,1);
}
ScriptProperties.setProperty('valueToFind','');
Logger.log('reset');
}