Configurazione script per task

Il task da eseguire viene definito attraverso uno script in linguaggio Visual Basic.NET (VB.NET).

Nello script è possibile utilizzare primitive specifiche per il trasferimento dati da altri database, che nelle release precedenti alla 2015.17.2c era necessario programmare attraverso il servizio QDaemon il quale era basato sulla piattaforma client/server, facendo uso del linguaggio dBase.

Le primitive consentono di specificare la definizione della mappatura dei campi della tabella da trasferire in una modalità del tutto simile a quella utilizzata nella precedente versione di QDaemon, rendendo anche più semplice la migrazione di script esistenti alla piattaforma web.

Tale definizione della mappatura viene effettuata attraverso l’oggetto QDaemonTableDef.
Una volta assegnato l’oggetto QDaemonTableDef, è necessario richiamare l’apposita primitiva di importazione, che ha la seguente sintassi:

QDaemonImportTable(<oggetto database>,<nome tabella>,<oggetto TableDef>)dove:

  • <oggetto database> è l’oggetto contenente il database rappresentato dalla variabile DB,
  • <nome tabella> è una stringa contenente un nome convenzionale assegnato alla tabella/file da importare e può essere assegnato arbitrariamente,
  • <oggetto QDaemonTableDef> e l’oggetto di tipo QDaemonTableDef contenente la definizione della tabella/file da importare e la mappatura dei campi.

La primitiva QDaemonImportTable registra gli eventi sulla tabella LOGDOC con CODDOC=’QDAEMON’. Per verificare l’esito delle importazioni ed eventuali errori si può utilizzare la funzionalità Consultazione LOG QualiWare Server Daemon selezionando l’opzione “Qdaemon”.

 

Note sui CodeBlock

I CodeBlock possono essere utilizzati sia nella definizione dei campi sia nella proprietà AfterSave. Le sintassi da utilizzare sono però diverse.
Nel primo caso, il CodeBlock può essere scritto in due modi:

.campi("INVOICE_MONTH")=Function (oFlds,oFldsQ) val(oFlds("INVOICE_MONTH").value)

oppure

.campi("INVOICE_MONTH")=Function (oFlds,oFldsQ) 
                             return val(oFlds("INVOICE_MONTH").value)
                         End Function

La differenza fra le due sintassi consiste nel fatto che la prima può essere usata se il calcolo consiste in una sola funzione, la quale può essere specificata direttamente dopo la parola chiave “Function” senza necessità di specificare “Return”. La seconda invece deve essere utilizzata quando il calcolo richiede più istruzioni, e dovrà essere utilizzata la parola chiave “Return” per restituire il risultato.
Si noti che la specifica del parametro “oFldsQ” non è obbligatoria.

Nel caso della proprietà AfterSave, il CodeBlock non deve ritornare un valore, e la sintassi da utilizzare in quel caso sarà come la seguente:

tabella.AfterSave=Sub (oTbl)
                     oTbl.replace("DESCREXT",oTbl.rowset.fields("DESCRIZION").value)
                     oTbl.saverecord()
                  End Sub

 

Esempi

Di seguito sono riportati alcuni esempi di script di importazione.

Importazione da una query, con AfterSave

dim tabella as new QDaemonTableDef
tabella.gest_sql="select 'Z'+CODICE as CODICE, DESCRIZION, UNMIS, TIPO, UNCAMP from ARTIC where CODICE like 'ZZZ%'"
tabella.q95_name="ARTIC"
tabella.keys=new dbarray("CODICE")

with tabella
 .campi("CODICE")="CODICE"
 .campi("DESCRIZION")="DESCRIZION"
 .campi("UNMIS")="UNMIS"
 .campi("TIPO")="TIPO"
 .campi("UNCAMP")=Function (oFlds) 1
end with

tabella.AfterSave=Sub (oTbl)
                     oTbl.replace("DESCREXT","AfterSave")
                     oTbl.saverecord()
                  End Sub

QDaemonImportTable(DB,"ARTIC",tabella)

 

Importazione da file CSV delimitato da virgola, senza intestazioni e con doppi apici

