Sviluppo4d.it
Sito indipendente di informazioni tecniche per sviluppatori 4th Dimension italiani  

Sviluppatori 4D

Utility 4D

Risorse 4D



4d logo
Naviga:

Faq

Ho trovato 835 faq, ecco le prime 50.

Categoria Argomento Commenti
Info Info Comandi deprecati aggiornati alla v19
CommandReplaced withObsolete since
4D Environment theme:
_o_DATA SEGMENT LIST-v11
Backup theme:
_o_INTEGRATE LOG FILEINTEGRATE MIRROR LOG FILEv16
Compiler theme:
_o_ARRAY STRINGARRAY TEXTv12
_o_C_GRAPH(use SVG with the GRAPH command)v12
_o_C_INTEGERC_LONGINTv12
_o_C_STRINGC_TEXT (as soon as database is in Unicode)v12
Data Entry theme:
_o_ADD SUBRECORDADD RECORD in the n table of a N->1 relationv12
_o_MODIFY SUBRECORDMODIFY RECORD in the n table of a N->1 relationv12
Drag and Drop theme:
_o_DRAG AND DROP PROPERTIESCommands from the Pasteboard themev17 R4
Form Events theme:
_o_DuringReplace with Form event code and the appropriate eventv12
Forms theme:
_o_FORM GET PARAMETERDisabledv17 R4
Graphs theme:
GRAPH (using 4D Graph Area)Use an SVG picture insteadv12
Hierarchical Lists theme:
_o_REDRAW LISTRemove in code (does nothing since v11)v11
List Box theme:
LISTBOX Get property constants:
_o_lk display hor scrollbar/_o_lk display ver scrollbarOBJECT GET SCROLLBARv16 R3
_o_lk footer heightLISTBOX Get footers heightv16 R3
_o_lk header heightLISTBOX Get headers heightv16 R3
_o_lk hor scrollbar position/_o_lk ver scrollbar positionOBJECT GET SCROLL POSITIONv16 R3
Objects (Forms) theme:
_o_OBJECT Get actionOBJECT Get actionv16 R3
_o_OBJECT SET COLOROBJECT SET RGB COLORSv18
Pictures theme:
_o_PICTURE TO GIFPICTURE TO BLOBv16 R5
Printing theme:
_o_PAGE SETUPSET PRINT OPTION, GET PRINT OPTIONPrint settings to BLOBBLOB to print settingsv18
Selection theme:
_o_MOBILE Return selectionORDAv18
SQL theme:
_o_USE EXTERNAL DATABASESQL LOGINv12
_o_USE INTERNAL DATABASESQL LOGOUTv12
String theme:
_o_Mac to Winv11
_o_Win to Macv11
Subrecords theme: all commandsReplace “nnn SUBRECORD” and “nnn SUBSELECTION” with an action on the N record or N-selection of the N-table in a N->1 relationv12
System Documents theme:
_o_Document typePath to objectv12
_o_Document creatorPath to objectv16 R6
_o_SET DOCUMENT TYPEObject to pathv16 R6
_o_SET DOCUMENT CREATORObject to pathv16 R6
_o_MAP FILE TYPESUse UTIs and Info.plistv16 R6
System Environment theme:
_o_Font nameUse font identifiersv14
The OBJECT SET FONT command no longer accepts a LongInt parameter for the font: this parameter is now a String and you must specify the font name.
_o_GestaltGet system info / Is macOS / Is Windowsv17
_o_PLATFORM PROPERTIESGet system info / Is macOS / Is Windowsv17
User Forms theme:
_o_CREATE USER FORMDynamic Formsv17 R4
_o_DELETE USER FORMDynamic Formsv17 R4
_o_EDIT FORMDynamic Formsv17 R4 
_o_LIST USER FORMSDynamic Formsv17 R4
Web Server theme:
_O_WEB Get session process countUse scalable sessionsv18 R6
4D Internet Commands:
POP3 Review Mail commands4D Mail built-in themev18
SMTP Send Mail commands4D Mail built-in themev18 R6
IMAP Review Mail commands4D Mail built-in themev19
Codice Codice Convertire numeri arabi in numeri romani
Di seguito lo sviluppo di un algoritmo per la conversione di un numero arabo in numero romano. Il testo romano viene generato da destra a sinistra


//u_DaAraboARomano
//--------------------------

If (Count parameters=0)
      $romano:=u_DaAraboARomano (87) //per test
Else
      $number:=$1
      $udigits:="IVXLCDM"
      $romano:=""
      $posizione:=1
      Repeat
           $modulo:=$number%10
           If (($modulo%5)<4)
           For ($i;($modulo%5);1;-1)
           $romano:=$udigits[[$posizione]]+$romano
           End for
           End if
           If (($modulo>=4) & ($modulo<=8))
           $romano:=$udigits[[$posizione+1]]+$romano
           End if
           If ($modulo=9)
           $romano:=$udigits[[$posizione+2]]+$romano
           End if
           If ($modulo%5=4)
           $romano:=$udigits[[$posizione]]+$romano
           End if
           $number:=Trunc($number/10;0)
           $posizione:=$posizione+2
      Until ($number<=0)
      $0:=$romano
End if

Codice Codice Check Digit Ean13/Ean8
// calcola il check digit del codice ean
    // se il codice ean è di 8 o 13 caratteri elimino un carattere e ricalcolo il check digit

C_TEXT($check;$ritorno;$codice)
C_COLLECTION($strParts)
C_LONGINT($lngIndex;$intTotal;$intCount;$intUp As;$elementi;$modoup)

If (Undefined($1))
  $0:=""
End if

If ($1="")
  $0:=""
End if

$codice:=$1

If (Length($codice)=13)
  $codice:= prendiSinistra($codice;12)
End if

If (Length($codice)=8)
  $codice:= prendiSinistra($codice;7)
End if

$codice:=$codice+"C"
$strParts:=Split string($codice;"")
$elementi:=$strParts.length

For ($lngIndex;$elementi-2;0;-2)
  For ($intCount;1;3)
    $intTotal:=$intTotal+Num($strParts[$lngIndex])
  End for
End for

$lngIndex:=13

For ($lngIndex;$elementi-1;0;-2)
  $intTotal:=$intTotal+Num($strParts[$lngIndex])
End for

$intUp:=$intTotal

Repeat
  $intUp:=$intUp+1
  $modoup:=Mod($intUp;10)
Until ($modoup=0)

$check:=String($intUp-$intTotal)

For ($lngIndex;0;$elementi-2)
  $ritorno:=$ritorno+$strParts[$lngIndex]
End for

$ritorno:=$ritorno+$check
$0:=$ritorno


Sotto il codice per le funzioni prendiSinistra/prendiDestra


---- prendiSinistra ------
    // $1=testo
    // $2=lunghezza
    // $0=testo left

If ($2=0)
$0:=""
End if

C_LONGINT($lungo)
$lungo:=Length($1)
If ($lungo=0)
$0:=""
End if

$0:=Substring($1;1;$2)

---- prendiDestra ----
    // $1=testo
    // $2=lunghezza
    // $0=testo right

If ($2=0)
  $0:=""
End if

$lunghezza:=Length($1)
If ($lunghezza=0)
  $0:=""
End if

$lunghezza:=Length($1)

$0:=Substring($1;$lunghezza-$2+1;$2)
Codice Codice Numeri a lettere
Ritorna il numero in formato lettera come ad esempio per gli assegni bancari :
1234,56 = MilleDuecentoTrentaQuattro//56

C_TEXT($result;$risultato;$intero)

    // il dato passato è un numero double che devo trasformare in un formato italiano
$intero:=String($1;"###########0.00")
    // $intero:=$1 // importo in lettere
C_TEXT($resto)
C_LONGINT($lungo)
$lungo:=Length($intero)
C_LONGINT($decimale)
$decimale:=Position(",";$intero)
$resto:="/"+tright ($intero;2)
$intero:=tleft ($intero;$decimale-1)
C_TEXT($verifica)
$verifica:=Substring($intero;1;1)
If ($verifica="-")
  $intero=Mid(intero, 2)
End if
If ($1=0)
  $0="zero/00"
