Gambas-it

Gambas3 => Programmazione => Topic aperto da: dex - 15 Marzo 2019, 07:44:32

Titolo: [Risolto] Funzione conversione float
Inserito da: dex - 15 Marzo 2019, 07:44:32
Ciao raga mi serve capire come convertire testo in numero float senza errori

mi arrivano stringhe con numeri ma alcune sono sporche tipo: 25ò25   87)756


le devo convertire in float oppure ritornarmi 0 se sporca.

tipo:
Codice: [Seleziona]
Print Cinst(Val(stringa))

solo che cosi quando arrivano sporche mi va in errore, come posso rimediare?
Titolo: Re:Funzione conversione float
Inserito da: Gianluigi - 15 Marzo 2019, 10:01:39
Una cosa così dovrebbe andare bene:

Codice: [Seleziona]
  If Not IsNull(Val("87)756")) Then
    Print "È un numero"
  Else
    Print "Non è un numero"
  Endif

Anche più veloce:
Codice: [Seleziona]
  If Val("87)756") Then
    Print "È un numero"
  Else
    Print "Non è un numero"
  Endif

Naturalmente questo codice fa passare qualunque stringa interpretabile da Val, tienine conto.
Titolo: Re:Funzione conversione float
Inserito da: dex - 15 Marzo 2019, 10:41:09
Ciao Gianluigi

avevo già provato qualcosa di simile con val, il problema è che le stringhe contenenti le cifre hanno separatore decimale diverso, alcune hanno il punto altre la virgola, e val ora non ricordo con quale, ne riconosceva soltanto una.
ho fatto delle prove anche conuna struttura if e chr che mi convertiva in 0 tutti i caratteri alfanumerici, ma anche li non andava bene in quanto una stringa tipo:
12klh45 diventava 1200045.

L'unica possibilità è una struttura if che controlla singolarmente i caratteri e se ne trova di alfanumerici cambia il contenuto della stringa in 0, data la quantità delle stringhe richiede molte risorse.
speravo in una cosa più semplice tipo isnumber ecc..
Titolo: Re:Funzione conversione float
Inserito da: Gianluigi - 15 Marzo 2019, 10:43:20
Per me ti stai sbagliando, prova meglio.
Val riconosce sia la virgola che il punto.

Rettifica: Hai ragione riconosce solo la virgola.
La cosa è normale in quanto Val localizza.
Potresti provare prima con un Replace():
Codice: [Seleziona]
If "876.00" Like "*.??" Then Print Replace("876.00", ".", ",")

C'era un refuso, Print scordai!
Titolo: Re:Funzione conversione float
Inserito da: dex - 15 Marzo 2019, 10:56:54
devo provare a passare replace prima
Titolo: Re:Funzione conversione float
Inserito da: Gianluigi - 15 Marzo 2019, 11:00:12
Naturalmente se hai dei numeri tipo 12,345.67 la cosa si fa più complicata.
Ma se hai solo separatori decimali il codice di prima dovrebbe funzionare bene.
Titolo: Re:Funzione conversione float
Inserito da: dex - 15 Marzo 2019, 11:43:12
in effetti mi capitano anche quelli.
devo fare un if che controlla, se trova . e , mi deve togliere la virgola e poi con replace converto la virgola in punto
Titolo: Re:Funzione conversione float
Inserito da: Gianluigi - 15 Marzo 2019, 12:44:30
Penso che una cosa così dovrebbe andare:
Codice: [Seleziona]
Public Sub Main()

  Dim s As String

  '' Se il numero più grande è una cosa del genere s = "123,456,789,987.89"
  '' parti da quel pattern e scali fino a:
  s = "123,456.78" '' che funziona anche su 12,345.67 e 1,234.56
  If s Like "*,*,*,*.??" Then
    Print Scan(s, "*,*,*,*.*")[0] & "." & Scan(s, "*,*,*,*.*")[1] & "." & Scan(s, "*,*,*,*.*")[2] & "." & Scan(s, "*,*,*,*.*")[3] & "," & Scan(s, "*,*,*,*.*")[4]
  '' ...
  Else If s Like "*,*.??" Then
    Print Scan(s, "*,*.*")[0] & "." & Scan(s, "*,*.*")[1] & "," & Scan(s, "*,*.*")[2]
  Endif

