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
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 a table of different prices in each rows. how do i make a sum of those rows in google docs and display it with "sum="?
Unit Name Description Price
<> <> <>
<> <> <>
sum=
I found this script and tested it.
function sumTable() {
var doc = DocumentApp.getActiveDocument();
var body = doc.getBody();
var tables = body.getTables();
var numRows = tables[0].getNumRows();//specify the table in [ ] that you're working with
var row;
var val;
var total = 0.0;
for(row = 1; row<numRows-1; row++) {
val = tables[0].getCell(row, 2).getText();
if(val) {
total += parseFloat(val);
}
}
tables[0].getCell(numRows -1,2).setText("$"+total.toString());
}
Now when you click “Run” in your Apps Script project it will execute and update the table, if you want to run the script from the Google Doc, you can run this other function and it will add an option under “Add-ons” from the Google Doc menu.
function onOpen(e) {
var menu = DocumentApp.getUi().createAddonMenu();
menu.addItem("Sum Table", "sumTable");
menu.addToUi();
}
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've got a String full of weblink image (23 links) :
listItem.text = String(item.movieimage);
If I do trace(String(item.movieimage)); the output is :
http://www.thewebsite.nc/Content/images/AFFICHES/xxx_3.jpg
http://www.thewebsite.nc/Content/images/AFFICHES/vaiana.jpg
http://www.thewebsite.nc/Content/images/AFFICHES/tous_scene.jpg
http://www.thewebsite.nc/Content/images/AFFICHES/fits.jpg
http://www.thewebsite.nc/Content/images/AFFICHES/boyfriend.jpg
http://www.thewebsite.nc/Content/images/AFFICHES/sahara2017.jpg
http://www.thewebsite.nc/Content/images/AFFICHES/resident_evil_final.jpg
http://www.thewebsite.nc/Content/images/AFFICHES/raid_dingue.jpg
http://www.thewebsite.nc/Content/images/AFFICHES/passengers2017.jpg
http://www.thewebsite.nc/Content/images/AFFICHES/lego_batman.jpg
http://www.thewebsite.nc/Content/images/AFFICHES/grande_muraille.jpg
http://www.thewebsite.nc/Content/images/AFFICHES/fille_brest.jpg
Know, I've got 9 UILoader on my stage.
So I would like to do
uiloader1.source = item.movieimage[1];
uiloader2.source = item.movieimage[2];
uiloader3.source = item.movieimage[3];
...etc...
How can I do that ?
Thanks
Assuming they're separated by an indent
//Put all the links in an array
var myItems:Array = listItem_txt.text.split("\n");
//You say you only have nine, so only iterate until the 9th
for (var i:int = 0; i < 9; i++)
{
//Also assuming your "uiloader" is a custom class you made with a .source property
this.getChildByName("uiloader" + i).source = myItems[i];
}
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...