Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Sisällysluettelo

Table of Contents

Yleistä

SKJScript on SKJ:n oma 'ohjelmointiympäristö'.

...

  • csv -tiedoston käsittely
  • csv -tiedoston tuonti apu
  • Ftp -siirrot
  • Sähköpostin lähetys
  • SQL -kyselyt
  • Winskj -taulukäsittely
  • Xml -käsittely
  • Sisäänrakennettu debuggeri
  • Merkkijonojen ja numeroiden käsittely

Ohjelman komentoriviparametrit

Ohjelma ymmärtää vakiona seuraavat komentoriviparametrit:

...

Scriptikohtaisesti voidaan määritellä omia parametrejä.

Ohjelman asetukset

Ohjelma tarvitsee varsinaisesti yhden asetustiedoston, skjscript.ini:n, jossa kerrotaa lisenssin sijainti. Skjscript.ini:n pitää sijaita samassa kansiossa kuin käynnistettävä skjscript.exe.

Code Block
[SKJSCRIPT]
LISENSSITIEDOSTO=C:\winskj\files\lisenssi.xml

Funktio ja aliohjelmalista

Dokumentoinnissa on funktioiden ja muuttujien tyypit näytetty, vaikka ei tarvitsisi.
Tämä on selvyyden vuoksi, jotta esim. tietokantamuuttujan asemasta ei laitettaisi merkkijonoa.

  • Abs - palauttaa itseisarvon f:= abs(f);
  • Append - avaa tekstitiedoston ja siirtää kirjoituskohdan perään
  • Assigned - Palauttaa TRUE jos parametri <> nil
  • AssignFile - määrittää tiedostomuuttujan. assignfile(f, 'koe.txt');
  • Beep - piip
  • Chdir - vaihtaa hakemiston
  • Chr -palauttaa ascii -koodia vastaavan merkin esim. s := 'testi'chr(13)+chr(10)'data';
  • CloseFile - sulkee tiedoston
  • Copy - kopioi osan merkkijonosta copy('suomen kassajärjestelmät, 7,5) -> 'kassa'
  • Cos - cosini, erittäin tarpeellinen toimialalle ja paljon käytetty mm. myyntien laskennassa. (vitsi...)
  • CreateOleObject
  • EOF - eof(tiedostomuuttuja) - true jos tiedosto loppu
  • Exp
  • FilePos - peräkkäistiedoston luku/kirjoituspaikan sijainti
  • FileSize - tiedoston koko
  • FloatToStr - liukuluku merkkijonoksi
  • Format - muotoilee dataa
  • FormatFloat - muotoilee liukulukua
  • Frac - luvun desimaaliosa
  • GetActiveOleObject
  • High - taulukon korkein indeksi
  • IncMonth - kasvatetaan päiväystä kk määrällä
  • InputQuery - kysyy yksinkertaisella dialogilla merkkijonon
  • Insert - lisää keskelle merkkijonoa
  • Int - muutta liukuluvun kokonaisluvuksi (tyyppi = integer)
    *Interpret (star)
  • IntToHex muutaan integerin hexaksi
  • IntToStr muutaan integerin merkkijonoksi
  • IsValidIdent
  • Length - merkkijonon pituus
  • Ln - luonnollinen logritmi
  • Low - taulukon alin elementti
  • LowerCase - merkkijono pienille kirjaimille
    *Machine (star)
  • Odd
  • Ord
  • Pyorista - pyöristää luvun pyorista(luku,-2) pyöristää 2 desimaaliin. Jos pyorista(luku,2) pyöristää lähimpään sataan.
  • PyoristaSentit - pyöristää annetun luvun senttisääntöjen mukaan (ylös tai alas 0/5 senttiä).
  • Raise
  • Random
  • ReadLn
  • Reset
  • Rewrite
  • Round
    *Scripter (star)
    *SetOf (star)
  • ShowMessage
  • Sin
  • Sqr
  • Sqrt
  • VarArrayCreate
  • VarArrayHighBound
  • VarArrayLowBound
  • VarIsNull
  • VarToStr
  • Write
  • WriteLn

Merkkijono

  • AnsiCompareStr
  • AnsiCompareText
  • AnsiLowerCase
  • AnsiUpperCase
  • CompareStr
  • CompareText
  • Delete
  • StrToFloat
  • StrToInt
  • StrToIntDef
  • Trim
  • TrimLeft
  • TrimRight
  • Trunc
  • UpperCase
  • AnsiUpperCase

...

Katso myös CSV_Tuonti.htm esimerkki.

Numerot

  • Arc
  • Tan
  • Dec
  • Inc
    • Lisää yhden muuttujaan, esim Inc(count)
  • Pyorista(Luku; tarkkuus)
    • Pyöristää luvun annettuun tarkkuuteen, esim -2 -> 2 desimaaliin, 2 = lähimpään 100:n
  • SimpleRoundTo
    • Sama kuin pyöristä, mutta johtuen d7 system kirjaston bugista, toimii väärin jossain tilanteissa. Pyorista korjaa sen. D2007 versioon korjautunut.
  • RoundTo

Päiväys

  • function Date:TDateTime;
    • palauttaa nykyisen päiväyksen DateTime tyyppinä

...

  • function FormatDateTime(format: string; DateTime: Tdatetime):String;
    • Muotoilee ajan ja päivän annetulla formaatilla kts.
  • StrToTime
  • Time
  • TimeToStr

Bonuslaskenta

  • function AlustaBonus(Tietokanta): Bonusluokka;
    • lataa bonusasetukset. Kutsu vain kerran ja jokaista AlustaBonus rutiinin kutsua kohden pitää kutsua vapautabonus.
  • procedure VapautaBonus(Bonusluokka);
    • vapauttaa aiemmin AlustaBonus funktiolla luodun bonusmuuttuja.
  • function BonusPros(kertyma:Double): Double;
    • palauttaa bonusprosentin johon ostokertymä oikeuttaa

Tietokanta

Titan -komponentin liityntä tauluun luodaan seuraavasti

...

  • function TTbTable.TryPost (ms_viive: integer);
    • tTbTable-luokan menetelmä. Yrittää saada muokkausoikeuden taulun nykyiseen tietueeseen ja yritetään korkeintaan ms_viiveen ajan. Aika on millisekunteina. Palauttaa false jos epäonnistui, esim.

      Code Block
      languagedelphi
      if varsaldo.tryEdit(2000) then
      begin
        varsaldo.fieldbyname('saldo').asfloat := 0;
        varsaldo.fieldbyname('muutosklo').asdatetime := now;
        if not varsaldo.trypost(2000) then
        begin
          logentry('Varsaldoa ei voi tallentaa');
          varsaldo.cancel;
        end;
      end
      else
        showmessage('Saldoa ei voi muokata');
      
      

Pervasive sql

Koska pervasiven PDAC komponenttikirjastoista ei ole saatavilla lähdekoodeja, siitä emme ole voineet tuottaa titan rajanpinnan kaltaista liittymää. Sql rajapinta on tehty omilla rutiineilla jotka ovat
*function LuoSql(TietokantaAlias, sql, tapa) - luo kyselyn ja palauttaa sen muuttujan (jatkossa alla kysely). Voidaan myös lisätä suoraan sql parametriksi esim. q := luosql(dbname,'select count(star) as c from from tuote'); joka tekee luonnin lisäksi sql lauseen asettamisen. Vapaaehtoinen 3. parametri tapa voidaan myös antaa. Se voi olla välillä 1-3, 1= avaa kyselyn, 2 = ajaa kysely (update, insert, delete tms), 3= ajaa kyselyn ja vapauttaa sql muutujan. Kun tapa=3, paluu arvona on vaikutettujen rivien määrä.

...

Code Block
languagedelphi
kysely := LuoSql('testikanta');
asetasql(kysely,'select tuote,sum(summa) as myynti from tuotemyy where tuotelaji in (0,2) and pvm>''2011'' ');
avaasql(kysely);
while not eofsql(kysely) do
begin
  showmessage(sqlfbs(kysely,'tuote')+' '+formatfloat('#0.00',sqlfbf(kysely,'myynti')));
  sqlnext(kysely);
end;
suljesql(kysely);
vapautasql(kysely);

kysely1 := CreateSql('testikanta','select count(*) as maara from tuote where ryhma = :r');
preparesql(kysely1);
for i := 1 to 10 do
begin
  sqlSetParam(kysely1,'r',i);
  opensql(kysely1);
  showmessage('Tuoteryhmässä '+inttostr(i)+' on tuotteita '+inttostr(sqlfbi(kysely1,'maara')));
  closesql(kysely1);
end;
unprepareSql(kysely1);
vapautasql(kysely1);

Excel liityntä

Excel yhteys perustaa AdoDb:n. Esimerkki avauksesta, tässä excel avataan vain luku tilaan. Lisäksi kerromme että headereita ei ole (HDR=NO) jolloin kentät ovat f1, f2 jne sekä excel ei yritä päätellä datatyyppejä (IMEX=1). Jälkimmäinen on tarpeen jos siellä on tyhjiä tai sekalaisia arvoja samassa sarakkeessa. 

...

64 bittisessä ympäristössä uuden excel driverin kanssa voi olla ongelmaa, jos se ei toimi, kannattaa kokeilla 2007 versio ajuria
https://www.microsoft.com/en-us/download/details.aspx?id=23734


Muut

  • procedure ShowMessage(s);

...

  • function OnkoParam(parametri): string;
    • Palauttaa parametrin arvon tai vakion NOPARAM jos parametria ei ole annettu. Esim.
      lahdetiedosto := onkoparam('lahde');
      if lahdetiedosto = NOPARAM then
      lahdetiedosto := 'c:winskjdata.txt';
      komentorivillä parametri olisi annettu skjscript /f:skriptinnimi.pas /run /lahde:c:\data\joku.txt

FTP /SFTP

  • procedure LuoFtp(Serveri,Username,password: String; Ftp: tFtpLuokka)
    • avaa passiivi ftp -yhteyden serveriin. Jos serverin nimessä perässä lukee ;PASSIVE pakotetaan passiivi -yhteys, jos jotain muuta esim ;A tai ;ACTIVE tulee aktiivi -yhteys. Ftp -muuttujassa palaa ftp-luokka
    • Ftp <>0 jos toiminto onnistunut.

...

Code Block
var
  ftp;
  fs;
  s;
  dir;
  i;
  fn: string;
  target,source;
  fingerprint,host,user,pass,port,directory,wildcard;
  tiedosto;
  st;
  lista,nimi;

 function validoi(avain);
   begin
       if avain = fingerprint then // serverin avain
       result := 'OK'
      else
       result := '';
       end;


begin
  // Muuttujat alkaa

  fingerprint := '1b:1b:dd:e2:bb:a6:02:2d:14:86:2e:e2:ac:40:2b:ee'; // SSH host fingerprint
  host := '1.2.3.4'; // SFTP palvelin
  user := 'username'; // SFTP username
  pass := 'password'; // SFTP password
  port := '22'; // SFTP portti, oletus 22
  directory := '/mnt/finvoice/' ; // hakemisto, mihin tiedostot tallennetaan palvelimella, loppuun /
  wildcard := 'F*.*' ;
  source := 'C:\TEMP\'; // mist‰ laskut luetaan, \ per‰‰n

  // Muuttujat loppuu

  st := CreateStatus('SFTP lähetys');
  ShowStatus(st,'Yhdistäminen','');
  ftp := LuoSFtp(host,user,pass,port,'validoi');
  if assigned(ftp) then
  begin  
    ShowStatus(st,'hakemiston vaihto','');
    // kohdehakemisto palvelimella
    lista := tstringlist.create;
    listaatiedostot(source+wildcard,0,0,lista);
    for i:= 0 to lista.count -1 do
    begin
      tiedosto := lista.strings[i];
      nimi := justfilename(tiedosto);
      showstatus(st,'Siirto ',nimi);
      try
        PutSFtp(ftp,tiedosto,directory+nimi);
        deletefile(tiedosto);
        LogEntry('Tiedosto ' + tiedosto + ' siirretty SFTP-palvelimelle ' + directory+nimi + ' ja poistettu.');
      except
        LogEntry('Siirto virhe '+tiedosto+' '+lastExceptionmessage);
      end;
      sleep(1000);
    end;
    lista.free;
  suljesftp(ftp);
  end;
  CloseStatus(st);
end;

Sähköpostin lähetys

Sähkopostin lähetys käyttää winskj:n tallennettuja asetuksia, joten sen tarvitsee tietää tietokannan nimi, josta ne haetaan.
Eli parametrit ovat

...

Code Block
var
  a,a2,mr;
  dbname;
  s: string;
  i: integer;
  myymala:integer;
begin
  dbname := 'SKJ';
  // alustetaan asiakasmuutostietue
 myymala := 1; // minkä myymälän nimiin muutokset kirjataan
  LuoAsiakasMuutostietue(dbname,myymala,mr);

  a := ttbtable.Create(nil);
  a.databasename := dbname;
  a.tablename := 'asiakas';
  a.open;
  a2 := ttbtable.Create(nil);
  a2.databasename := dbname;
  a2.tablename := 'asiakas2';
  a2.open;

  while not a.eof do
  begin
    if (WordCount(trim(a.FieldByName('nimi').AsString),' ')>0) and ( trim(a.FieldByName('nimi2').AsString) = '') then
    begin
      // alustetaan muutosten seuanta tälle asiakkaalle
      AloitaAsiakasmuutos(a,a2,mr);
      // tässä muunnetaan nimi kenttä muodosta "Möttönen Marko Uolevi" -> Nimi: Möttönen Nimi2: Marko Uolevi
      a.edit;
      s :=  a.FieldByName('nimi').AsString;
      a.FieldByName('nimi').AsString := ExtractWord(1,s,' ');
      a.FieldByName('nimi2').AsString := '';
      for i:=2 to wordCount(s,' ') do
        a.FieldByName('nimi2').AsString :=  a.FieldByName('nimi2').AsString+' '+extractWord(i,s,' ');
      a.FieldByName('nimi2').AsString := trim(a.FieldByName('nimi2').AsString)
      logEntry('Muutettu '+s+':->'+a.FieldByName('nimi').AsString+', '+a.FieldByName('nimi2').AsString);
      a.post;
      // tallennetaan mahdolliset muutokset
      LopetaAsiakasmuutos(a,a2,mr,false);
    end;
    a.next;
  end;
  a.close;
  a2.close;
end;


Tiedostot

hakemisto läpikäyntiin ja tiedostojen etsintään

FindFirst, FindNext ja FindClose

  • function FindFirst(const Path: string; Attr: Integer; var F: TSearchRec): Integer;
  • function FindNext(var F: TSearchRec): Integer;
  • procedure FindClose(var F: TSearchRec);

...

  • procedure ListaaTiedostot(Polku,attribuutit, rekursio, lista);
  • Hoitaa tiedostojen listaamisen.
      • Lista = luotu TStringList
      • Polku = mitä haetaan , attribuutit, yleensä 0.
      • Rekursio, käydäänkö alihakemistot. Ei tehty vielä.
        esim.

        Code Block
        lista := tstringlist.create;
        listaatiedostot('c:\winskj\*.txt',0,false,lista);
        showmessage(lista.text);
        

XML käsittely

Xml käsittely tehdään käyttäen microsoftin xmldom -komponenttia, tässä pari esimerkkiä.

SKJ Tuote import

export-lause taustaa varten, jotta saadaan jo olemassa olevasta kannasta tiedot muokattavaksi:

...

Huom! VERHINTA ei ole käytössä SKJTuoteImport.xls :ssä.

JSON käsittely

Json käsittely on toteuttu pohjautuen mormot kirjastoon. Väliin on jouduttu tekemään muutama rutiini.

...

Code Block
  b:= JsonNewDocFromjson('{"id":"A000173","group":12,"department":1,"float":12.32,"name":"3.3. A3 + F1 P4suora erikois","name2":""}');
  maara := jsongetcount( b );
  id := jsongetvalue(b, "id"); 
  for i:= 0 to jsongetcount(b)-1 do
  begin
    showmessage(jsongetname(b,i)+'='+jsontostring ( jsongetvalue(b,i,true)));  
  end;


REST Rajapinta

function RestCall(Url: string; data: String; BasicAuth_username: string; Basic_Auth_password: string; var status: integer; var statustxt: string; method: string='post'): string;

...