End

Naturalmente tenendo anche conto dei numeri senza separatori decimali...
Titolo: Re:Funzione conversione float
Inserito da: dex - 15 Marzo 2019, 17:20:39
Buona idea
visto che i miei numeri sono più piccoli di quello che hai ipotizzato dovrebbe venire più snello.

Grazie Gianluigi
Titolo: Re:Funzione conversione float
Inserito da: Gianluigi - 15 Marzo 2019, 17:28:29
Prego  :)
Scan è molto potente e veloce solo ricordati di passarlo a una matrice così fai prima e meglio  :ciao:
Titolo: Re:Funzione conversione float
Inserito da: dex - 15 Marzo 2019, 17:36:50
dice che conviene metterlo in matrice?
i miei dati al massimo sono 1,000.2222

non ho mai usato scan

se dovesse arrivare 5.666,3333, da come ho letto il tuo codice non dovrebbe fare nulla, giusto?
Titolo: Re:Funzione conversione float
Inserito da: Gianluigi - 15 Marzo 2019, 17:40:40
No, se hai solo una virgola e un punto non serve.
Usi solo Like e Scan per tutto e non ti serve più Replace.
Titolo: Re:Funzione conversione float
Inserito da: Gianluigi - 15 Marzo 2019, 17:45:09


se dovesse arrivare 5.666,3333, da come ho letto il tuo codice non dovrebbe fare nulla, giusto?

Devi vedere quali sono i dati che ti arrivano e in base a quelli ti crei i pattern.
Se vuoi puoi scrivere qui tutte le varianti e io ti scrivo il codice, ma credo che tu non ne abbia bisogno.
Comunque "a eshposizione"
Titolo: Re:Funzione conversione float
Inserito da: dex - 15 Marzo 2019, 17:46:14
ho appena letto il wiki di scan
caspita è molto versatile, potrei anche utilizzarlo per pulire le mie stringhe dai caratteri alfanumerici
Titolo: Re:Funzione conversione float
Inserito da: dex - 15 Marzo 2019, 17:48:44
semplice a me i dati arrivano:

1234
1234.55
1.222,235569
3,898.4444

ho solo queste varianti, quando i decimali superano 4 le taglio
Titolo: Re:Funzione conversione float
Inserito da: Gianluigi - 15 Marzo 2019, 17:56:21
semplice a me i dati arrivano:

1234
1234.55
1.222,235569
3,898.4444

ho solo queste varianti, quando i decimali superano 4 le taglio

Ma tu come ottieni queste stringhe, le tagli a quattro prima o dopo?
Può anche esserci un numero con tre decimali?
Può esserci un numero con decine o centinaia di migliaia?
Titolo: Re:Funzione conversione float
Inserito da: dex - 15 Marzo 2019, 18:12:48
le taglio dopo solo se hanno più di quattro.
senza decimali o con massimo 4 le converto direttamente in float

ho provato scan
funziona bene
non mi tocca i numeri
1234
1234.55
1.222,235569
che posso convertire tranquillamente togliendo il punto con replace

mi modifica il numero
3,898.4444 come mi serve

ora dovrei fare una struttura che mi converta questi numeri con decimali diversi tipo

3,898.4
3,898.44
3,898.444
3,898.4444

oltre i quattro non mi serve solo che scan non opererebbe oltre 4 decimali e mi tocca tagliarli prima




Titolo: Re:Funzione conversione float
Inserito da: dex - 15 Marzo 2019, 18:25:35
Codice: [Seleziona]
If s Like "*,*.?" Then
    Print
else If s Like "*,*.??" Then
   Print
else If s Like "*,*.???" Then
print
else If s Like "*,*.????" Then
print
Endif

in questo modo dovrei risolvere, solo che se i decimali superano 4?