End if
C_LONGINT($mille)
$mille:=-1
C_LONGINT($k)
$k:=Mod(Length($intero);3)
If ($k#0)
  $intero=Repeate (3-$k,"0")+$intero
End if

While ($intero#"")
  $mille:=$mille+1
  C_TEXT($parziale;$tripla;$s)
  C_LONGINT($tv;$td; $tc)
  C_LONGINT($x;$y)

  $tripla:=tright ($intero;3)
  $intero:=tleft ($intero;Length($intero)-3)
  $tv:=Num($tripla)
  $td:=Mod($tv;100)
  $tc:=($tv-$td)/100
  If (Not($tc=0)
    $parziale:="cento"
    If ($tc>1)
      $parziale:=unita ($tc)+$parziale
    End if
  End if
  If ($td<20)
    $parziale:=$parziale+unita ($td)
  Else
    $x:=Mod($td;10)
    $y:=($td-$x)/10
    $parziale:=$parziale+decine ($y)
    $s:=unita ($x)
    $primoc:=tleft ($s;1)
    $instr:=Position($primoc;"uo";1)

    If ($instr#0)
      If ($s#"")
        If (Not$y=0)
          $parziale:=tleft ($parziale;Length($parziale-1))
        End if
      End if
    End if

    $parziale:=$parziale+$s
  End if
  $s:=migliaia ($mille)
  If ($mille>0)
    If ($parziale#"")

      $k:=$mille
      If ($parziale#"uno")
        $k:=$k+4
        $s:=migliaia ($k)
        $ddestra:=tright ($parziale;3)
        If ($ddestra="uno")
          $parziale:=tleft ($parziale;Length($parziale)-1)
          End if
      Else
        $parziale:=""
      End if
      $parziale:=$parziale+$s
    End if
  End if
  $result:=$parziale+$result
End while

If ($1<0)
$result="meno"+$result
End if

$0:=$result+$resto


E di seguito le varie altre funzioni utilizzate :

--- Repeate ---

C_TEXT($testo)
C_LONGINT($contatore)
For ($contatore;1;$1)
  $testo:=$testo+$2
End for

$0:=$testo

--- unita ---

C_COLLECTION($lettere)
C_TEXT($risultato)
$lettere:=Split string(",uno,due,tre,quattro,cinque,sei,sette,otto,nove,dieci,undici,dodici,tredici,quattordici,quindici,sedici,diciassette,diciotto,diciannove";",")

C_LONGINT($lunghezza)
$lunghezza:=$lettere.length

If ($1<0)
$risultato:=""
Else
If ($1>$lunghezza)
$risultato:=""
Else
$risultato:=$Lettere[$1]
End if
End if

$0:=$risultato

--- migliaia ---

C_COLLECTION($lettere)

C_TEXT($risultato)
$lettere:=Split string(",mille,unmilione,unmiliardo,millemiliardi,mila,milioni,miliardi,milamiliardi,milamiliardi,migliaiadimiliardi";",")

C_LONGINT($lunghezza)

$lunghezza:=$lettere.length
If ($1<0)
$risultato:=""
Else
If ($1>$lunghezza)
$risultato:=""
Else
$risultato:=$Lettere[$1]
End if
End if

$0:=$risultato

--- isnumeric ---

If (Undefined($1))
$0=False
End if

$lettera:=$1
$numero:=Num($lettera)
$letteranunero:=String($numero)

If (Substring($lettera;1;1)="0")
$letteranunero:="0"+$letteranunero
End if

If (Length($lettera)=Length($letteranunero)
$0:=True
Else
$0:=False
End if

--- decine ----

C_COLLECTION($lettere)
C_TEXT($risultato)
C_LONGINT($lunghezza)

$lettere:=Split string(",dieci,venti,trenta,quaranta,cinquanta,sessanta,settanta,ottanta,novanta";",")
$lunghezza:=$lettere.length

If ($1<0)
$risultato:=""
Else
If ($1>$lunghezza)
$risultato:=""
Else
$risultato:=$Lettere[$1]
End if
End if
$0:=$risultato

--- tleft ----
    
    // $1=testo
    // $2=lunghezza
    // $0=testo left

If ($2=0)
$0:=""
End if

C_LONGINT($lungo)
$lungo:=Length($1)
If ($lungo=0)
$0:=""
End if

$0:=Substring($1;1;$2)

--- tright ---
    // $1=testo
    // $2=lunghezza
    // $0=testo right

If ($2=0)
$0:=""
End if

$lunghezza:=Length($1)
If ($lunghezza=0)
$0:=""
End if

$lunghezza:=Length($1)

$0:=Substring($1;$lunghezza-$2+1;$2)
Codice Codice Controllo Codice Fiscale
Questo metodo ritorna Vero se il codice fiscale passato è scritto correttamente, utilizzando il carattere di controllo finale. La procedura è un po' condensata: per l'algoritmo di controllo completo potete trovare il dettaglio sul sito del Ministero delle Finanze.

    `Metodo Controllo_CodiceFiscale
    `controlla il checksum del codice fiscale
    `Nexus srl 4-6-90
C_LONGINT($i;$n_l;$car_l;$cod_l)
C_STRING(16;$cf_s;$1)
C_STRING(43;$mysndcod_s)
$cf_s:=$1
If (Length($cf_s)#16)
  $0:=False
Else
  $n_l:=0
  For ($i;2;14;2)
    $car_l:=Ascii($cf_s[[$i]])
    Case of
      : (($car_l>=48) & ($car_l<=57))
        $cod_l:=$car_l-48
      : (($car_l>=65) & ($car_l<=90))
        $cod_l:=$car_l-65
      Else
        $cod_l:=0
    End case
    $n_l:=$n_l+$cod_l
  End for
  $mysndcod_s:="BAFHJNPRTVUMBERTOBAFHJNPRTVCESULDGIMOQKWZYX"
  For ($i;1;15;2)
    $car_l:=Ascii($cf_s[[$i]])-47
    $cod_l:=Ascii($mysndcod_s[[$car_l]])-65
    $n_l:=$n_l+$cod_l
  End for
  $0:=((65+$n_l-(Int($n_l/26)*26))=Ascii($cf_s[[16]]))
End if
3
Codice Codice Calcolo del codice fiscale
La funzione per il calcolo del codice fiscale :
Nota : occorre il database con i comuni e relativi codici istat.

---- calcolocodicefiscale ----

    // dati da passare per il calcolo
    // $1:Nome;$2:Cognome;$3:data in formato testo;$4:sesso M o F;$5:codice istat comune
    // ritorno il codice fiscale
$nome:=$1
$cognome:=$2
$data:=$3
$sesso:=$4
$comune:=$5

$inome:=""
$icognome:=""
$icomune:=""
$controllo:=""
$temp:=""
$letteracod:=""
    //prendi le iniziali del nome
    //ccc As int32=1
$lungnome:=0
For ($lungnome;1;Length($nome))
$temp:=Lowercase(Substring($nome;$lungnome;1))
Case of
: $temp="b"
$inome:=$inome+$temp
: $temp="c"
$inome:=$inome+$temp
: $temp="d"
$inome:=$inome+$temp
: $temp="f"
$inome:=$inome+$temp
: $temp="g"
$inome:=$inome+$temp
: $temp="h"
$inome:=$inome+$temp
: $temp="j"
$inome:=$inome+$temp
: $temp="k"
$inome:=$inome+$temp
: $temp="l"
$inome:=$inome+$temp
: $temp="m"
$inome:=$inome+$temp
: $temp="n"
$inome:=$inome+$temp
: $temp="p"
$inome:=$inome+$temp
: $temp="q"
$inome:=$inome+$temp
: $temp="r"
$inome:=$inome+$temp
: $temp="s"
$inome:=$inome+$temp
: $temp="t"
$inome:=$inome+$temp
: $temp="v"
$inome:=$inome+$temp
: $temp="w"
$inome:=$inome+$temp
: $temp="x"
$inome:=$inome+$temp
: $temp="y"
$inome:=$inome+$temp
: $temp="z"
$inome:=$inome+$temp

End case

End for

If (Length($inome)>=4)
$temp:=Lowercase($inome)
$inome:=Substring($temp;1;1)+Substring($temp;3;1)+Substring($temp;4;1)
End if

    //controlla la lunghezza delle iniziali
If (Length($inome)>3)
$inome:=Substring($inome;1;3)
Else
If (Length($inome)<3)
For $lungnome(1;Length($nome))
$letteracod:=Substring($nome;$lungnome;1)
Case of
: $letteracod="a"
$inome:=$inome+"a"
: $letteracod="e"
$inome:=$inome+"e"
: $letteracod="i"
$inome:=$inome+"i"
: $letteracod="o"
$inome:=$inome+"o"
: $letteracod="u"
$inome:=$inome+"u"
End case
End for

If (Length($inome)>3)
$inome:=Substring($inome;1;3)
If (Length($inome)<3)
For ($lungnome;Length($inome);3)
$inome:=$inome+"x"
End for
End if
End if
End if
End if

    // prendi lettere del cognome
For ($lungnome;1;Length($cognome))
$temp:=Lowercase(Substring($cognome;$lungnome;1))
Case of
: $temp="b"
$icognome:=$icognome+$temp
: $temp="c"
$icognome:=$icognome+$temp
: $temp="d"
$icognome:=$icognome+$temp
: $temp="f"
$icognome:=$icognome+$temp
: $temp="g"
$icognome:=$icognome+$temp
: $temp="h"
$icognome:=$icognome+$temp
: $temp="j"
$icognome:=$icognome+$temp
: $temp="k"
$icognome:=$icognome+$temp
: $temp="l"
$icognome:=$icognome+$temp
: $temp="m"
$icognome:=$icognome+$temp
: $temp="n"
$icognome:=$icognome+$temp
: $temp="p"
$icognome:=$icognome+$temp
: $temp="q"
$icognome:=$icognome+$temp
: $temp="r"
$icognome:=$icognome+$temp
: $temp="s"
$icognome:=$icognome+$temp
: $temp="t"
$icognome:=$icognome+$temp
: $temp="v"
$icognome:=$icognome+$temp
: $temp="w"
$icognome:=$icognome+$temp
: $temp="x"
$icognome:=$icognome+$temp
: $temp="y"
$icognome:=$icognome+$temp
: $temp="z"
$icognome:=$icognome+$temp
End case
End for

    // controlla la lunghezza delle iniziali
If (Length($icognome)>3)
$icognome:=Substring($icognome;1;3)
Else
If (Length($icognome)<3)
// minore di tre cifre prendi anche le vocali
For ($lungnome;1;Length($cognome))
letteracod:=Substring($cognome;$lungnome;1)
Case of
: $letteracod="a"
$icognome:=$icognome+"a"
: $letteracod="e"
$icognome:=$icognome+"e"
: $letteracod="i"
$icognome:=$icognome+"i"
: $letteracod="o"
$icognome:=$icognome+"o"
: $letteracod="u"
$icognome:=$icognome+"u"
End case
End for

If (Length($icognome)>3)
$icognome:=Substring($icognome;1;3)
Else
If (Length($icognome)<3)
For ($lungnome;Length($icognome);3)
$icognome:=$icognome+"x"
End for
End if
End if
End if
End if

    // Dim idata, gg, mm, aa As String
    // temp=data
    // Dim tempn As string

ARRAY TEXT($ddata;0)
C_COLLECTION($detta)

$detta:=Split string($data;"/")
COLLECTION TO ARRAY($detta;$ddata)

$gg:=$ddata{1}
$mm:=$ddata{2}
If (Length($ddata{3})=2)
$aa:=$ddata{3}
Else
$aa:=Substring($ddata{3};3;2)
End if

$idata:=$aa
    //MsgBox("TEMP"+temp)
Case of
: $mm="01"
$idata:=$idata+"a"
: $mm="02"
$idata:=$idata+"b"
: $mm="03"
$idata:=$idata+"c"
: $mm="04"
$idata:=$idata+"d"
: $mm="05"
$idata:=$idata+"e"
: $mm="06"
$idata:=$idata+"h"
: $mm="07"
$idata:=$idata+"l"
: $mm="08"
$idata:=$idata+"m"
: $mm="09"
$idata:=$idata+"p"
: $mm="10"
$idata:=$idata+"r"
: $mm="11"
$idata:=$idata+"s"
: $mm="12"
$idata:=$idata+"t"
End case
If ($sesso="M")
$idata:=$idata+$gg
Else
If ($sesso="F")

$idata:=$idata+String(Num($gg)+40)
End if
End if

C_LONGINT($vdis)

    // codice parziale per calcolare ultima cifra
$parz:=Lowercase($icognome+$inome+$idata+$comune)
    // trova il carattere di verificca
For ($lungnome;1;15;2)
$d:=Substring($parz;$lungnome;1)
Case of
: $d="0"
$vdis:=$vdis+1
: $d="1"
$vdis:=$vdis+0
: $d="2"
$vdis:=$vdis+5
: $d="3"
$vdis:=$vdis+7
: $d="4"
$vdis:=$vdis+9
: $d="5"
$vdis:=$vdis+13
: $d="6"
$vdis:=$vdis+15
: $d="7"
$vdis:=$vdis+17
: $d="8"
$vdis:=$vdis+19
: $d="9"
$vdis:=$vdis+21
: $d="a"
$vdis:=$vdis+1
: $d="b"
$vdis:=$vdis+0
: $d="c"
$vdis:=$vdis+5
: $d="d"
$vdis:=$vdis+7
: $d="e"
$vdis:=$vdis+9
: $d="f"
$vdis:=$vdis+13
: $d="g"
$vdis:=$vdis+15
: $d="h"
$vdis:=$vdis+17
: $d="i"
$vdis:=$vdis+19
: $d="j"
$vdis:=$vdis+21
: $d="k"
$vdis:=$vdis+2
: $d="l"
$vdis:=$vdis+4
: $d="m"
$vdis:=$vdis+18
: $d="n"
$vdis:=$vdis+20
: $d="o"
$vdis:=$vdis+11
: $d="p"
$vdis:=$vdis+3
: $d="q"
$vdis:=$vdis+6
: $d="r"
$vdis:=$vdis+8
: $d="s"
$vdis:=$vdis+12
: $d="t"
$vdis:=$vdis+14
: $d="u"
$vdis:=$vdis+16
: $d="v"
$vdis:=$vdis+10
: $d="w"
$vdis:=$vdis+22
: $d="x"
$vdis:=$vdis+25
: $d="y"
$vdis:=$vdis+24
: $d="z"
$vdis:=$vdis+23
End case
End for

C_LONGINT($vpar)

For ($lungnome;2;14;2)
$p:=Substring($parz;$lungnome;1)
Case of
: $p="0"
$vpar:=$vpar+0
: $p="1"
$vpar:=$vpar+1
: $p="2"
$vpar:=$vpar+2
: $p="3"
$vpar:=$vpar+3
: $p="4"
$vpar:=$vpar+4
: $p="5"
$vpar:=$vpar+5
: $p="6"
$vpar:=$vpar+6
: $p="7"
$vpar:=$vpar+7
: $p="8"
$vpar:=$vpar+8
: $p="9"
$vpar:=$vpar+9
: $p="a"
$vpar:=$vpar+0
: $p="b"
$vpar:=$vpar+1
: $p="c"
$vpar:=$vpar+2
: $p="d"
$vpar:=$vpar+3
: $p="e"
$vpar:=$vpar+4
: $p="f"
$vpar:=$vpar+5
: $p="g"
$vpar:=$vpar+6
: $p="h"
$vpar:=$vpar+7
: $p="i"
$vpar:=$vpar+8
: $p="j"
$vpar:=$vpar+9
: $p="k"
$vpar:=$vpar+10
: $p="l"
$vpar:=$vpar+11
: $p="m"
$vpar:=$vpar+12
: $p="n"
$vpar:=$vpar+13
: $p="o"
$vpar:=$vpar+14
: $p="p"
$vpar:=$vpar+15
: $p="q"
$vpar:=$vpar+16
: $p="r"
$vpar:=$vpar+17
: $p="s"
$vpar:=$vpar+18
: $p="t"
$vpar:=$vpar+19
: $p="u"
$vpar:=$vpar+20
: $p="v"
$vpar:=$vpar+21
: $p="w"
$vpar:=$vpar+22
: $p="x"
$vpar:=$vpar+23
: $p="y"
$vpar:=$vpar+24
: $p="z"
$vpar:=$vpar+25
End case

End for

    // somma dei valori ottenuti dal dispari e dal pari
$vdisparsomma:=$vdis+$vpar
    // ---------------------
    // vdisparsomma=148
    // ---------------------
    // diviso 26, troviamo il resto
$restov:=Mod($vdisparsomma;26)

Case of $restov
: $restov=0
$controllo:="a"
: $restov=1
$controllo:="b"
: $restov=2
$controllo:="c"
: $restov=3
$controllo:="d"
: $restov=4
$controllo:="e"
: $restov=5
$controllo:="f"
: $restov=6
$controllo:="g"
: $restov=7
$controllo:="h"
: $restov=8
$controllo:="i"
: $restov=9
$controllo:="j"
: $restov=10
$controllo:="k"
: $restov=11
$controllo:="l"
: $restov=12
$controllo:="m"
: $restov=13
$controllo:="n"
: $restov=14
$controllo:="o"
: $restov=15
$controllo:="p"
: $restov=16
$controllo:="q"
: $restov=17
$controllo:="r"
: $restov=18
$controllo:="s"
: $restov=19
$controllo:="t"
: $restov=20
$controllo:="u"
: $restov=21
$controllo:="v"
: $restov=22
$controllo:="w"
: $restov=23
$controllo:="x"
: $restov=24
$controllo:="y"
: $restov=25
$controllo:="z"
End case
    // fai il codice fiscale
$codicefiscale:=Uppercase($parz+$controllo)
$0:=$codicefiscale

Codice Codice Cercafield : Query veloce lookup
// ritorna i dati da una tabella non correlata
    // $1 campo, $2 chiave, $3 tabella, $4 $filtro

C_TEXT($campo) // è il campo che utilizzo per la ricerca
C_TEXT($chiave) // è la chiave cioè il campo che voglio sia ritornato
C_TEXT($tabella) // è il nome della tabella per la quale voglio effettuare la ricerca
C_TEXT($filtro) // eventuale filtro WHERE
C_TEXT($risultato)
$campo:=$1
$chiave:=$2
$tabella:=$3
$filtro:=$4

SQL LOGIN(SQL_INTERNAL;"";"")

C_LONGINT($ffiltro)
$ffiltro:=Position($filtro;"%")
If ($ffiltro>0)
  $filtro:=Char(Quote)+$filtro+Char(Quote)
  SQL EXECUTE("SELECT DISTINCT "+$chiave+" FROM "+$tabella+" WHERE "+$campo+" LIKE "+$filtro;$risultato)
Else
  $filtro:=Char(Quote)+$filtro+Char(Quote)
  SQL EXECUTE("SELECT DISTINCT "+$chiave+" FROM "+$tabella+" WHERE "+$campo+" = "+$filtro;$risultato)
End if

SQL LOAD RECORD(SQL all records)
SQL LOGOUT

$0:=$risultato{0}
Codice Codice Interaleave 2of5 codice per ottenere binario del codice
Il presente codice serve per ricavare il codice binario del codice 2 of 5 per poter poi disegnare il barcode in SVG (0) linea sottile, (1) linea spessa

C_TEXT($K)
C_TEXT($strCode)
C_TEXT($strAux)
C_TEXT($strExit)

$strCode:=$1
$strAux:=$strCode

If ($strCode="")
$0:=""
End if

For ($K=1;(Length($strCode))
C_TEXT($codice)
$codice:=Substring($strAux;$K;1)
Case of
: $codice="0"
: $codice="1"
: $codice="2"
: $codice="3"
: $codice="4"
: $codice="5"
: $codice="6"
: $codice="7"
: $codice="8"
: $codice="9"
: $codice="@"
: $codice="§"
// ok il codice non contiene caratteri non validi
Else
Alert("Errore il codice interleave 2 of 5 contiene caratteri non ammessi, sono ammessi solo numeri da 0-9)
$0:=""
End case
End for

For($K;1;length($strCode))
C_TEXT($codice)
$codice:=Substring($strCode;$K;1)
Case of
: ="1"
$strExit:=$strExit+"11010010010110"
: ="2"
$strExit:=$strExit+"11010101001100"
: ="3"
$strExit:=$strExit+"11001010100110"
: ="4"
$strExit:=$strExit+"11010010100110"
: ="5"
$strExit:=$strExit+"10110100100110"
: ="6"
$strExit:=$strExit+"10011010101100"
: ="7"
$strExit:=$strExit+"10110010101100"
: ="8"
$strExit:=$strExit+"10011001010110"
: ="9"
$strExit:=$strExit+"10110100101100"
: ="0"
$strExit:=$strExit+"11001010010110"
: ="@"
$strExit:=$strExit+"10110010110010"
: ="§"
$strExit:=$strExit+"11010000000000"
End case
// salto
End for

$0:=$strExit

Codice Codice Ean2Bin
Funzione utile per ricavare una stringa come questa riferita al codice EAN 13 o EAN 8 : 00010100011010100111000110100100010100111010001101010111001011011001001110101110010100001101100101000

è possibile poi dividere la stringa e disegnare con SVG linee verticali di spessore normale (0) e spessore doppio (1) per ricavare l'immagine del barcode.

$1 è il codice EAN ( se è lungo 12 o 7 caratteri inserire anche il metodo checkdigit, lo trovate in questo forum).

C_LONGINT($K)
C_TEXT($strAux)
C_TEXT($strExit)
C_TEXT($strCode)
C_TEXT($strEANCode)
$strAux:=$1
$strEANCode:=$1

    // se ho passato il codice ean senza check digit lo calcolo
If (Length($strAux)=12)
  $strEANCode:=Ean138CheckDigit ($strEANCode)
Else
  If (Length($strAux)=7)
    $strEANCode:=Ean138CheckDigit ($strEANCode)
  End if
End if

$strAux:=$strEANCode

If (Not(isnumeric ($strAux)))
  ALERT("Attenzione, il barcode contiene caratteri non validi")
  $0:=""
End if


If (Length($strAux)=13)
      // verifico che sia un EAN 13
      // per prima cosa scarto la prima cifra che è lo stato di emissione(fare riferimento ad INDICOD '
  $strAux:=Substring($strAux;2)
  C_LONGINT($numero)
  $numero:=Num(tleft ($strEANCode;1))
  Case of
    : $numero=0
      $strCode:="000000"
    : $numero=1
      $strCode:="001011"
    : $numero=2
      $strCode:="001101"
    : $numero=3
      $strCode:="001110"
    : $numero=4
      $strCode:="010011"
    : $numero=5
      $strCode:="011001"
    : $numero=6
      $strCode:="011100"
    : $numero=7
      $strCode:="010101"
    : $numero=8
      $strCode:="010110"
    : $numero=9
      $strCode:="011010"
  End case
Else
  $strCode:="0000"
End if

    //
    //Il codice EAN inizia con un carattere iniziale
    //
$strExit:="000101"

    //
    //Prima metà del codice
    //
For ($K;1;Length($strAux)\2)
  
  C_TEXT($code)
  C_LONGINT($numero)
  
  $code:=Substring($strCode;$K;1)
  $numero:=Num(Substring($strAux;$K;1))
  Case of
    : $numero=0
      C_TEXT($temptext)
      If ($code="0")
        $temptext:="0001101"
      Else
        $temptext:="0100111"
      End if
      $strExit:=$strExit+$temptext
      
    : $numero=1
      C_TEXT($temptext)
      If ($code="0")
        $temptext:="0011001"
      Else
        $temptext:="0110011"
      End if
      $strExit:=$strExit+$temptext
      
    : $numero=2
      C_TEXT($temptext)
      If ($code="0")
        $temptext:="0010011"
      Else
        $temptext:="0011011"
      End if
      $strExit:=$strExit+$temptext
      
    : $numero=3
      C_TEXT($temptext)
      If ($code="0")
        $temptext:="0111101"
      Else
        $temptext:="0100001"
      End if
      $strExit:=$strExit+$temptext
      
    : $numero=4
      C_TEXT($temptext)
      If ($code="0")
        $temptext:="0100011"
      Else
        $temptext:="0011101"
      End if
      $strExit:=$strExit+$temptext
      
    : $numero=5
      C_TEXT($temptext)
      If ($code="0")
        $temptext:="0110001"
      Else
        $temptext:="0111001"
      End if
      $strExit:=$strExit+$temptext
      
    : $numero=6
      C_TEXT($temptext)
      If ($code="0")
        $temptext:="0101111"
      Else
        $temptext:="0000101"
      End if
      $strExit:=$strExit+$temptext
      
    : $numero=7
      C_TEXT($temptext)
      If ($code="0")
        $temptext:="0111011"
      Else
        $temptext:="0010001"
      End if
      $strExit:=$strExit+$temptext
      
    : $numero=8
      C_TEXT($temptext)
      If ($code="0")
        $temptext:="0110111"
      Else
        $temptext:="0001001"
      End if
      $strExit:=$strExit+$temptext
      
    : $numero=9
      C_TEXT($temptext)
      If ($code="0")
        $temptext:="0001011"
      Else
        $temptext:="0010111"
      End if
      $strExit:=$strExit+$temptext
      
  End case
End for

    //
    // Prosegue poi con un separatore di mezzo
    //

$strExit:=$strExit+"01010"

    //
    // Seconda metà del codice
    //

For ($K;Length($strAux)\2+1;Length($strAux))
  C_LONGINT($numero)
  $numero:=Num(Substring($strAux;$K;1))
  Case of
    : $numero=0
      $strExit:=$strExit+"1110010"
    : $numero=1
      $strExit:=$strExit+"1100110"
    : $numero=2
      $strExit:=$strExit+"1101100"
    : $numero=3
      $strExit:=$strExit+"1000010"
    : $numero=4
      $strExit:=$strExit+"1011100"
    : $numero=5
      $strExit:=$strExit+"1001110"
    : $numero=6
      $strExit:=$strExit+"1010000"
    : $numero=7
      $strExit:=$strExit+"1000100"
    : $numero=8
      $strExit:=$strExit+"1001000"
    : $numero=9
      $strExit:=$strExit+"1110100"
  End case
End for

    // Il Codice EAN finisce con un separatore finale

$strExit:=$strExit+"101000"

$0:=$strExit
Codice Codice Sconti composti
Gli sconti composti sono gli sconti commerciali ad esempio 50+20+3 oppure 50+20-3 ( applico lo sconto del 50+20 con un amento del 3% ).

per l'utilizzo :
$importoscontato:=scontocommerciale(126.34,"50+20+3")

--- scontocommerciale ---

    // ricava lo sconto in base alla stringa
    // $1 importo
    // $2 sconto
    // ritorno l'importo scontato su $0

If ($2="")
  If ($1=0)
    $0:=0
  Else
    $0:=$1
  End if
End if


$scontotxt:=$2
$scontotxt:=Replace string($scontotxt;"+";"§+")
$scontotxt:=Replace string($scontotxt;"-";"§-")

C_COLLECTION($sconti)
ARRAY TEXT($ssconti;0)
C_REAL($importoscontato;$scontopercento)

$sconti:=Split string($scontotxt;"§")
COLLECTION TO ARRAY($sconti;$ssconti)

$elementi:=Size of array($ssconti)
$importoscontato:=$1

For ($contatore;1;$elementi)
  $scontopercento:=Num($ssconti{$contatore})
  $sconto:=$importoscontato*$scontopercento/100
  $importoscontato:=$importoscontato-$sconto
End for

$0:=$importoscontato
Info Info [v15] Limitazione automatica dei log
Con il comando SET DATABASE PARAMETER e il parametro Circular log limitation si può gestire il massimo numero di file di log dia tenere in rotazione automatica per tipo di log.

Il numero passato limita il numero di file presenti, con la cancellazione automatica del più vecchio. Si applica a:

- request logs (selectors 28 and 45),
- debug log (selector 34),
- events log (selector 79)
- Web request logs and Web debug logs (selectors 29 and 84 of the WEB SET OPTION command).

Il default è 0 che registra tutti i file senza limiti (finché c'è spazio su disco...)
Info Info [v16] Sintassi alternativa dei 4d Tags
Per 4DTEXT, 4DHTML, 4DEVAL c'è una sintassi alternativa veramente comoda.

Con la v16 è possibile usare per questi tag la forma con il $:
$4dtag (espressione) al posto del solito

Questo va bene solo per questi tag:
4DTEXT
4DHTML
4DEVAL

Quindi ad esempio:
$4DTEXT(UserName)

invece di:
<!--#4DTEXT UserName-->
Comandi Comandi [v16] 4D Tags
Questo è l'elenco aggiornato dei TAG da usare nelle pagine dinamiche ( o da Web o col comando PROCESS 4D TAGS) :

4DTEXT, inserisce variabili o espressioni di 4D come testo (se contengono un carattere come il < lo traducono in htmlencode per visualizzarlo cosi com'è)

4DHTML, inserisce variabili o espressioni di 4D come codice HTML, senza conversioni

4DEVAL, valuta espressioni di 4D, anche senza risultato ( tipo a:=1 ), nel caso ritorni lo considera come HTML senza sostituzioni di caratteri

4DSCRIPT, esegue un metodo 4D (in fase di preparazione della pagina, non arriva sul browser) con la sintassi &lt;!--#4DSCRIPT/metodo/mioparametro--&gt; : The method does not exist.
Nota: il metodo deve essere flaggato come disponibile per il web, aver dichiarato come testo $0 e $1, e in $1 riceverà "/mioparametro"

4DINCLUDE, include un'altra pagina (in fase di preparazione della pagina, non arriva sul browser)

4DBASE, definisce da quel punto in avanti dove prendere le pagine con i 4DINCLUDE successivi

4DCODE, esegue blocchi di codici 4D anche su più righe, incluse finestre e il comando Trace: è eseguito lato server prima di servire la pagina

4DIF, 4DElse, 4DElseIF e 4DENDIF, per gestire condizioni,

4DLOOP and 4DENDLOOP, per fare cicli di codice. Adesso accetta:
- array ( incluso array di puntatori)
- tabella (la selezione corrente)
- espressione, in cui esce dal ciclo per una condizione classica, del tipo:
<!--#4DEVAL $i:=0-->
<!--#4DLOOP ($i<4)-->
<!--#4DEVAL $i-->
<!--#4DEVAL $i:=$i+1-->
<!--#4DENDLOOP-->
Info Info JSON e i caratteri da filtrare
Nelle stringhe JSON i caratteri da filtrare sono:

virgolette (quote) -> \"
barra a destra (slash) -> \/
barra a sinistra (backslash) -> \\
backspace -> \b
formfeed -> \f
nuova linea (new line, char(10) ) -> \n
a capo (return, char(13) ) -> \r
tabulatore (tab, char(9) ) -> \t
tutti i caratteri da 0 a 31 esclusi quelli sopra devono diventare \x00-\x1F
un qualsiasi carattere unicode -> \u+4 cifre esadecimale


// web_jsonEncode

$risultato:=$1

$risultato:=Replace string($risultato;"\\";"\\\\")
$risultato:=Replace string($risultato;char(double quote);"\\\"")
$risultato:=Replace string($risultato;"/";"\\/")
$risultato:=Replace string($risultato;Char(Backspace);"\\b")
$risultato:=Replace string($risultato;Char(FF ASCII code);"\\f")
$risultato:=Replace string($risultato;Char(Line feed);"\\n")
$risultato:=Replace string($risultato;Char(Carriage return);"\\r")
$risultato:=Replace string($risultato;Char(Tab);"\\t")

$0:=$risultato
1
Tecniche Tecniche [v14] Campi OBJECT e coppie chiavi-valore
E' un classico registrare in coppie di array impostazioni o valori da tenere in memoria.

Tipicamente sono due array, si cerca nel primo e se si trova si prende il valore dal secondo, così:

// PER REEGISTRARE
ARRAY TEXT(preferenzeChiave;3)
ARRAY TEXT(preferenzeValore;3)
preferenzeChiave{1}:="Valuta"
preferenzeValore{1}:="Euro"
preferenzeChiave{2}:="Iva"
preferenzeValore{2}:="22"
preferenzeChiave{3}:="Spese"
preferenzeValore{4}:="2,00"

// PER RIPRENDERE
$ce=Find in array(preferenzeChiave;"Iva")
If ($ce>0)
  $0:= preferenzeValore{$ce}
Else
  $0:=""
End if

Con il nuovo Tipo C_OBJECT le due cose si possono scrivere così:

// PER REEGISTRARE
C_OBJECT(oPreferenze)
OB SET(oPreferenze;"Valuta";"Euro";"Iva";22;"Spese";2.00)

// PER RIPRENDERE
$iva:=OB GET(oPreferenze;"Iva")
Info Info [v15] Campi Object visualizzati come JSON
Nelle form impostando un oggetto di Variabile con il contenuto di un Object si ottiene:
1- la visualizzazione del Json corrispondente (senza dover usare JSON stringify)
2- il Json può essere modificato dall'utente e la variabile si aggiorna!
Info Info [v14] JSON e i campi Time
Quando si usa JSON Stringify o Selection to JSON i campi time vengono trasformati in un numero intero di millisecondi dalla mezzanotte.

Quindi le 10 del mattino diventano 10*3600*1000 = 36 000 000

Per recuperare l'orario originale si possono fare due cose:


$millisec:=36000000

Se mi serve una Stringa:
$testo:=Time String($millisec/1000)
-> $testo = "10:00:00"

Se mi serve un Time:
$ora:=Time($millisec/1000)
-> $ora = ?10:00:00?
Comandi Comandi [v14] I comandi nativi JSON: Selection to JSON
Il comando Selection to JSON crea una stringa JSON con i campi della selezione corrente, ad esempio:

$jsonString :=Selection to JSON([Anagrafica])

Il risultato sarà del tipo :
[
{"cognome":"Rossi", "nome":"Mario"},
{"cognome":"Verdi", "nome":"Giuseppe"},
...
]

E' possibile caricare solo alcuni campi aggiungendoli alla sintassi:

$jsonString :=Selection to JSON([Anagrafica], [Anagrafica]Cognome)
[
{"Cognome":"Rossi"},
{"Cognome":"Verdi"},
...
]


Oppure si può impostare un "template"

  C_OBJECT($template)
  OB SET($template;"LastName";->[Anagrafica] Cognome)
  $jsonString :=Selection to JSON([Anagrafica];$template)

[
{"LastName":"Rossi"},
{"LastName":"Verdi"},
...
]
Comandi Comandi [v14] I comandi nativi JSON: JSON Stringify
Partendo da una variabile C_Object si ottiene l'equivalente in stringa JSON con il comando

JSON Stringify ( value ; * ) -> ritorna una stringa compatta
JSON Stringify ( value ; * ) -> modalità 'pretty print', ritorna una stringa indentata

Esempio:

C_OBJECT($Anagrafica;$Figli)
  OB SET($Anagrafica;"cognome";"Rossi";"nome";"Mario")
  OB SET($Figli;"nome";"Giovanni";"anni";"12")
  OB SET($Anagrafica;"figli";$Figli)
  $Uno:=JSON Stringify($Anagrafica)

  {"nome":"Mario","cognome":"Rossi","figli":{"nome":"Giovanni","anni","12"}}

$Due:=JSON Stringify($Anagrafica;*)
  
  {
  "nome":"Mario",
  "cognome":"Rossi",
  "figli":{
    "nome":"Giovanni",
    "anni","12"
  }
}
Comandi Comandi [v14] I comandi nativi JSON: JSON Parse
Dalla versione v14 sono disponibili i comandi JSON, che permettono di passare da stringhe a oggetti 4d.

Gli oggetti JSON sono circondati da graffe {}
Gli array sono circondati da quadre []
I dati sono in formato "chiave":"valore"
La sequenza di dati è separata dalle virgole

Il valore può essere:

  • testo (fra virgolette)

  • numero (col punto decimale)

  • data ( "YYYY-MM-DDTHH:mm:ssZ" )

  • true/false

  • null



JSON Parse ( jsonString {; type} ) -> Function result

Se viene passato il parametro il comando lo converte nel formato richiesto, altrimentii farà la conversione al meglio possibile. Due esempi:

JSON Parse("{\"nome\":124}") -> ritorna un C_OBJECT con {nome = 124}
JSON Parse("{\"nome\":124}", is longint) -> ritorna 124
Plugin Plugin Creare un documento Excel da 4D
Ecco un esempio di codice per la creazione di un foglio Excel usando il plugin free e opensource scritto da Miyako:

https://github.com/miyako/4d-plugin-xls

$text:=Unicode_sample

    //create a workbook
$book:=XLS WORKBOOK Create

$sheetName:=$text
$sheet:=XLS WORKBOOK Create sheet ($book;$sheetName)

    //problem with Mac version of Excel 2010; OK on Windows
XLS WORKSHEET SET COL WIDTH ($sheet;0;20*256)

$row:=0 //zero-based
$col:=0 //zero-based
$format:=0 //NULL=default format (0x0F)
$cell:=XLS WORKSHEET Set cell text ($sheet;$row;$col;$format;$text)
XLS CELL RELEASE ($cell) //we don't need this reference any more, so release it.

    //create a range reference node
$cell1:=XLS WORKSHEET Set cell real ($sheet;0;1;$format;1)
$cell2:=XLS WORKSHEET Set cell real ($sheet;1;1;$format;2)
$area:=XLS WORKBOOK Create area node ($book;$cell1;$cell2;XLS_CELL_ABSOLUTE_As1;XLS_CELLOP_AS_REFERENCE)
XLS CELL RELEASE ($cell1)
XLS CELL RELEASE ($cell2)

    //create a function node
$fn:=XLS WORKBOOK Create fn1 node ($book;XLS_FUNC_SUM;$area)
$cell:=XLS WORKSHEET Set cell fn ($sheet;2;1;$format;$fn)
XLS NODE RELEASE ($fn)
XLS NODE RELEASE ($area)
XLS CELL RELEASE ($cell)

XLS WORKSHEET RELEASE ($sheet)

$success:=XLS WORKBOOK Save document ($book;System folder(Desktop)+$text+".xls")

XLS WORKBOOK CLEAR ($book)
Info Info Privacy e cookies
COOKIE LAW
      1) Che cosa sono i cookie?
I cookie sono dei file di testo che i siti visitati inviano al browser dell'utente e che vengono memorizzati per poi essere ritrasmessi al sito alla visita successiva.

      2) A cosa servono i cookie?
I cookie possono essere usati per monitorare le sessioni, per autenticare un utente in modo che possa accedere a un sito senza digitare ogni volta nome e password e per memorizzare le sue preferenze.

      3) Cosa sono i cookie tecnici?
I cookie cosiddetti tecnici servono per la navigazione e per facilitare l'accesso e la fruizione del sito da parte dell'utente. I cookie tecnici sono essenziali per esempio per accedere a Google o a Facebook senza doversi loggare a tutte le sessioni. Lo sono anche in operazioni molto delicate quali quelle della home banking o del pagamento tramite carta di credito o per mezzo di altri sistemi.

      4) I cookie Analytics sono cookie tecnici?
In altri termini i cookie che vengono inseriti nel browser e ritrasmessi mediante Google Analytics o tramite il servizio Statistiche di Blogger o similari sono cookie tecnici?. Il Garante ha affermato che questi cookie possono essere ritenuti tecnici solo se "utilizzati a fini di ottimizzazione del sito direttamente dal titolare del sito stesso, che potrà raccogliere informazioni in forma aggregata sul numero degli utenti e su come questi visitano il sito. A queste condizioni, per i cookie analytics valgono le stesse regole, in tema di informativa e consenso, previste per i cookie tecnici."

      5) Che cosa sono i cookie di profilazione?
Sono cookie utilizzati per tracciare la navigazione dell'utente per creare profili sui suoi gusti, sulle sue preferenze, sui suoi interessi e anche sulle sue ricerche. Vi sarà certamente capitato di vedere dei banner pubblicitari relativi a un prodotto che poco prima avete cercato su internet. La ragione sta proprio nella profilazione dei vostri interessi e i server indirizzati opportunamente dai cookie vi hanno mostrato gli annunci ritenuti più pertinenti.

      6) È necessario il consenso dell'utente per l'installazione dei cookie sul suo terminale?
Per l'installazione dei cookie tecnici non è richiesto alcun consenso mentre i cookie di profilazione possono essere installati nel terminale dell'utente solo dopo che quest'ultimo abbia dato il consenso e dopo essere stato informato in modo semplificato.

      7) In che modo gli webmaster possono richiedere il consenso?
Il Garante per la Privacy ha stabilito che nel momento in cui l'utente accede a un sito web deve comparire un banner contenente una informativa breve, la richiesta del consenso e un link per l'informativa più estesa come quella visibile in questa pagina su che cosa siano i cookie di profilazione e sull'uso che ne viene fatto nel sito in oggetto.

      8) In che modo deve essere realizzato il banner?
Il banner deve essere concepito da nascondere una parte del contenuto della pagina e specificare che il sito utilizza cookie di profilazione anche di terze parti. Il banner deve poter essere eliminato solo con una azione attiva da parte dell'utente come potrebbe essere un click.

      9) Che indicazioni deve contenere il banner?
Il banner deve contenere l'informativa breve, il link alla informativa estesa e il bottone per dare il consenso all'utilizzo dei cookie di profilazione.

      10) Come tenere documentazione del consenso all'uso dei cookie?
È consentito che venga usato un cookie tecnico che tenga conto del consenso dell'utente in modo che questi non abbia a dover nuovamente esprimere il consenso in una visita successiva al sito.

      11) Il consenso all'uso dei cookie si può avere solo con il banner?
No. Si possono usare altri sistemi purché il sistema individuato abbia gli stessi requisiti. L'uso del banner non è necessario per i siti che utilizzano solo cookie tecnici.

      12) Che cosa si deve inserire nella pagina informativa più estesa?
Si devono illustrare le caratteristiche dei cookie installati anche da terze parti. Si devono altresì indicare all'utente le modalità con cui navigare nel sito senza che vengano tracciate le sue preferenze con la possibilità di navigazione in incognito e con la cancellazione di singoli cookie.

      13) Chi è tenuto a informare il Garante che usa cookie di profilazione?
Il titolare del sito ha tale onere. Se nel suo sito utilizza solo cokie di profilazione di terze parti non occorre che informi il Garante ma è tenuto a indicare quali siano questi cookie di terze parti e a indicare i link alle informative in merito.

      14) Quando entrerà in vigore questa normativa?
Il Garante ha dato un anno di tempo per mettersi in regola e la scadenza è il 2 Giugno 2015.

COOKIE UTILIZZATI IN QUESTO SITO
File di log: Come molti altri siti web anche questo fa uso di file di log registra cioè la cronologia delle operazioni man mano che vengono eseguite. Le informazioni contenute all'interno dei file di registro includono indirizzi IP, tipo di browser, Internet Service Provider (ISP), data, ora, pagina di ingresso e uscita e il numero di clic. Tutto questo per analizzare le tendenze, amministrare il sito, monitorare il movimento dell'utente dentro il sito e raccogliere dati demografici, indirizzi IP e altre informazioni. Tale dati non sono riconducibili in alcun modo all'identità dell'utente e sono cookie tecnici.

COOKIE DI TERZE PARTI PRESENTI NEL SITO

Cookie: www.sviluppo4d.it usa i cookie per memorizzare le informazioni sulle preferenze dei visitatori e sulle pagine visitate dall'utente e per personalizzare il contenuto della pagina web in basa al tipo di browser utilizzato e in funzione delle altre informazioni che appunto tale browser invia.

1) Cookie Google: tale cookie è stato introdotto da Google cinque anni fa e serve per pubblicare annunci Adsense su www.sviluppo4d.it in modo da mostrare all'utente della pubblicità più mirata in base alla loro cronologia. Gli utenti possono accettare tale cookie oppure disattivarlo nel loro browser visitando la pagina Privacy e Termini. Ulteriori informazioni sulle tipologie e sull'uso che fa Google dei cookie con finalità pubblicitarie possono essere trovate nella pagina web dei Tipi di cookie utilizzati. Anche alcuni partner pubblicitari di Google Adsense possono usare cookie e Web Beacons per tracciare gli utenti.

2) Cookie di Facebook: Questo sito ha alcuni plugin di Facebook che possono tracciare il comportamento dei lettori. Per avere maggiori informazioni si può consultare la pagina per la
Politica della Privacy di Facebook.

3) Google+ attraverso lo script plusone.js potrà trattare i dati personali secondo queste line guida
Google Cookie Policy Privacy

In questo blog hanno accesso server di terze parti o di rete pubblicitarie che usano tale tecnologia per inviare gli annunci nel tuo browser attraverso www.sviluppo4d.it. Tramite il rilevamento del tuo indirizzo IP mostrano la pubblicità più pertinente con i tuoi interessi. Tecnologie simili (quali cookie, web bacons e javascript) possono essere utilizzati dalle reti pubblicitarie di terze parti per misurare l'efficacia dei loro messaggi pubblicitari e per personalizzare il contenuto di tali messaggi.

Il sito www.sviluppo4d.it e il suo amministratore non hanno alcun controllo sui cookie che vengono utilizzati da terze parti quindi per approfondire il tema si consiglia di consultare le politiche della privacy di queste terze parti così come le opzioni per disattivare la raccolta di queste informazioni. L'amministratore di questo sito non può quindi controllare le attività degli inserzionisti di questo blog. È comunque possibile disabilitare i cookie direttamente dal proprio browser.

Queste disposizioni del Garante della Privacy non sono solo italiane ma sono comuni a gran parte del paesi europei. Si possono conoscere le regole di ciascuna giurisdizione consultando il sito Your Online Choices nella propria lingua.

UTILIZZO DI GOOGLE ANALYTICS IN QUESTO SITO
Come detto i cookie analytics sono considerati tecnici se utilizzati solo a fini di ottimizzazione e se gli IP degli utenti sono mantenuti anonimi. Informiamo l'utente che questo sito utilizza il servizio gratuito di Google Analytics. Ricordiamo che i dati vengono usati solo per avere i dati delle pagine più visitate, del numero di visitatori, i dati aggregati delle visite per sistema operativo, per browser, ecc. Gli IP di Google Analytics sono stati anonimizzati. Questi parametri vengono archiviati nei server di Google che ne disciplina la Privacy secondo queste linee guida.

Un utente può disattivare Google Analytics durante la navigazione utilizzando il componenete aggiuntivo disponibile per Chrome, Firefox, Internet Explorer, Opera e Safari.

Si possono inoltre
cancellare i cookie singolarmente per ciascun dominio,
nascondere le ricerche.
settare le impostazioni degli annunci di Google.

NAVIGAZIONE ANONIMA

Una navigazione senza l'utilizzo di cookie tecnici e di profilazione è possibile mediante quella che viene definita navigazione in incognito e che è fattibile con tutti i principali browser.
Ulteriori informazioni sulla disabilitazione dei cookie su Firefox, in inglese.
Ulteriori informazioni sulla disabilitazione dei cookie su Chrome, in inglese
Ulteriori informazioni sulla disabilitazione dei cookie su Internet Explorer, in inglese
Ulteriori informazioni sulla disabilitazione dei cookie su Safari , in inglese
Ulteriori informazioni sulla disabilitazione dei cookie su Opera, in inglese.
Info Info Versioni di OpenSSL usate da 4D
Le librerie OpenSSL usate da 4d e 4d server e il corrispondente supporto a TLS sono i seguenti:

4D openSSL TLS supportato
12.x : 0.9.8j : TLS v1.0
13.x : 1.0.0.d : TLS v1.0
14.x : 1.0.0.d : TLS v1.0
Info Info Posizione della cartella Preferenze di 4d
Dalla versione v12 queste sono le posizioni dei file di preferenza:

WINDOWS
C:\Users\\AppData\Roaming\4D\
C:\Users\\AppData\Roaming\4D Server\

MAC
erano per la v12:
/Users//Library/Preferences/4D/
adesso sono:
/Users//Library/Application Support/4D/ /Users//Library/Application Support/4D Server/


Le posizioni delle finestre e altre dimensioni si trovano:

WINDOWS
C:\Users\Administrator\AppData\Roaming\4D\4D Window Bounds v14\

MAC
/Users//Library/Application Support/4D/4D Window Bounds v14/
Info Info 4D v13.5 : non sono permessi campi unici senza indice
Dalla versione 13.5 4d non salverà più i record che hanno il flag di unico, ma che non hanno un indice assegnato.

Questa procedura permette l'estrazione dalla struttura dei campi unici non indicizzati
cfr http://kb.4d.com/assetid=77024


C_LONGINT($maxTableNumber_l;$currentTable_l)
C_LONGINT($maxFieldCount_l;$currentField_l)
C_LONGINT($dontCare_l) // Per valori GET FIELD PROPERTIES non usati.
C_BOOLEAN($dontCare_f;$isIndexed_f;$isUnique_f)
C_TEXT($logHeader_t;$logRecord_t;$logfile_t)
C_TEXT($delim_t;$lf_t)
C_TIME($logfile_h)
C_TEXT($tableName_t;$fieldName_t;$note_t)

$delim_t:=Char(Tab)
$lf_t:=Char(Carriage return)+Char(Line feed)

$logHeader_t:="Campi unici senza indice:"+$lf_t

$logfile_t:=Get 4D folder(Logs Folder)+"UniciNonIndicizzati"

$logfile_h:=Create document($logfile_t)

If (OK=1)

  SEND PACKET($logfile_h;$logHeader_t)

  $maxTableNumber_l:=Get last table number

  For ($currentTable_l;1;$maxTableNumber_l)
    If (Is table number valid($currentTable_l))
      $maxFieldCount_l:=Get last field number(Table($currentTable_l))
      For ($currentField_l;1;$maxFieldCount_l)
        If (Is field number valid($currentTable_l;$currentField_l))

           // Nota che la seguente riga è spezzata in due:
          GET FIELD PROPERTIES($currentTable_l;$currentField_l;$dontCare_l;\
           $dontCare_l;$isIndexed_f;$isUnique_f;$dontCare_f)

          If (($isUnique_f) & (Not($isIndexed_f)))

           $tableName_t:=Table name(Table($currentTable_l))
           $fieldName_t:=Field name(Field($currentTable_l;$currentField_l))

           $logRecord_t:="["+$tableName_t+"]"+$fieldName_t+$lf_t

           SEND PACKET($logfile_h;$logRecord_t)

          End if
        End if
      End for
    End if
  End for

  CLOSE DOCUMENT($logfile_h)
  SHOW ON DISK($logfile_t)
End if
Web Web Header di risposta da Web
Quando si usa 4D come Web server, normalmente si risponde con le normali pagine come richieste dall'utente con un leader di default (= 200)

Quando invece bisogna rispondere con una pagina che non è quella richiesta, la cosa migliore per rispondere ai casi eccezionali sarebbe quella di mettere il corretto header.

Ad esempio, se l'url non è riconosciuto puoi mandare l'utente alla pagina che vuoi, dovresti impostare questo header

ARRAY TEXT($atHeaders;2)
ARRAY TEXT($atValues;2)
$atHeaders{1}:="X-VERSION"
$atValues{1}:="HTTP/1.1"
$atHeaders{2}:="X-STATUS"
$atValues{2}:="404 Not Found"
WEB SET HTTP HEADER($atHeaders;$atValues)
WEB SEND FILE("pagina_errore.html")

Un altro header utile:
"302 Moved Temporarily" (equivalente al redirect) cfr http://www.sviluppo4d.it/Detail_Faq_Display?ID=632&title=Alternativa+al+comando+SEND+HTTP+REDIRECT

Per una funzione non disponibile si dovrebbe usare:
"501 Not implemented"

Da notare che usualmente si vedono due tipi di errore gestiti automaticamente da 4D Web Server:
"500 Internal server error" : il codice ha incontrato una condizione non prevista, di solito errore puro
"503 Service Unavailable" : hai superato il numero di richieste contemporanee accettate ( di solito legato ad un parametro di configurazione )

Qui l'elenco ufficiale:
http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
Novita' Novita' 4d su Mac OS X 10.9
Su Mac OS X 10.9 Maverick le applicazioni che non sono davanti (in 'foreground') vengono automaticamente abbassate di priorità con la nuova funzione "App Nap".

Questo è ovviamente un problema se il 4d Server viene usato su un 10.9: in questo caso basta andare nella finestra Info del Finder per l'app Server e impostare il flag "Impedisci App Nap"
Tecniche Tecniche Testo di un pulsante su più righe
E' possibile scrivere il testo di un pulsante in modo che venga visualizzato su due righe. Non bisogna usare il classico Carriage Return, bensì il carattere "\" ("\\" nel code editor).

Questa caratteristica è utilizzabile solo su 3D button, 3D radio button e 3D check box.
Info Info Ripristino della configurazione di backup
Se si sceglie di effettuare manualmente il backup con il metodo:

CONFIRM("Eseguo il salvataggio automatico?";"Sì";"No")
If (OK=1)
  BACKUP
End if

Se la destinazione non è disponibile (ad esempio una pen drive) 4D modifica il percorso di backup con la cartella della struttura.
Se si salva in un file BackupSave.xml la copia della configurazione corretta, si può modificare il metodo precedente così:

CONFIRM("Eseguo il salvataggio automatico?";"Sì";"No")
If (OK=1)
  DELETE DOCUMENT(getPathname (Structure file)+"Preferences\\Backup\\Backup.xml")
  COPY DOCUMENT(getPathname (Structure file)+"Preferences\\Backup\\BackupSave.xml";u_PathnameOnly (Structure file)+"Preferences\\Backup\\Backup.xml")
  BACKUP
End if
Comandi Comandi Impostare il livello di cifratura SSL
Il comando SET DATABASE PARAMETER con l'opzione 64 (SSL Cipher List) permette di impostare il livello di cifratura SSL.

Ad esempio è possibile eseguire questo codice per disabilitare l'SSL2 e attivare solo l'SSL3 per la versione di 4d v11:

STOP WEB SERVER
SET DATABASE PARAMETER (SSL Cipher List;"HIGH:!SSLv2:!EXP:!ADH:!aNULL:!eNULL:!NULL")
START WEB SERVER

Alcune informazioni su come scrivere questo parametro si può leggere la documentazione del Comando Ciphers di OpenSSL.

Nella v13.3 i valori di default sono:
TLSv1/SSLv3, Cipher : AES256-SHA AES(256)

Le altre cifrature accettate sono
SSL2 ciphers: nessuno

SSL3 ciphers:
CAMELLIA256-SHA 256 bit
AES256-SHA 256 bit
DES-CBC3-SHA 168 bit
SEED-SHA 128 bit
CAMELLIA128-SHA 128 bit
AES128-SHA 128 bit
IDEA-CBC-SHA 128 bit
RC4-SHA 128 bit
RC4-MD5 128 bit
DES-CBC-SHA 56 bit

TLS1 ciphers:
CAMELLIA256-SHA 256 bit
AES256-SHA 256 bit
DES-CBC3-SHA 168 bit
SEED-SHA 128 bit
CAMELLIA128-SHA 128 bit
AES128-SHA 128 bit
IDEA-CBC-SHA 128 bit
RC4-SHA 128 bit
RC4-MD5 128 bit
DES-CBC-SHA 56 bit
Info Info Posizione delle risorse locali *
Nelle installazioni Client/Server 4D registra in locale delle risorse che velocizzano i collegamenti successivi e che sono automaticamente aggiornati senza che l'utente debba intervenire.

Dalla v11 la posizione di queste risorse è in cartelle registrate in queste posizioni:

Windows XP:
{Disco:}\Documents and Settings\{nome_utente}\Local Settings\Application Data\Nomeprogramma_indirizzo

Windows Vista/7
{Disco:}\Users\{nome_utente}\AppData\Local\4D\Nomeprogramma_indirizzo

Mac
{Disco}Users\{nome_utente}\Libreria\Cache\4D\Nomeprogramma_indirizzo


Nel caso in cui il client è incorporato nell'applicazione, le cartelle locali sono:

Windows Vista/7
{Disk}:\Users\{nome_utente}\AppData\Local\Nomeprogramma

Mac OS X
{Disk}:Users:{nome_utente}:Library:Caches:Nomeprogramma Client


Nel caso ci fossero problemi di accesso a queste cartelle è sempre possibile creare una cartella "ClientLocal" vicino al 4d usato come client

Su installazioni Terminal Server/Citrix purtroppo le cartelle Local e Local Settings non possono essere inserite nel profilo, quindi ogni connessione richiederebbe di scaricare sempre le informazioni dal server. Se si vuole evitare questo è possibile integrare direttamente la cartella dell'applicazione (contenente una sottocartella ClientLocal) nel profilo di roaming. Ovviamente in questo caso deve esserci un 4d usato come client per ogni utente collegato.
Tecniche Tecniche Duplicazione RECORD con SUBRECORD
Le nuove versioni di 4D non duplicano piu' i subrecord all'interno del record ed il campo id_added_by_converter non e' editabile, ne avevo necessita' per cui ho fatto questa routine (spero esista un metodo piu' semplice)

Occorre preventivamente creare un set del record da duplicare ed un set del record duplicato (ricordarsi di cancellarli al termine) poi :

DuplicaSubrecords (->[TABLE];->[TABLE]Subrecord;->[TABLE_Subrecord];->[TABLE_Subrecord]id_added_by_converter)


    // DUPLICAZIONE SUBRECORDS

$p_TABLErecord:=$1 // Puntatore alla Tabella RECORD
$p_TABLEsubrecord:=$2 // Puntatore al campo SUBRECORD DEL RECORD
$p_TABLENewsubrecord:=$3 // Puntatore alla Tabella NEW SUBRECORD
$p_Id:=$4 // Puntatore al campo id_added_by_converter

$NumeroTABLE:=Table($p_TABLENewsubrecord)
USE SET("OLD") // Richiamo il record originale
QUERY($p_TABLENewsubrecord->;$p_Id->=Get subrecord key($p_TABLEsubrecord->))
$NumeroSubrecords:=Records in selection($p_TABLENewsubrecord->)
If ($NumeroSubrecords>0)
  USE SET("NEW") // Richiamo il record copia
  For ($i;1;$NumeroSubrecords)
    CREATE SUBRECORD($p_TABLEsubrecord->) // Creo l'aggancio al record
  End for
  SAVE RECORD($p_TABLErecord->)
  USE SET("OLD")
  $NumeroCampi:=Get last field number($p_TABLENewsubrecord)
  ARRAY POINTER($p_ElementoCampo;$NumeroSubrecords*$NumeroCampi)
  For ($i;1;$NumeroSubrecords)
    $P_RECORD:=($i-1)*$NumeroCampi
    For ($k;1;$NumeroCampi)
      $P_Vettore:=$P_RECORD+$k // Calcolo l'elemento del vettore
      $p_ElementoCampo{$P_Vettore}:=Get pointer("$var_"+String($k)) // Associo il puntatore
      $p_Campo:=Field($NumeroTABLE;$k) // Puntatore al campo da prelevare
      $p_ElementoCampo{$P_Vettore}->:=$p_Campo-> // Momorizzo il valore del campo sulla variabile
    End for
    NEXT RECORD($p_TABLENewsubrecord->)
  End for
  USE SET("NEW")
  QUERY($p_TABLENewsubrecord->;$p_Id->=Get subrecord key($p_TABLEsubrecord->))
  $NumeroSubrecords:=Records in selection($p_TABLENewsubrecord->)
  ON ERR CALL("ErrorIdSubrecord") // Filtra Errore su assegnazione campo id_added_by_converter (Metodo ErrorIdSubrecord VUOTO)
  For ($i;1;$NumeroSubrecords)
    $P_RECORD:=($i-1)*$NumeroCampi
    For ($k;1;$NumeroCampi)
      $P_Vettore:=$P_RECORD+$k // Calcolo l'elemento del vettore
      $p_Campo:=Field($NumeroTABLE;$k) // Puntatore al campo da assegnare
      $p_Campo->:=$p_ElementoCampo{$P_Vettore}-> // Assegno il valore dalla variabile al campo
    End for
    SAVE RECORD($p_TABLENewsubrecord->)
    NEXT RECORD($p_TABLENewsubrecord->)
  End for
  UNLOAD RECORD($p_TABLENewsubrecord->)
  ON ERR CALL("")
  SAVE RECORD($p_TABLErecord->) // Forse non serve
End if
2
Info Info Dove si trovano i file 4DLINK
Il file .4DLINK indica il percorso e le opzioni per aprire una struttura, sia per 4d Mono che Server.

Vengono creati automaticamente da 4D per mostrarli nei recenti, ma si possono recuperare, riutilizzare direttamente ed eventualmente modificare.

Per le versioni v11 e v12 il file si trovano nella cartella:

• Windows Vista: C:\Users\UserName\AppData\Roaming\4D\Favorites v11\
• Windows XP: C:\Documents and Settings\UserName\Application
Data\4D\Favorites v11\
• Mac OS: Users/UserName/Library/Preferences/4D/Favorites v11/


Per la versione v13:

• Windows: C:\Users\UserName\AppData\Roaming\4D\Favorites v13\

• Mac OS: /Users/UserName/Library/Application Support/4D/Favorites v13/

dove UserName è il nome dell'utente del sistema.
Info Info Adattare pagine web su Safari IOS
Quando predisponete una pagina web che deve essere visualizzata su device mobili con browser HTML5, tipo Safari Mobile su iPhone e iPad, è possibile utilizzare un metatag specifico che adatta il contenuto allo schermo.

La riga va inserita sotto il tag <head> :

<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">

Per ulteriori informazioni guarda la Safari Web Content Guide
Codice Codice Percorso della cartella Documenti
Nella v13:

$0:=System Folder(Documents folder)


Nella v12:

// Codice di Maurizio Zanni

C_TEXT($_vt_Path)

C_LONGINT($_vl_Type)
$_vl_Type:=Desktop

//Ritorna il Path del Desktop
$_vt_Path:=System Folder($_vl_Type)

//Elimina il Separatore alla fine del Path
$i:=Length($_vt_Path)
$_vt_Path:=Substring($_vt_Path;1;$i-1)

//Ritorna il Path alla cartella Padre del Desktop
$i:=Length($_vt_Path)
While ($_vt_Path≤$i≥#Folder Separator) & ($i>0)
        $i:=$i-1
End while
$_vt_Path:=Substring($_vt_Path;1;$i-0)

//Aggiunge la Cartella Documents con il Separatore finale (Mac o Win)
$_vt_Path:=$_vt_Path+"Documents"+Folder Separator

$0:=$_vt_Path
Info Info Caratteri non utilizzabili in un testo in modalità Unicode
A partire dalla versione 11 è possibile utilizzare il database in modalità Unicode.

In questa modalità, tre caratteri non possono essere memorizzati all'interno di un testo della base dati, e sono:
0
65534 (FFFE)
65535 (FFFF)
Tecniche Tecniche Limite fisico degli indici B-Tree per i campi Text
È importante sapere che, quando si indicizza un campo di tipo testo, il limite fisico di un indice B-Tree è 1024 caratteri, e dunque se si indicizzano contenuti di lunghezza maggiore la ricerca può fallire.
Nessun limite invece per quel che riguarda gli indici a keyword.
Info Info La linea laterale del Method Editor
Sulla parte sinistra del nuovo Method Editor di 4D è possibile vedere, accanto al numero di linea, una piccola linea verticale colorata.

Il colore è verde per indicare che la riga non è stata modificata dall'ultimo salvataggio, giallo se la riga è stata modificata.
Info Info Come utilizzare con 4d i lettori barcode per iPhone, iPod, iPad
I lettori di barcode della Infinite Peripherals, Linea Pro per iPhone e iPod e Infinea Tab per iPad, sono quelli usati da Apple nei propri AppleStore.

Per utilizzarli con un nostro gestionale in 4d (a parte scrivere un'app nativa in IOS) potete usare una soluzione abbastanza semplice:
- da 4d pubblicate via web le pagine con le funzioni che vi servono
- scaricare l'app "Nexus Barcode" che è gia pubblicata su AppStore
- nelle impostazioni dell'app mettete l'indirizzo della vostra pagina di 4d

A questo punto quando aprite l'app si carica la pagina web del vostro gestionale:
- fate click (ops tap) sul campo da inserire
- premete il tasto del lettore di barcode che va a scrivere nel campo

Oppure:
- nella preparazione della pagina predisponete un javascript che si aspetta un solo parametro, tipo: function loadBarcode(codice) {}
- nelle impostazioni dell'app scrivete il nome della funzione: loadBarcode

In questa modalità non c'è bisogno di cliccare (tappare) il campo dove inserire il codice, basta usare il lettore del barcode; a parte la comodità di un passaggio in meno, l'altro vantaggio è che non serve far apparire la tastiera che sullo schermo dell'iPod significa guadagnare un bel po' di spazio

Per l'hardware dei lettori ci si può rivolgere al distributore italiano dei lettori barcode per iPhone, iPod, iPad Cidroid, divisione della Nexus.

Cidroid LineaPro

Cidroid InfineaTab
Info Info Limitare il numero di caratteri in una variabile alfanumerica
Una delle prime FAQ pubblicate su Sviluppo4D riguardava la limitazione del numero di caratteri inseribili in un campo Alpha.

Eccone una versione aggiornata:
Case of
      : (Form event=On After Edit)
      If (Length(Get edited text)>=vLength)
           $textvariable:=Substring(Get edited text;1;vLength)
      End if
End case

A vLength può essere sostituita la lunghezza del campo, nei casi in cui è possibile.

A $textvariable potrebbe essere sostituito Self->, ma in questo caso il metodo non funziona ad esempio sugli elementi degli array di una listbox.
1
Info Info Eseguire VB Script in 4D
Utilizzando il metodo di Keisuke Miyako per l'esecuzione di un VB script, vediamo un esempio di conversione di un file utilizzando MS Word.

Ecco il testo di uno script che apre un file e lo salva in formato solo testo:


Set objWord = CreateObject("Word.Application")
Set objDoc = objWord.Documents.Open("C:\codici.doc")
Const wdFormatText = 2
objDoc.SaveAs "C:\codici.txt", wdFormatText
objWord.Quit




Ecco il metodo (lievemente modificato) di Keisuke Miyako:

C_TEXT($1;$0)
C_BLOB($2)

C_LONGINT($platform_l)
PLATFORM PROPERTIES($platform_l)

If ($platform_l=Windows)

$script_folder_path_t:=Get 4D folder(Current Resources folder)+"vbs\\"
$script_file_path_t:=$script_folder_path_t+Replace string($1;"/";"\\";*)

      If (Test path name($script_file_path_t)=Is a document)

           SET ENVIRONMENT VARIABLE("_4D_OPTION_HIDE_CONSOLE";"true")
           C_BLOB($standard_input_x;$standard_output_x;$standard_error_x)

           If (Count parameters=2)
           $standard_input_x:=$2
           //patch to counter data loss caused by CRLF's in input stream
           SET BLOB SIZE($standard_input_x;BLOB size($standard_input_x)+8166;0)
           End if

           LAUNCH EXTERNAL PROCESS("cscript //Nologo //U \""+$script_file_path_t+"\"";$standard_input_x;$standard_output_x;$standard_error_x)
           $standard_output_t:=Convert to text($standard_output_x;"UTF-16LE")

           If (BLOB size($standard_error_x)#0) & (BLOB size($standard_output_x)=0)
           $0:=Convert to text($standard_error_x;"UTF-16LE")
           Else
           $0:=$standard_output_t
           End if

      End if

End if
Tecniche Tecniche Cosa fare se 4D si chiude all'avvio
Alcune istruzioni veloci su come intervenire nel caso in cui 4d si chiude all'avvio.

Se si riesce ad entrare come Designer basterà verificare la procedura di startuo legata allo specifico user.

Se non si riesce proprio ad entrare, provare una delle seguenti opzioni (una alla volta!)

1. Sei sicuro di essere entrato come Designer?
Se per caso hai impostato un utente di default non fa andare in ambiente Designer e quindi potrebbe non intercettare eventuali errori.
Per verificare tieni premuto il maiuscolo al lancio del programma, così ti appare la lista degli utenti.

2. provare a togliere temporaneamente i plugin

3. cancellare le preferenze di 4d (attento a tenere il file delle licenze)

4. fare una verifica della struttura con 4d tools

5. recuperare l'ultima copia della struttura funzionante

5. provare a verificare la struttura con un'utilitty tipo SanityCheck della Committedsoftware, che funziona fino alla versione 2004.5
http://www.committedsoftware.com/sanitycheck.html
Info Info 4d e Mountain Lion
Ecco i risultati dei primi test con le versioni di 4d v12.4 e v13.1 su Mountain Lion.

Restano aperti solo quattro problemi, che saranno sicuramente fissati nelle prossime versioni (subito nelle prossime versioni Hotfix per i Partner):

2 problemi importanti riguardano un crash dopo:
- il cambio di stampante da codice
- la stampa dagli editor di Etcihette o dal Quick Report

2 solo cosmetici riguardano:
- il comando OBJECT SET ENABLE non mette in grigio il testo disabilitato
- il colore della selezione di record nelle maschere di tipo Lista

Inoltre 4d sas dovrà gestire in qualche modo la nuova gestione di Gatekeeper, per certificare le prossime versioni di 4d con Apple.

Da segnalare un problema con il web server Apache integrato in OS X: se la condivisione web era attiva prima di aggiornare a Mountain Lion, 4d non pèotrà accedere alla porta 80 con il suo Web server.
Purtroppo in Mountain Lion non c'è più la preferenza che stoppa Apache, per cui bisognerà interromperlo con il comando da terminale:
sudo apachectl stop

cfr http://www.4d.com/blog/information-4d-mountain-lion.html
Codice Codice Come creare una plist per Mac OS X o IOS
Il formato XML plist è lo standard con cui sono scritte ad esempio le preferenze dei vari programmi su Mac OS X.

Il formato è letto nativamente dalle applicazioni scritte in XCode, come ad esempio programmi per iPhone e iPad.

L'esempio successivo mostra come creare una plist per ad esempio inviare dei dati strutturati ad un applicativo su iOS in modo semplice e veloce: infatti un xml generico andrebbe ogni volta interpretato, mentre la plist può essere letta direttamente come un NSDictionary.

    ` ----------------------------------------------------
    ` User name (OS): Umberto Migliore
    ` Date and time: 08-02-11, 12:22:51
    ` ----------------------------------------------------
    ` Method: nx_crea_plist
    ` Description:
    `mostra come creare un documento plist:
    `
    `<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
    `<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    `<plist version="1.0">
    ` <dict>
    ` <key>Author</key>
    ` <string>William Shakespeare</string>
    ` <key>Title</key>
    ` <string>Macbeth</string>
    ` <key>Lines</key>
    ` <array>
    ` <string>It is a tale told by an idiot,</string>
    ` <string>Full of sound and fury, signifying nothing.</string>
    ` </array>
    ` <key>Birthdate</key>
    ` <integer>1564</integer>
    ` </dict>
    `</plist>
    `
    ` Parameters
    ` ----------------------------------------------------
C_TEXT($autore;$titolo)
C_LONGINT($annonascita)
ARRAY TEXT($citazione;0)

    `=== preparo i dati
$autore:="William Shakespeare"
$titolo:="Macbeth"
$annonascita:=1564
APPEND TO ARRAY($citazione;"It is a tale told by an idiot,")
APPEND TO ARRAY($citazione;"Full of sound and fury, signifying nothing.")

    `=== creo la plist
$xml_ref:=DOM Create XML Ref("plist";"";"version";"1.0")

    `=== dict principale che contiene tutto
$dict:=DOM Create XML element($xml_ref;"dict")

$key:=DOM Create XML element($dict;"key")
DOM SET XML ELEMENT VALUE($key;"Author")
$value:=DOM Create XML element($dict;"string")
DOM SET XML ELEMENT VALUE($value;$autore)

$key:=DOM Create XML element($dict;"key")
DOM SET XML ELEMENT VALUE($key;"Title")
$value:=DOM Create XML element($dict;"string")
DOM SET XML ELEMENT VALUE($value;$titolo)

$key:=DOM Create XML element($dict;"key")
DOM SET XML ELEMENT VALUE($key;"Lines")
$array:=DOM Create XML element($dict;"array")
For ($riga;1;Size of array($citazione))
  $value:=DOM Create XML element($array;"string")
  DOM SET XML ELEMENT VALUE($value;$citazione{$riga})
End for

$key:=DOM Create XML element($dict;"key")
DOM SET XML ELEMENT VALUE($key;"Birthdate")
$value:=DOM Create XML element($dict;"integer")
DOM SET XML ELEMENT VALUE($value;$annonascita)

    `=== chiude l'xml, aggiunge lo header e ritorna un testo
DOM EXPORT TO VAR($xml_ref;$testo)
DOM CLOSE XML($xml_ref)
$header:="<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n"
$testo:=Insert string($testo;$header;Position("<plist";$testo))

ALERT($testo)  ` $0:=$testo
1
Comandi Comandi Indentazione XML
Quando si crea un XML, i comandi di 4d lo creano con tutta l'indentazione necessaria ad una più facile lettura.

Però se l'xml è utilizzato per comunicazioni via wan (server to server, mobile to server, etc) in produzione è meglio risparmiare in dimensioni dei messaggi, ad esempio togliendo l'indentazione: su file complessi con molti livelli di indentazione il risparmio può essere notevole.

Fino alla v11 si usava il secondo parametro del comando
DOM SET XML OPTION

Dalla v12 il comando è stato rinominato
DOM SET XML OPTION -> DOM SET XML DECLARATION

e invece per le opzioni più generiche si usa il comando più specifico
XML SET OPTION

Questo comando ha diverse opzioni, nel caso specifico la sintassi è:

DOM SET XML OPTION($idRef; XML Indentation; XML No indentation)
Codice Codice Ruotare un'immagine usando SVG
Questo codice è un esempio di utilizzo del componente incluso in 4d per gestire i comandi SVG; lo scopo del metodo è di ruotare di 90 gradi un'immagine, ad esempio per raddrizzare una foto.

    // ----------------------------------------------------
    // User name (OS): Umberto Migliore
    // Date and time: 14-02-11, 11:41:14
    // ----------------------------------------------------
    // Method: nx_svgRuotaQuartoDestra
    // Description
    // Ruota un immagine di un quarto di giro a destra
    //
    // Parameters
    // ----------------------------------------------------

C_PICTURE($immagine;$1;$0)
$immagine:=$1
PICTURE PROPERTIES($immagine;$larga;$alta)
$maggiore:=Choose($larga>$alta;$larga;$alta)
$svg:=SVG_New ($alta;$larga)
$img:=SVG_New_embedded_image ($svg;$immagine;0;0)
SVG_SET_TRANSFORM_ROTATE ($svg;90;$maggiore/2;$maggiore/2)
If ($larga>$alta)
  SVG_SET_TRANSFORM_TRANSLATE ($svg;0;$larga-$alta)
End if
$immagine:=SVG_Export_to_picture ($svg;0)
SVG_CLEAR ($svg)
$0:=$immagine
1
Info Info Autenticazione SOAP
I servizi webservice possono richiedere l'autenticazione in diversi modi:

1. lo standard http BASIC
-> si può usare il comando WEB SERVICE AUTHENTICATE ("nome", "password"; 1)

2. lo standard http DIGEST
-> si può usare il comando WEB SERVICE AUTHENTICATE ("nome", "password"; 2)

3. uno dei due standard http, ma con un proxy http intermedio:

-> si usa il doppio comando
WEB SERVICE AUTHENTICATE ("nome", "password", 0) `può essere BASIC o DIGEST
WEB SERVICE AUTHENTICATE ("nome2", "password2", *) `dati di accesso al proxy

4. può essere del tipo SOAP HEADER, cioè inclusa nel corpo della SOAP

$xml:=DOM Create XML Ref("auth")
$utente:=DOM Create XML element($xml;"username")
DOM SET XML ELEMENT VALUE($utente;"nome")
$password:=DOM Create XML element($xml;"password")
DOM SET XML ELEMENT VALUE($password;"password")
SET WEB SERVICE OPTION(Web Service SOAP Header,$xml)
DOM CLOSE XML($xml)

Sono eventualmente da verificare che i nodi siano "username" e "password"
Codice Codice InStrRev trova la prima posizione di una stringa partendo dalla fine
Come tutti sappiamo, la funzione Position() di 4D restituisce la posizione del primo carattere trovato, ma partendo da sinistra.

In giro ho trovato questo ciclo per trovare la posizione della prima occorrenza di una stringa inclusa in un'altra a partire dalla destra della stringa.
Un po come InStrRev di VB.

C_INTEGER($Pos;$start;$lengthfound;$Result)
C_TEXT($Temp)
  // Ricava la path della cartella preferenze
// Replace string(... Aggiunge un Folder separator alla stringa ricavata:
// Se Folder separator esiste, sostituisce i due Folder separator risultanti con una stringa vuota
// Se Folder separator esiste, non fa' nulla
// In ogni caso la stringa ricavata non terminerà con Folder separator !

$Temp:=Replace string(Get 4D folder(Active 4D Folder)+Folder separator;Folder separator+Folder separator;"")
$Pos:=0
$start:=1
Repeat
  $Result:=Position(Folder separator;$Temp;$start;$lengthfound)
  If ($Result#0)
    $Pos:=$Result
  End if
  $start:=$start+$lengthfound
Until ($Result=0)
<>g_PathPreferences:=Substring($Temp;1;Length(Substring($Temp;1;$Pos)))+Folder separator

Sicuramente funzionante ma, a mio avviso, un po' troppo 'contorta'.
Si puo' semplificare cosi:
    
C_TEXT($Temp)
C_INTEGER($Conta)
    // Ricava la path della cartella preferenze
$Temp:=Replace string(Get 4D folder(Active 4D Folder)+Folder separator;Folder separator+Folder separator;"")
For ($Conta;Length($Temp);1;-1)
  If (Substring($Temp;$Conta;1)=Folder separator)
    $Temp:=Substring($Temp;1;$Conta)
    $Conta:=1
  End if
End for
<>g_PathPreferences:=$Temp+Folder separator

Oltre ad avere un codice piu' leggibile, abbiamo risparmiato tre righe di procedura (a parte le note) e dichiarato
due variabili contro cinque della procedura precedente.

Non è il massimo ...ma con la crisi che incombe, bisogna centellinare tutto.
Codice Codice Creare un file di testi UTF-8 con BOM
Il testo in 4d era in Mac ASCII fino alla versione 2004, dalla v11 è in UTF-16 (a meno che non abbiate lasciato la compatibilità Ascii del db)

Quando si esporta un file in Unicode è necessario normalmente indicare in che formato sono i caratteri che occupano 2 byte (big-endian o little-endian) con un prefisso chiamato un BOM (Byte Order Mark). In realtà in UTF-8 si tende ad esportare i caratteri in byte singoli quindi in linea di massima non ci sono problemi di ordinamento dei byte, e non servirebbe.

Però alcune applicazioni se lo aspettano comunque, quindi a volte è necessario aggiungerlo, come ad esempio con questa procedura:

C_TEXT($1;$testo_t)
C_BLOB($blob_b;$bom_b)

$testo_t:=$1

SET BLOB SIZE($bom_b;3)
$bom_b{0}:=239 ` EF
$bom_b{1}:=187 ` BB
$bom_b{2}:=191 ` BF

CONVERT FROM TEXT($testo_t;"UTF-8";$blob_b)

$doc_h:=Create document("")
If (OK=1)
  SEND PACKET($doc_h;$bom_b)
  SEND PACKET($doc_h;$blob_b)
  CLOSE DOCUMENT($doc_h)
End if
Info Info [v13] Nuova funzionalità dei comandi statistici
I comandi Average, Max, Min, Std deviation, Sum, Sum squares e Variance che storicamente si usavano solo nella stampa dei rapporti (dopo un comando Accumulate) adesso funzionano anche sulla selezione corrente o su un array.

L'effetto sulla ottimizzazione del codice è immediato:
dove prima ad esempio per avere la somma di un array occorreva ciclare sui suoi elementi adesso basta scrivere $totale:=Sum($array).

Accesso

User:
Pass: Accedi

Cerca

Se non trovi le informazioni che cerchi scrivi a aiuto@sviluppo4d.it

4D Principali

4D Discussioni

Faq random


Crediti

Dominio registrato da ZetaNet
Sito realizzato da Nexus srl
4D SQL 11.9.0 offerto da 4D & Italsoftware
Icone di FAMFAMFAM
Moderato da Umberto Migliore
303 utenti registrati

Pagina servita il 29/03/24 alle 10:38:17 Valid HTML 4.01! Valid CSS!

Mutuo Facile, iDigitalScout, iDigitalTags e altre app di Nexid srl per iPhone e iPad

Cidroid, distributore italiano lettori barcode per IOS Apple iPhone, iPod, iPad