Desenvolupament d'aplicacions amb App Inventor

Tutorial Exemples     Recursos CITCEA
Llibre Projectes Dades pràctiques   Inici

2- Preparem l'script

Podem crear un codi executable (anomenat script) que interactuï amb el nostre full de càlcul. Una manera senzilla d'executar aquest codi des de l'App Inventor és creant una funció que s'executi quan rep una ordre HTTP de tipus get. El nostre script tindrà, doncs, una adreça URL que ens permetrà executar-lo des de l'App Inventor.

En aquest exemple no pretenem entendre com està fet aquest codi ja que el nostre objectiu és fer aplicacions amb App Inventor i el llenguatge i l'entorn dels scripts s'aparta molt del nostre objectiu. Així, doncs, el que farem serà explicar com adjuntar l'script al nostre full de càlcul i després comentarem totes les accions que preveu.

En el nostre full de càlcul, anirem a la pestanya Extensions i triarem l'opció Apps Script. Se'ns obrirà una finestra similar a la següent:

Vista del programa

Hem d'esborrar la funció buida myFunction i deixar l'espai en blanc. Ara hem de copiar el nostrescript.

// Funció per interaccionar amb el full de càlcul des de l'App Inventor
// Oriol Boix, 2018
// Sota llicència Creative Commons BY-NC-ND
// https://creativecommons.org/licenses/by-nc-nd/3.0/deed.es_ES
//
// Aquesta funció està basada en una de Ferran Mas
//
// Les variables següents ens permeten personalitzar l'script al nostre projecte
// En principi, no hauríem de tocar la resta de l'script 
var IdFull = "1d0176v9_8iFIaPGe3DjKUPCl3KdT4bt8NTICcwEwl1U"; // Identificador del full de càlcul 
              // S'aconsegueix picant a Comparteix i triant Opcions avançades
var numFull = 0;  // Número del full amb el que hem de treballar
var numCols = 4;  // Nombre de columnes de treball que tenim al full de càlcul
var colId = 0;  // Columna que conté l'identificador de filera, la primera columna (A) és la 0
var colNom = 1;  // Columna que conté els noms que han de sortir en una llista del contingut

// Script per interactuar amb el full de càlcul
// Funció que s'executa quan hi ha una ordre get
// La nostra funció tindrà tres paràmetres:
      // accio    l'acció que s'ha de realitzar
      //          (get, comptar, llegir, consultar, afegir, modificar, esborrar, cercar)
      // id       l'identificador que (si cal) ens permet saber la filera sobre la que treballem
      // dades    les dades que s'han d'introduir en les caselles del full (en les accions en les que cal) 
function doGet(e) {
  // Assignem els paràmetres a variables
  var Accio = e.parameter.accio; 
  var Id = e.parameter.id; 
  var Dades = e.parameter.dades;
  if (Dades != undefined){
    var dades = Dades.split(';');  // Converteix la llista de dades en una matriu (array) 
  }                                // El separador és el ;
  var motcerca = dades[0].toLowerCase(); 
  var resul = "";
  // Obrim el full de càlcul
  var sh = SpreadsheetApp.openById(IdFull) ;
  var sheet = sh.getSheets();
  // Llegim les dades del full seleccionat
  var full = sheet[numFull].getDataRange().getValues();
  // Cerquem l'identificador demanat
  for(var i in full){    // Mirem totes les fileres usades
    var filera = full[i];    // Agafem una filera
    var ident = filera[colId];    // Agafem l'identificador de la filera
    // Ens preparem per a les accions de consultar i afegir
    if(Accio=="get"){
      if (i > 1){
        resul = resul + '\n';
      }
      if (i > 0){
        resul = resul + '"';
        for(var j = 0;j < numCols;j++){ 
          if (j > 0){
            resul = resul + ',"';
          }
          resul = resul + filera[j] + '"';
        }
      }
    }
    if(Accio=="llegir"){
      if (i > 0){
        resul = resul + '"' + filera[colId] + '","' + filera[colNom] + '"\n';
      }
    }
    if(Accio=="cercar"){
      var trobat = filera[colNom].toLowerCase().indexOf(motcerca);
      if (trobat >= 0){
        resul = resul + '"' + filera[colId] + '","' + filera[colNom] + '"\n';
      }
    }
    // Les accions afegir, modificar i esborrar necessiten trobar l'identificador
    if (ident == Id){  // S'ha trobat l'element
      if(Accio=="consultar"){
        var resultat = '"';
        for(var j = 0;j < numCols;j++){ 
          if (j > 0){
            resultat = resultat + ',"';
          }
          resultat = resultat + filera[j] + '"';
        }
      }
      if(Accio=="esborrar") {
        var fila =  parseInt(i)+1; 
        sheet[numFull].deleteRow(fila);   
        var resultat = 'Esborrada la filera amb Id = ' + Id;
      }
      if(Accio=="modificar") {
        var fila =  parseInt(i)+1; 
        // Anem a seleccionar el grup de caselles a modificar
        // Inici a filera seleccionada i columna 1, una sola filera i totes les columnes
        var rangeVal = sheet[numFull].getRange(fila, 1, 1, numCols);
        var valuesM = new Array(1);  // Creem una matriu d'una sola filera
        valuesM[0] = dades;  // Guardem les dades en format matriu
        rangeVal.setValues(values);  // Copiem la matriu a les caselles seleccionades
        var resultat = 'Modificada la filera amb Id = ' + Id;
      }
      // Si volíem afegir però ja existeix
      if(Accio=="afegir") {
        var resultat = "L'element amb Id = " + Id + ' ja existeix';
      }
      // Si no hem fet cap acció, generem un avís
      if (resultat == undefined){
        var resultat = 'Acció incorrecta';
      }  
      return ContentService.createTextOutput(resultat); 
    }
    var compta = i;
  }
  if((Accio=="get") || (Accio=="llegir") || (Accio=="cercar")){
    return ContentService.createTextOutput(resul); 
  }
  if(Accio=="comptar") {
    return ContentService.createTextOutput(compta); 
  }
  // Si no ha trobat l'identificador demanat (sinó ja hem tornat al return)
  // Ara podem afegir sense por a repetir
  if(Accio=="afegir")  {
    sheet[numFull].appendRow(dades);   // Afegeix una fila amb la llista de dades en format matriu 
    var resultat = 'Afegida la filera amb Id = ' + dades[colId];
    return ContentService.createTextOutput(resultat); 
  }
  // Si l'acció era modificar o esborrar i hem arribat aquí és que no s'ha trobat la filera demanada
  if((Accio=="modificar") || (Accio=="esborrar")){
    var resultat = "No s'ha trobat cap element amb Id = " + Id;
    return ContentService.createTextOutput(resultat); 
  }
  var resultat = 'Acció incorrecta';
  return ContentService.createTextOutput(resultat); 
}