mi possono capitare cifre sballate con decine o molte decine di decimali (sono quelle che mi davano errore di segmentazione)
Titolo: Re:Funzione conversione float
Inserito da: Gianluigi - 15 Marzo 2019, 18:34:45
Codice: [Seleziona]
If s Like "*,*.?" Then
    Print
else If s Like "*,*.??" Then
   Print
else If s Like "*,*.???" Then
print
else If s Like "*,*.????" Then
print
Endif

in questo modo dovrei risolvere, solo che se i decimali superano 4?

mi possono capitare cifre sballate con decine o molte decine di decimali (sono quelle che mi davano errore di segmentazione)

Occorre stare molto attenti alle successioni dei pattern di ricerca.
Ad esempio con questi pattern non rileveresti i numeri con più di 4 decimali, dovresti pertanto tagliare i numeri prima di usare i pattern.
Questo codice funzionerebbe bene se dovessi convertire solo numeri americani fino a 9,999 e con massimo 4 decimali, ma con numeri mischiati cambierebbe anche quelli giusti tipo 3.456 (tremila quattrocentocinquantasei) in 3,456 (tre virgola ...).

Non so se riesco a spiegarmi.
Quindi, come suggerivi prima, conviene fare un primo passaggio che rileva i numeri "italiani" e li cancella o cambia in modo che non diano fastidio e poi fare un secondo passaggio sui numeri "americani".
Titolo: Re:Funzione conversione float
Inserito da: vuott - 15 Marzo 2019, 18:41:12
La funzione Scan( ) nella nostra Wiki:

  https://www.gambas-it.org/wiki/index.php?title=Scan
Titolo: Re:Funzione conversione float
Inserito da: Gianluigi - 15 Marzo 2019, 18:46:45
Ciao vuott,
ma qui il problema per dex è LIKE, Scam è più semplice usi solo gli asterischi.
Ci sarebbe regex, che potrebbe aiutare, ma credo che ci si possa arrangiare anche con Like usando qualche passaggio in più.
Titolo: Re:Funzione conversione float
Inserito da: dex - 15 Marzo 2019, 18:56:07
no gianluigi ti eri spiegato bene
sono gli americani (e anche i nostrani) che danno problemi, un numero che arriva 3.456 oppure 0.123 è giusto come pure 0,456 o 0,123
sono vecchi cataloghi da cui devo tirare i prezzi.

quelli che creano casino sono:
1,234.56 oppure 1.234,56, in pratica con un solo separatore va bene, con due le cose si complicano

ciao vuott
Titolo: Re:Funzione conversione float
Inserito da: Gianluigi - 15 Marzo 2019, 19:06:07
no gianluigi ti eri spiegato bene
sono gli americani (e anche i nostrani) che danno problemi, un numero che arriva 3.456 oppure 0.123 è giusto come pure 0,456 o 0,123
sono vecchi cataloghi da cui devo tirare i prezzi.

quelli che creano casino sono:
1,234.56 oppure 1.234,56, in pratica con un solo separatore va bene, con due le cose si complicano

ciao vuott

Inizio a confondermi  :rolleyes:
Io credo che 0.123 sia sicuramente errato e 0,123 sia corretto.
Ma se non abbiamo modo di sapere se 3.456 sia corretto perché potrebbe essere 3,456 americano allora mi dispiace ma neppure San Giorgio che mangiava draghi a colazione ti può aiutare.
Titolo: Re:Funzione conversione float
Inserito da: vuott - 15 Marzo 2019, 19:08:39
Vorrei capire una cosa: la parte frazionaria del gruppo di caratteri numerali ricevuti è composta sempre e solo da due cifre ?
Titolo: Re:Funzione conversione float
Inserito da: Gianluigi - 15 Marzo 2019, 19:09:54
Vorrei capire una cosa: la parte frazionaria del gruppo di caratteri numerali ricevuti è composta sempre e solo da due cifre ?

Ma se ha appena detto che ce ne possono essere anche venti  :violent:
Titolo: Re:Funzione conversione float
Inserito da: Gianluigi - 15 Marzo 2019, 19:13:48

