Caricare un foglio di GoogleDocs da IBMi via Rest WebServices

0
169

Google DocsLa possibilità di pubblicare Rest Web Services dalle ultime PTF della 7.1 e 7.2 apre un mondo di possibilità …  come, ad esempio, caricare uno SpreadSheet di Google Docs con un programma RPG via Rest WebService.

Lascio immaginare a voi le strade che apre una cosa come questa : inserire dati in un foglio di GDocs e caricarli su IBMi (il budget ? l’order entry ? un listino prezzi o che altro vogliate caricare) … oppure costruirsi un foglio di Gdocs con una serie di codici (articoli, clienti, agenti …) e compilarne gli attributi richiamando un “normale” programma RPG …

Stimolato l’interesse ? Spero di sì … continua a leggere la procedura passo passo riportata qui di seguito.

Passo 1: Creazione di un sorgente del Service Program

Per prima cosa faccio un piccolo Service Program che riceve in ingresso due parametri “From” e “To” e ritorna una “schiera” di elementi “codice”-“descrizione”-“prezzo” … per facilitare i test il codice messo a disposizione crea una tabella temporanea nella QTEMP che poi ritorna … naturalmente ci mettete la vostra logica dentro !

ctl-opt nomain pgminfo(*pcml:*module);
ctl-opt bnddir('XSERVRMS') ;
//-----------------------------------------------------------------------*
// TSGETITEM Test Webservice: Get Item from IBMi to GoogleDocs
// Spreadsheets
//-----------------------------------------------------------------------*
dcl-c Http_Ok const(200);
dcl-c Http_NotFound const(404);
dcl-ds brarti extname('BRARTI0F') end-ds;
dcl-ds Itemsds qualified template;
Id char(15);
Desc char(10);
Price packed(21:4);
end-ds;
dcl-ds items likeds(Itemsds) dim(1000);
dcl-s i int(5);
dcl-s Id char(15);
dcl-s Desc char(50);
dcl-s Price packed(15:4);
//-----------------------------------------------------------------------*
//Procedure ts_itemsget
//-----------------------------------------------------------------------*
DCL-PROC ts_itemsget export;
dcl-pi ts_itemsget;
i_from char(100) ;
i_to char(100) ;
o_nrofelements int(5);
o_ds likeds(Itemsds) dim(1000) options(*varsize);
o_error char(100);
httpStatus int(10);
httpHeaders char(100) dim(10);
end-pi;
// Gestione dei servizi del WS
clear o_error;
clear o_ds;
o_nrofelements=1;
clear items;
clear i;
// Create an example for All-About-i.info
// I create a temporary table only for example
// you can read your file/table or everything else
// as a normal RPG programm
Create_example();
exec sql
declare c1 cursor for
select *
from QTEMP/ITEMS
where id between :i_from and :i_to
order by id;
exec sql open c1;
dow 1=1;
exec sql fetch c1 into :Id, :Desc, :Price;
if sqlcod<>0;
exec sql close c1;
leave;
ENDIF;
i+=1;
items(i).id=Id;
items(i).desc=Desc;
items(i).price=Price;
ENDDO;
select;
when i=0;
o_error='ERROR - No Items found';
httpStatus=Http_NotFound;
other;
httpStatus=Http_Ok;
O_NrOfElements=i;
o_ds=items;
ENDSL;
return;
END-PROC;
DCL-PROC Create_Example;
exec sql
CREATE or REPLACE TABLE QTEMP/ITEMS
(ID char(10), desc char(100), price dec(15 , 4));
exec sql
delete from QTEMP/ITEMS
where 1=1;
exec sql
INSERT INTO QTEMP/ITEMS
(ID, desc, price)
VALUES('A001', 'Apple Iphone 6', 700);
exec sql
INSERT INTO QTEMP/ITEMS
(ID, desc, price)
VALUES('A002', 'Apple Iphone 6S', 800);
exec sql
INSERT INTO QTEMP/ITEMS
(ID, desc, price)
VALUES('S001', 'Samsung S6 32GB', 639);
exec sql
INSERT INTO QTEMP/ITEMS
(ID, desc, price)
VALUES('S002', 'Samsung S6 EDGE', 739);
END-PROC;

 

Passo 2: Creazione di un sorgente per Il Bind per le funzioni esportare dal SRVPGM

STRPGMEXP SIGNATURE('TS_ITEMS L.1')
export symbol(ts_itemsget)
ENDPGMEXP

 

Passo 3: Compilare Modulo e Service Program