Copiem tot el text i l'enganxem a la finestra de l'editor d'scripts. Un cop enganxat, haurem de fer-hi un canvi. En la imatge següent s'han requadrat aquelles línies pensades per a que es pugui personalitzar el programa. En el nostre exemple haurem de modificar la línia requadrada en vermell canviant el text entre cometes pel codi de la taula que hem trobat a l'apartat anterior. Els elements requadrats en blau no s'han de tocar per a l'exemple que farem però sí pot ser necessari tocar-los si aprofitem el programa per a altres aplicacions.

Vista del programa

Un cop personalitzat el programa l'hem de guardar, picant el botó que es mostra a continuació.

Botó guardar

Picarem el botó Implementar.

Implementar

En el desplegable triarem Nueva implementación i s'obrirà una finestra similar a la següent:

Nueva implementación

El primer cop que ho fem, haurem de picar en el botó que es mostra a continuació.

Tipus

I triar l'opció Aplicación web. La finestra ens preguntarà en nom de qui volem que s'executi l'aplicació (li direm Yo) i qui hi té accés (li direm que qualsevol usuari). Finalment, picarem el botó Implementar.

Nueva implementación

Se'ns mostrarà una pantalla en la que se'ns indicarà l'adreça URL de l'aplicació, que haurem de copiar.

URL script https://script.google.com/macros/s/^^fycbxqrJpVA-KT1sUd8HIta643R3bH4ixpDahttayGSGjkpHUBjPQ/exec

Un cop estiguem, podem picar el botó Listo.

Atenció: Hem de recordar que cal guardar el programa (botó del disquet) abans d'implementar, si no ho fem ens implementarà la darrera versió guardada que no serà l'actual.

Ara que ja tenim el nostre full de càlcul preparat, anem a comentar les possibilitats que ens ofereix aquest script, per després poder-les emprar des de l'App Inventor.

Primer comencem per les quatre variables que ens permeten personalitzar el codi. A la taula següent hi ha el seu nom i la descripció corresponent.

Variable Valor
exemple
Descripció
numFull 0 Número de full que fem servir, el primer és el 0
(poden haver-hi diversos fulls amb el mateix enllaç)
numCols 4 Nombre de columnes del full que fem servir
(si posem 4 treballarem amb les columnes que van de la 0 a la 3)
colId 0 Columna que correspon a l'identificador de filera
L'identificador de filera no pot estar repetit
En el nostre exemple hem agafat el DNI (columna 0)
colNom 1 Columna que conté el contingut principal
Aquesta columna es fa servir en les cerques i en altres accions
Nosaltres hem triat la columna dels noms de les persones (1)

La nostra funció té tres paràmetres però no són tots necessaris en totes les accions. La taula següent detalla quins són.