quelli che creano casino sono:
1,234.56 oppure 1.234,56, in pratica con un solo separatore va bene, con due le cose si complicano


Qui non c'è casino perché
Codice: [Seleziona]
Like "*.???,*"
te lo rilevano e poi ti basta rimuovere eventuali virgole o punti finali e/o iniziali.
Titolo: Re:Funzione conversione float
Inserito da: dex - 15 Marzo 2019, 19:21:11
Gian scusa se ti ho confuso

in pratica si tratta di cataloghi vari e in varie valute, quando il separatore decimale è uno solo che sia punto o virgola non ha importanza, lo converto con replace e risolvo

quando mi arrivano cifre formattate americane o nostrane con . e , diventa più complicato, le nostrane le risolvevo con replace togliendo il . le americane dovrei togliere la virgola, quindi dovrei fare due codici, il problema è che molti cataloghi hanno per lo stesso articolo i prezzi in varie valute, e li mi tocca digitare a manina ed è estremamente noioso.
Titolo: Re:Funzione conversione float
Inserito da: dex - 15 Marzo 2019, 19:30:26
Codice: [Seleziona]
If s Like "*,*.?" Then
    Print
else If s Like "*,*.??" Then
   Print
else If s Like "*,*.???" Then
print
else If s Like "*,*.????" Then
print
Endif

in questo modo dovrei risolvere, solo che se i decimali superano 4?

mi possono capitare cifre sballate con decine o molte decine di decimali (sono quelle che mi davano errore di segmentazione)

Occorre stare molto attenti alle successioni dei pattern di ricerca.
Ad esempio con questi pattern non rileveresti i numeri con più di 4 decimali, dovresti pertanto tagliare i numeri prima di usare i pattern.
Questo codice funzionerebbe bene se dovessi convertire solo numeri americani fino a 9,999 e con massimo 4 decimali, ma con numeri mischiati cambierebbe anche quelli giusti tipo 3.456 (tremila quattrocentocinquantasei) in 3,456 (tre virgola ...).

Non so se riesco a spiegarmi.
Quindi, come suggerivi prima, conviene fare un primo passaggio che rileva i numeri "italiani" e li cancella o cambia in modo che non diano fastidio e poi fare un secondo passaggio sui numeri "americani".

era su questa tua risposta che intendevo il casino
posso tagliare le stringhe a 4 decimali ma con quale criterio di ricerca?
se uso il punto

1,234.12345679 ecc diventa 1,234.1234 poi con replace tolgo la virgola ed è ok
ma se mi arriva 1.234,123456789 diventa 1.234, ed è sbagliato

usando la ricerca con la virgola avrei il problema inverso
Titolo: Re:Funzione conversione float
Inserito da: Gianluigi - 15 Marzo 2019, 19:34:05
il problema è che molti cataloghi hanno per lo stesso articolo i prezzi in varie valute, e li mi tocca digitare a manina ed è estremamente noioso.

Non capisco perché devi farlo a mano ti basta estrarre un unico valore sicuro e poi lo traduci in altre valute moltiplicandolo per il corretto fattore.
Una volta i listini prezzi erano il mio pane Excel non aveva segreti  ;D
Titolo: Re:Funzione conversione float
Inserito da: Gianluigi - 15 Marzo 2019, 19:40:09


era su questa tua risposta che intendevo il casino
posso tagliare le stringhe a 4 decimali ma con quale criterio di ricerca?
se uso il punto

1,234.12345679 ecc diventa 1,234.1234 poi con replace tolgo la virgola ed è ok
ma se mi arriva 1.234,123456789 diventa 1.234, ed è sbagliato

usando la ricerca con la virgola avrei il problema inverso
Intanto vorrei capire chi è quel pazzo che fa listini con 20 decimali...
Comunque avrai un massimo di decimali o no?
Oppure: Avrai un carattere delimitatorio? Intendo dire che ci sarà pure una fine del numero e poi qualcosa?
Titolo: Re:Funzione conversione float
Inserito da: dex - 15 Marzo 2019, 19:43:52
Excel risolve molti problemi, peccato che non legga il cartaceo   ;D