CRTSQLRPGI OBJ(mylib/TS_ITEMS) SRCFILE(mylib/mysrcpf) SRCMBR(TS_ITEMS) OBJTYPE(*MODULE) OPTION(*EVENTF) REPLACE(*YES) DBGVIEW(*SOURCE)
CRTSRVPGM SRVPGM(mylib/TS_ITEMS) MODULE(TS_ITEMS) EXPORT(*SRCFILE) SRCFILE(mylib/mysrcpf) SRCMBR(TS_ITEMSBN) ACTGRP(*CALLER)
 

 

Passo 4: Pubblicare Rest Web Service tramite “IBM Web Administration for i”

Loggarsi sul Web Administration for i

http://myibmi:2001/HTTPAdmin

e seguire i vari passi di pubblicazione del Rest Web Service …

 

IBM WebAd4i 01IBM WebAd4i 02

IBM WebAd4i 03

IBM WebAd4i 04

IBM WebAd4i 06

IBM WebAd4i 07

IBM WebAd4i 08

IBM WebAd4i 09

IBM WebAd4i 10

 

Per gestire il numero corretto di elementi ritornati da un array … definito a livello RPG di un numero fisso (e grande) di elementi … sflaggare l’apposito flag “Detect length fields” e dichiarare la variabile di ouput che ritorna il numero di elementi validi …. ciò permette di avere un json di uscita con i soli elementi valorizzati senza i campi vuoti.

restservice step 4x

Passo 5: Testare il Rest Web Service

Per testare il Web Service è possibile a soluzioni come SOAP-UI o più semplicemente con le estensioni di Chrome come Advante Rest Client App for Chrome

Test Rest WS 01

Test Rest WS 02

 

Passo 6: Creare un foglio di Google Docs ed utilizzare l’editor Google Script Editor

Gdocs 01

Gdocs 02

Inserire questo script che crea all’apertura del documento un apposito menu con una funzione che chiama il Rest Web Service su IBMi passandogli i limiti From/To e ottenendo un griglia in formato Json…. che leggiamo con le funzioni native di Google Script

// This script works with the Brackets Test spreadsheet to create a tournament bracket
// given a list of players or teams.
var RANGE_START = 'FirstCell';
var RANGE_FROM = 'From';
var RANGE_TO = 'To';
var SHEET_ITEMS = 'Items';
var CONNECTOR_WIDTH = 15;
// This method adds a custom menu item to run the script
function onOpen() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
ss.addMenu("Get Data From IBMi",
[{ name: "Get Items", functionName: "getItems" }]);
}
// Get a list of items from IBMi
function getItems() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheetItems = ss.getSheetByName(SHEET_ITEMS);
var rangeStart = ss.getRangeByName(RANGE_START);
var rangeFrom = ss.getRangeByName(RANGE_FROM);
var rangeTo = ss.getRangeByName(RANGE_TO);
var sheetItems = ss.getSheetByName(SHEET_ITEMS);
// Get the range
var From = rangeFrom.getValue();
var To = rangeTo.getValue();
var Maxelements=100;
var OffsetRow=rangeStart.getRowIndex();
//for (var i = 0; i < Maxelements; i++) {
// var rng=sheetItems.getRange(i+OffsetRow, 1);
// rng.setValue(From);
// var rng=sheetItems.getRange(i+OffsetRow, 2);
// rng.setValue(To);
// }
var url = 'http://myesternalIP:10010/web/services/TS_ITEMS'
+ '/'+From
+ '/'+To;
var response = UrlFetchApp.fetch(url);
//Logger.log(response);
var json = response.getContentText();
//Logger.log(json);
var data = JSON.parse(json);
Logger.log(data.o_DS[0].ID);
//Browser.msgBox(data.O_DS.Items(1));
i=0;
var o_NROFELEMENTS=data.o_NROFELEMENTS;
Logger.log(o_NROFELEMENTS);
for (var i = 0; i < o_NROFELEMENTS; i++) {
var ItemID=data.o_DS[i].ID.toString().replace(' ', '');
var ItemDesc=data.o_DS[i].DESC;
var ItemPrice=data.o_DS[i].PRICE;
var r=i+OffsetRow;
var c=1;
var rng=sheetItems.getRange(r, c);
rng.setValue('\'' + ItemID);
c=c+1;
var rng=sheetItems.getRange(r, c);
rng.setValue(ItemDesc);
c=c+1;
var rng=sheetItems.getRange(r, c);
rng.setValue(ItemPrice);
}
}

 

Passo 7: Vediamo se funziona … Funziona!

Chiudiamo e riapriamo il foglio di Gdocs per attivare la funzione di script che aggiunge un nuovo menu alla barra dei comandi … eseguiamo il comando ed ecco compilate alcune celle dello SpreadSheet Gdocs con i dati ottenuti dal nostro programma RPG da IBMi ! Fantastico !

 

Gdocs 03

Gdocs 04