Here is what I am doing basically.
var Player1:Object = {age:Number,playerName:String};//etc... I need each Player to have the same set of properties.
var Player2:Object = {age:Number,playerName:String};
var Player3:Object = {age:Number,playerName:String};
var Player3:Object = {age:Number,playerName:String};
Now, I have a LOT more properties in each object, and I am creating them all dynamically through for loops and arrays. So each object will have a random name, age, etc...
I hate that I have to write the same line of code over and over, the only thing changing is the number at the end of the word Player.
What I want is...
createPlayers(4);
function createPlayers(a){
for(var i=1;i<a;i++){
var thisPlayer = "Player" + i;
thisPlayer:Object = {age:Number,playerName:String};
}
Now, of course I cannot reference them because the var thisPlayer was created in the function.
I also tried:
Players:Object = {age:Number,playerName:String};
Player1:Players = new Players //OR
Player1:Object = new Players //ETC...
I am missing something here.
I want to assign a "Player1" Object to a "P1" var so the btnP1 can call upon it.
case btnP1:txt_name.text = P1.playerName;
case btnP2:txt_name.text = P2.playerName; //etc...
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 Tableviewcontroller BeamsNameVC with 2 variables: Name and number.
If for example, the number is 7, and if I click on any row in this View controller, it will segue to another TableViewcontroller SpansListVC and than it will show 7 rows: S1, S2, S3, S4, S5, S6 & S7.
I want to save these Data, so I created 2 swift files:
class StructureElement: NSObject, NSCoding {
var name = ""
var nbrSpans = ""
var spans = [LoadDetailsForEachSpan]()
and
class LoadDetailsForEachSpan: NSObject, NSCoding {
var i_SpanName = ""
var i_Spanlength = ""
var i_ConcentratedLoadForEachSpans = [ConcentratedLoadForEachSpan]()
I created a protocol with the following:
let spanNbr = Int(structureElement[newRowIndex].nbrSpans)
let newElementDetailSpan = LoadDetailsForEachSpan()
for i in 0...spanNbr! {
newElementDetailSpan.i_SpanName = "S" + " \(i)"
structureElement[newRowIndex].spans.append(newElementDetailSpan)
}
If i run the application, it will segue to * SpansListVC* but all values are the last i.
Example:
if name is Test 7 and number of span is 7, I will be having inside *[Spans] * 7 values with the same name:
spans[0] = S 7
spans[1] = S 7
....
Any mistake with above code?
Welcome to the hell that mutable data objects can be ;). You are creating a single LoadDetailsForEachSpan instance and add that same instance a number of times to the array, while setting the i_SpanName property of that same instance every time the loop is iterated. You probably want to pull the instance creation into the loop:
for i in 0...spanNbr! {
let newElementDetailSpan = LoadDetailsForEachSpan()
newElementDetailSpan.i_SpanName = "S" + " \(i)"
structureElement[newRowIndex].spans.append(newElementDetailSpan)
}
Thanks #thm for your reply.
however, i find another solution as follow and it works:
var spanDetailAndLoadItem: [SpanDetailsAndLoads] = []
for var i in 1...nbr! {
let item = SpanDetailsAndLoads(name: "S\(i) - S\(i + 1)")
spanDetailAndLoadItem.append(item)
}
self.spans = spanDetailAndLoadItem
How do you call a different function when a line of text from a TextField/TextArea is clicked?
I already have a function which retrieves a description when any point of the TextField is clicked:
list.text = "chicken";
list.addEventListener(MouseEvent.CLICK, getter);
var descriptionArray:Array = new Array();
descriptionArray[0] = ["potato","chicken","lemon"];//words
descriptionArray[1] = ["Round and Brown","Used to be alive","Yellow"];//descriptions
function getter(e:MouseEvent):void
{
for (var i:int = 0; i < descriptionArray.length; i++)
{
var str:String = e.target.text;//The text from the list textfield
if (str == descriptionArray[0][i]) //if the text from List is in the array
{
trace("found it at index: " + i);
description.text = descriptionArray[1][i];//displays "Used to be alive".
}
else
{
trace(str+" != "+descriptionArray[0][i]);
}
}
}
It works fine, and returns the correct description.
But I want it to instead retrieve a different description depending on what line in the TextField/TextArea was clicked, like, if I used list.text = "chicken\npotato"
I know I can use multiple textfields to contain each word, but the list might contain over 100 words, and I want to use the TextArea's scrollbar to scroll through the words in the list, and if I used multiple textfields/areas, each one would have its own scrollbar, which is pretty pointless.
So, how do I call a different function depending on what line I clicked?
PS: It's not technically a different function, it's detecting the string in the line that was clicked, I just put it that way for minimal confusion.
There are a few built-in methods that should make your life easier:
function getter(e:MouseEvent):void
{
// find the line index at the clicked point
var lineIndex:int = list.getLineIndexAtPoint(e.localX, e.localY);
// get the text at that line index
var itemText:String = list.getLineText(lineIndex).split("\n").join("").split("\r").join("");
// find the text in the first array (using indexOf instead of looping)
var itemIndex:int = descriptionArray[0].indexOf(itemText);
// if the item was found, you can use the sam index to
// look up the description in the second array
if(itemIndex != -1)
{
description.text = descriptionArray[1][itemIndex];
}
}
I have a Google Apps script which replaces placeholders in a copy of a template document with some text by calling body.replaceText('TextA', 'TextB');.
Now I want to extend it to contain images. Does anybody have idea how to do this?
Thank you,
Andrey
EDIT: Just to make it clear what my script does. I have a Google form created in a spreadsheet. I've created a script which runs upon form submission, traverses a sheet corresponding to the form, find unprocessed rows, takes values from corresponding cells and put them into a copy of a Google document.
Some fields in the Google form are multi-line text fields, that's where '\r\r' comes from.
Here's a workaround I've come up with by now, not elegant, but it works so far:
// replace <IMG src="URL"> with the image fetched from URL
function processIMG_(Doc) {
var totalElements = Doc.getNumChildren();
for( var j = 0; j < totalElements; ++j ) {
var element = Doc.getChild(j);
var type = element.getType();
if (type =='PARAGRAPH'){
var par_text = element.getText();
var start = par_text.search(new RegExp('<IMG'));
var end = par_text.search(new RegExp('>'));
if (start==-1)
continue;
// Retrieve an image from the web.
var url = getURL_(par_text.substring(start,end));
if(url==null)
continue;
// Before image
var substr = par_text.substring(0,start);
var new_par = Doc.insertParagraph(++j, substr);
// Insert image
var resp = UrlFetchApp.fetch(url);
new_par.appendInlineImage(resp.getBlob());
// After image
var substr = par_text.substring(end+1);
Doc.insertParagraph(++j, substr);
element.removeFromParent();
j -= 2; // one - for latter increment; another one - for increment in for-loop
totalElements = Doc.getNumChildren();
}
}
}
Here is a piece of code that does (roughly) what you want.
(there are probably other ways to do that and it surely needs some enhancements but the general idea is there)
I have chosen to use '###" in the doc to mark the place where the image will be inserted, the image must be in your google drive (or more accurately in 'some' google drive ).
The code below uses a document I shared and an image I shared too so you can try it.
here is the link to the doc, don't forget to remove the image and to put a ### somewhere before testing (if ever someone has run the code before you ;-)
function analyze() { // just a name, I used it to analyse docs
var Doc = DocumentApp.openById('1INkRIviwdjMC-PVT9io5LpiiLW8VwwIfgbq2E4xvKEo');
var image = DocsList.getFileById('0B3qSFd3iikE3cF8tSTI4bWxFMGM')
var totalElements = Doc.getNumChildren();
var el=[]
for( var j = 0; j < totalElements; ++j ) {
var element = Doc.getChild(j);
var type = element.getType();
Logger.log(j+" : "+type);// to see doc's content
if (type =='PARAGRAPH'){
el[j]=element.getText()
if(el[j]=='###'){element.removeFromParent();// remove the ###
Doc.insertImage(j, image);// 'image' is the image file as blob
}
}
}
}
EDIT : for this script to work the ### string MUST be alone in its paragraph, no other character before nor after... remember that each time one forces a new line with ENTER the Document creates a new paragraph.