dim tabella as new QDaemonTableDef

tabella.gest_name="\\server\csv\Turnover.txt"
tabella.Gest_Separator="Delimited(,)"
tabella.gest_ColumnNames=new dbarray("INVOICE_YEAR","ITEM_GROUP","PRODUCT_LINE","INVOICE_MONTH","COUNTRY_CODE","CUSTOMER_CODE","CUSTOMER_NAME","ITEM_CODE","ITEM_DESCRIPTION","QUANTITY","TURNOVER","COST_OF_SALES","MARGIN","EXTERNAL_SALES_REP","BUSINESS_UNIT_CODE","BUSINESS_UNIT_NAME") 
tabella.q95_name="P_TURNOVER"
tabella.gest_CharacterSet="ANSI"
tabella.keys=new dbarray("INVOICE_YEAR","INVOICE_MONTH","CUSTOMER_CODE","ITEM_CODE","PROV")

with tabella
 .campi("INVOICE_YEAR")= (Function (oFlds) val(oFlds("INVOICE_YEAR").value)) 
 .campi("ITEM_GROUP")="ITEM_GROUP"
 .campi("PRODUCT_LINE")="PRODUCT_LINE"
 .campi("INVOICE_MONTH")=Function (oFlds,oFldsQ) val(oFlds("INVOICE_MONTH").value) 
 .campi("COUNTRY_CODE")="COUNTRY_CODE"
 .campi("CUSTOMER_CODE")=Function (oFlds) "C"+substr2(oFlds("CUSTOMER_CODE").value,4) 
 .campi("CUSTOMER_NAME")="CUSTOMER_NAME"
 .campi("ITEM_CODE")="ITEM_CODE" ' Chiave
 .campi("ITEM_DESCRIPTION")="ITEM_DESCRIPTION"
 .campi("QUANTITY")=Function (oFlds) val(oFlds("QUANTITY").value)
 .campi("TURNOVER")=Function (oFlds) val(oFlds("TURNOVER").value)
 .campi("COST_OF_SALES")=Function (oFlds) isnull(val(oFlds("COST_OF_SALES").value),0)
 .campi("MARGIN")=Function (oFlds) isnull(val(oFlds("MARGIN").value),0)
 .campi("EXTERNAL_SALES_REP")="EXTERNAL_SALES_REP"
 .campi("PROV")=Function () 0
end with

QDaemonImportTable(DB,"P_TURNOVER",tabella)

 

Importazione da file CSV, delimitato da Tab e con intestazioni

dim tabella as new QDaemonTableDef
tabella.gest_name="\\server\csv\artic.csv"
tabella.Gest_Separator="TabDelimited"
tabella.q95_name="ARTIC"
tabella.keys=new dbarray("CODICE")

with tabella
 .campi("CODICE")="CODICE"
 .campi("DESCRIZION")="DESCRIZION"
 .campi("UNMIS")="UNMIS"
 .campi("TIPO")=Function (oFlds) val(oFlds("TIPO").value)
 .campi("UNCAMP")=Function (oFlds) val(oFlds("UNCAMP").value)
end with

QDaemonImportTable(DB,"ARTIC",tabella)

 

Importazione da file CSV delimitato da Tab e senza intestazioni

dim tabella as new QDaemonTableDef

tabella.gest_name="\\server\csv\Turnover.txt"
tabella.Gest_Separator="TabDelimited"
tabella.gest_ColumnNames=new dbarray("INVOICE_YEAR","ITEM_GROUP","PRODUCT_LINE","INVOICE_MONTH","COUNTRY_CODE","CUSTOMER_CODE","CUSTOMER_NAME","ITEM_CODE","ITEM_DESCRIPTION","QUANTITY","TURNOVER","COST_OF_SALES","MARGIN","EXTERNAL_SALES_REP","BUSINESS_UNIT_CODE","BUSINESS_UNIT_NAME")
tabella.q95_name="P_TURNOVER"
tabella.keys=new dbarray("INVOICE_YEAR","INVOICE_MONTH","CUSTOMER_CODE","ITEM_CODE","PROV")