cmq ragazzi grazie per l'aiuto, ora mi metto all'opera con scan e provo a fare un po di pasticci.  :2birre:

s ho problemi vi rompo di nuovo  :D :D

gianluigi ho visto ora il tuo post, quel pazzo non è umano, è tesseract che fa del suo meglio su pagine mezze sbiadite, devo provare alrtri ocr, ma date le condizioni delle pagine temo che ci siano lo stesso problemi
Titolo: Re:Funzione conversione float
Inserito da: Gianluigi - 15 Marzo 2019, 19:44:57
@vuott

prima stavo scherzando, non te la sarai mica presa?  :-*  :-*  :-*
Titolo: Re:Funzione conversione float
Inserito da: dex - 15 Marzo 2019, 19:46:30
i numeri di solito hanno 2 decimali , massimo 4 quando sono sottozero tipo 0.022, io per uniformare il tutto taglio a 4, se poi mi esce 121.31 perchè in partenza aveva solo 2 decimali va bene lo stesso
Titolo: Re:Funzione conversione float
Inserito da: vuott - 15 Marzo 2019, 21:51:19
io per uniformare il tutto taglio a 4
Quindi mi fai capire che non appena ricevi i dati riduci immediatamente i decimali a non più di 4, se essi sono in origine più di 4.
Sia se la parte frazionaria è separata dalla virgola che dal punto ?
Pertanto, se giunge un valore di questo genere 123.45678, tu lo riduci a 123.4567 ?
Titolo: Re:Funzione conversione float
Inserito da: dex - 15 Marzo 2019, 21:56:36
si vuott, oltre i 4 decimali non mi servono, anzi spesso se sono più di 4 vul dire che tesseract ha letto male
Titolo: Re:Funzione conversione float
Inserito da: dex - 16 Marzo 2019, 01:51:01
Raga ho risolto
ora qualsiasi cifra mi arriva viene convertita nel formato giusto e con 4 decimali
Titolo: Re:[Risolto] Funzione conversione float
Inserito da: Gianluigi - 16 Marzo 2019, 09:22:23
Buona soluzione.   :ok:

A una superficiale lettura, mi sembra inutile il replace della virgola col punto:
Codice: [Seleziona]
      Select Case SeparatoreDec
          Case "."
             s = Replace(s, ",", "")
          Case ","
             s = Replace(s, ".", "")
            s = Replace(s, ",", ".")                                                                                                               
      End Select

Ma magari non ne ho compreso il motivo  :-\

 :ciao:

Ora vado a lavorare manualmente, sono di corvè, ci sentiamo più tardi...
Titolo: Re:[Risolto] Funzione conversione float
Inserito da: dex - 16 Marzo 2019, 11:34:29
Hai ragione
quel passaggio è inutile
Titolo: Re:[Risolto] Funzione conversione float
Inserito da: vuott - 16 Marzo 2019, 14:49:05
Ma tu vuoi che il carattere separatore stampato alla fine nella Label sia la virgola o sia il punto ?
Titolo: Re:[Risolto] Funzione conversione float
Inserito da: dex - 16 Marzo 2019, 20:36:34
la funzione serve per salvare i dati nel database al giusto formato

poi nelle label è poco importante, con format le fai visualizzare come vuoi
Titolo: Re:[Risolto] Funzione conversione float
Inserito da: vuott - 16 Marzo 2019, 21:47:54
la funzione serve per salvare i dati nel database al giusto formato

Eh... ma quale è il "giusto formato" ?
Titolo: Re:[Risolto] Funzione conversione float
Inserito da: dex - 17 Marzo 2019, 02:33:15
Cfloat vuole 123.45
per visualizzarla 123,45

se ho 123.45 uso Cfloat(s)
se ho 123,45 uso Cfloat(val(s))

usando la virgola mi serve ad entrambi,nella label la vedo correttamente poi con val la trasformo in float per i calcoli e il salvataggio nel database