Paràmetre Descripció Necessari
accio Indica quina acció fem sobre la taula (afegir, modificar, etc.) Sempre
id Indica sobre quina filera fem l'acció, s'hi posa l'identificador de filera A totes les accions excepte get, comptar, llegir i cercar
dades Les dades necessàries per a l'acció A l'afegir i modificar són tots els camps de la taula, ordenats, separats per punt i coma
Al cercar són els caràcters de la cerca
A les altres accions no es fa servir

Aquests paràmetres els hem d'enviar codificats amb l'adreça URL de la funció. Anem a veure un exemple. Imaginem que anem a afegir un usuari amb les següents dades:

Paràmetre Valor
accio afegir
id 43455678M
dades 43455678M
Pere Rocamora
199
Carretera de l'Arrabassada, 23

En principi, la URL hauria de quedar així:

https://script.google.com/macros/s/AKfycbysb5cirzf08AzksvdF-tQ2wc3YMK3qGQJIgfiomwcMHqI3mvE/exec?accio=afegir&id=43455678M&dades=43455678M;Pere Rocamora;199;Carretera de l'Arrabassada, 23

La tornem a escriure partida en dues línies per veure-ho millor però ha d'estar tot el text seguit:

https://script.google.com/macros/s/AKfycbysb5cirzf08AzksvdF-tQ2wc3YMK3qGQJIgfiomwcMHqI3mvE/exec
	?accio=afegir&id=43455678M&dades=43455678M;Pere Rocamora;199;Carretera de l'Arrabassada, 23

Els scripts es poden provar amb el navegador web. Si posem l'adreça URL a la barra d'adreces del navegador obtindrem la resposta a la pantalla.

Observem que després de l'URL de l'script es posa un interrogant que indica l'inici dels paràmetres. Després del nom de cada paràmetre hi va el signe igual i el valor del paràmetre. Els paràmetres es separen amb el símbol &. En el cas de les dades, els camps es separen amb punt i coma.

Hem suposat que les dades no tenen el signe del punt i coma. Si n'hi hagués algun, seria interpretat com un separador de dades i, per tant, ens generaria cinc dades en lloc de quatre.

D'altra banda, les adreces URL no haurien de tenir espais en blanc ni alguns altres caràcters. El llenguatge HTML preveu uns codis per representar-los i aquests són els que emprarem. Els caràcters que hem detectat que podríem fer servir en un exemple com aquest i que convé canviar són els de la taula següent.

Caràcter Substitució
% %25
, %2C
  %20
' %27
. %2E
/ %2F
; %3B

Fixem-nos que aquests canvis no es poden fer en un ordre qualsevol. Atès que els codis de substitució comencen tots amb % és necessari fer primer la substitució d'aquest símbol. Si ho féssim més tard ens canviaria també els % dels codis i ens crearia una barreja impossible de processar.

Si es detecten més caràcters que donen problemes sempre es poden afegir a la llista de canvis a fer. Podem trobar la llista completa de codis en aquesta pàgina.

Per acabar, anem a veure quines són les accions possibles. La taula següent ens diu quina és la seva finalitat, els paràmetres necessaris i el que retorna.

Acció Finalitat Paràmetres Dades retornades
get Recupera tot el contingut de la taula Cap Una taula (llista de llistes) en format csv
comptar Compta quants elements (fileres)
té la taula
Cap Un text que conté el nombre de fileres
llegir Recupera l'identificador i el contingut
principal de tota la taula
Cap Una taula (llista de llistes) en format csv
consultar Recupera les dades d'una filera Identificador de la filera desitjada Una llista en format csv
afegir Afegeix una filera a la taula Identificador de la filera (comprova que no hi sigui)
Tots els camps de la taula, ordenats, separats per comes
Text: Afegida la filera amb Id = id
Text: L'element amb Id = id ja existeix
modificar Modifica una filera de la taula Identificador de la filera
(només modifica si el troba)
Tots els camps de la taula, ordenats, separats per comes
Text: Modificada la filera amb Id = id
Text: No s'ha trobat cap element amb Id = id
esborrar Esborra una filera de la taula Identificador de la filera que cal esborrar Text: Esborrada la filera amb Id = id
Text: No s'ha trobat cap element amb Id = id
cercar Cerca el text indicat al contingut principal Text que cal cercar Una taula (llista de llistes) en format csv
que pot contenir una, cap o diverses fileres
qualsevol altra Si no posem cap acció vàlida Indiferent Text: Acció incorrecta

Ara ja podem passar a l'AppInventor.

Aquí l'script no era el nostre objectiu sinó només un pas necessari. En cas que volgueu modificar l'script o crear-ne un de nou, en aquest altre espai web pots trobar informació sobre els scripts.

 

 

Llicència de Creative Commons
Aquesta obra d'Oriol Boix està llicenciada sota una llicència no importada Reconeixement-NoComercial-SenseObraDerivada 3.0.