with tabella
 .campi("INVOICE_YEAR")= (Function (oFlds) val(oFlds("INVOICE_YEAR").value)) ' Chiave
 .campi("ITEM_GROUP")="ITEM_GROUP"
 .campi("PRODUCT_LINE")="PRODUCT_LINE"
 .campi("INVOICE_MONTH")=Function (oFlds,oFldsQ) val(oFlds("INVOICE_MONTH").value) ' Chiave
 .campi("COUNTRY_CODE")="COUNTRY_CODE"
 .campi("CUSTOMER_CODE")=Function (oFlds) "C"+substr2(oFlds("CUSTOMER_CODE").value,4) ' Chiave
 .campi("CUSTOMER_NAME")="CUSTOMER_NAME"
 .campi("ITEM_CODE")="ITEM_CODE" ' Chiave
 .campi("ITEM_DESCRIPTION")="ITEM_DESCRIPTION"
 .campi("QUANTITY")=Function (oFlds) val(oFlds("QUANTITY").value)
 .campi("TURNOVER")=Function (oFlds) val(oFlds("TURNOVER").value)
 .campi("COST_OF_SALES")=Function (oFlds) isnull(val(oFlds("COST_OF_SALES").value),0)
 .campi("MARGIN")=Function (oFlds) isnull(val(oFlds("MARGIN").value),0)
 .campi("EXTERNAL_SALES_REP")="EXTERNAL_SALES_REP"
 .campi("PROV")=Function () 0
end with

QDaemonImportTable(DB,"P_TURNOVER",tabella)

 

Importazione di dati tramite WebService

' Il seguente frammento di codice fornisce un esempio di come sia possibile acquisire informazioni da un 
' un servizio esterno di rilevazione dati tramite la chiamata ad un WebService utilizzando una URL che restituisce una stringa XML.
' Nella fattispecie, viene utilizzato il Web Service messo a disposizione dal sistema di monitoraggio dei 
' pannelli fotovoltaici SolarEdge )

' L'output è il seguente:
' <series>
'    <timeUnit>HOUR</timeUnit>
'    <unit>Wh</unit>
'    <measuredBy>INVERTER</measuredBy>
'    <values>
'      <dateValue>
'         <date>2017-05-08 00:00:00</date>
'         <value>0.0</value>
'      </dateValue>
' ....
'    </values>
' </series>

' I dati vengono recuperati su base giornaliera (per il giorno corrente) e memorizzati nella tabella IOTLOG
Dim Q as new QWTable
Q.Database=DB
Q.sql="select * from IOTLOG"
Q.allowallrecords=false
Q.active=true

Dim d as string=ltrim(dbase.str(Today.Year))+"-"+ltrim(dbase.str(Today.Month))+"-"+ltrim(dbase.str(Today.Day))
Dim url As String = "https://monitoringapi.solaredge.com/site/349661/energy.xml?timeUnit=HOUR&endDate="+d+"&startDate="+d+"&api_key=KDZ46QJYX2HQPIVPJY7KX3R9HA7ULNRG" 

Dim webClient As New System.Net.WebClient
Dim result As String = webClient.DownloadString(Url)

' Recupero della risposta
Dim response = System.XML.Linq.XElement.Parse(result)

for each el as System.XML.Linq.Xelement in response.LastNode.Nodes ' Il LastNode è "Values", e ne estrae tutti i nodi
 ' Il quarto nodo è quello dei Values
 Dim Data As String
 Dim Valore as String

 Data=Ctype(el.FirstNode,System.Xml.Linq.Xelement).Value
 dim da as System.datetime=System.Datetime.parse(data)
 Valore=Ctype(el.LastNode,System.Xml.Linq.Xelement).Value 

 if Valore<>"null"
    if not q.rowset.findkey(da,"SOLAR","SITE1")
    q.beginappend()
    q.replace("DATA",da)
    q.replace("DEVICENAME","SOLAR")
    q.replace("SENSORNAME","SITE1")
 End If

 q.replace("VALUE",val(Valore))
 q.saverecord()
 End If 
next

Q.active=false