Riprendo una "vecchia" discussione che era rimasta in sospeso...
Si trattava, per chi non avesse più il messaggio, dell'annoso problema
di "trattare" dei listini prezzi mal formattati (deve essere uno
standard qualitativo ma non codificato... :-) ) con cui spesso si ha a
che fare.
Nell'adattare dei prezzari per Ultimus ho sbattuto il naso con dei
prezzi in testo che non riuscivo (con i miei espedienti mediante la UI
standard) in nessun modo a trasformare in numeri.
Allora ho rispolverato la macro che Lido Bernardini ed Emanuele avevano
elaborato ottenendo così degli ottimi numeri :-).
Ma volendo pensare ad un strumento più generalizzato i problemi sono due:
1) Come prelevare il range da elaborare e dove scriverlo
2) Residui problemi di digestione...
Sulla 1) il selectRange di Emanuele presenta alcuni limiti, sia in
merito alla comodità di prelevare 2000 righe, che sul problema (già
discusso e non risolto) della finetra di ricerca aperta su altri doc...
Per l'uso specifico che devo farne io ho preferito modificare la macro
(e spero di non averla pasticciata troppo);
prima seleziono il range poi aziono la macro...
Non è il massimo ma non mi è venuto in mente niente di meglio... si
accettano suggerimenti.
Sul dove scrivere ho inserito del codice che aggiunge una colonna a
fianco di quella con il testo da convertire. Questa mi sembra una buona
soluzione...
Per il 2) ho constatato che se trova un numero negativo si inciampa...
uguale quando incontra delle parole...
Ritornando per un momento alle specifiche credo, per l'area Euro, si
possano restringere le possibilità a combinazioni ragionevoli... ma la
cosa importante è che, se non riesce a convertire, si copi ugualmente il
contenuto della cella paro paro... (magari con sfondo o testo colorati).
In questo modo vengono evitati errori clamorosi con effetti che possono
essere devastanti (contabilità di opere pubbliche)...
Anzi, magari una msgbox che avverte (visualizzando) appunto quando non
riesce a convertire...
Un po' di clang e OK aiutano l'utente a rimanere consapevole di ciò che
sta facendo... :-)
Infatti non si può escludere che all'interno di un range di migliaia di
righe, oltre a numeri in formato testo, non ci siano anche delle parole
(magari note importanti).
Anche i numeri negativi sono possibili (non ci avevo pensato)... e nei
casi che ho trovato si trattava di "sconti" in %...
Quindi, alla macro che allego in coda, sarebbero da pensare delle
correzioni in questo senso... ovviamente ci ho provato... ma non ci ho
cavato granché...
Sull'opzione di usare java o quan'altro per fare un addin, anch'io non
saprei da che parte cominciare...
Per il momento un normale pacchetto.uno.pkg dovrebbe bastare.
un grazie anticipato
Bart
---------------------------------------------
REM ***** BASIC *****
Sub Che_Digerisce_Quasi_Tutto_e_Lo_Converte_In_Numeri()
' versione da azionare con range pre-selezionato
'modificata con inserimento colonna
Dim d As long
Dim e As long
Dim f As long
Dim g As long
Dim Tipo As Double
Dim Tipo2 As String
dim oFoglio As Object
Dim oMycell As Object
Dim oMyRange As Object
Dim NumCol As Integer
Set oFoglio = ThisComponent.Sheets.getByName(_
ThisComponent.currentcontroller.activesheet.name)
oSelections = ThisComponent.getCurrentSelection()
oMyRange=oSelections.getRangeAddress()
d = oMyRange.StartColumn 'getColonnaIniziale(a)
e = oMyRange.StartRow 'getRigaIniziale(a)
f = oMyRange.EndRow 'getRigaFinale(a)
NumCol = oMyRange.StartColumn ' definisce il numero della colonna
oFoglio.Columns.insertbyindex(d+1,1)
For g = Val(e) to Val(f) ' Inizia il ciclo
rifa:
Tipo = oFoglio.getCellByPosition(NumCol, g).Value
Tipo2 = oFoglio.getCellByPosition(NumCol, g).String
' xray Tipo
' Xray Tipo2
if Tipo = "" or Tipo2 = "" then
g = g+1
goto rifa
end if
if Tipo <> 0 Then ' Se è un numero si limita a formattare
'la cella
oMycell = oFoglio.getCellRangeByName(d + LTrim(Str(g)))
oMycell.NumberFormat = 4 'Valore ##.##0,00
Else ' Altrimenti fa una serie di controlli per determinare
' che tipo di stringa è
' se trova dei caratteri di testo o delle celle vuote
' salta alla cella dopo
if InStr(Tipo2, "'") > 0 then
Tipo2 = join(split(Tipo2,"'"),"")
Tipo2 = Trim(Tipo2)
end if
Dim h As Integer
Dim i As Integer
Dim l As String
Dim iPosizionePrimoPunto as integer
Dim iPosizionePrimaVirgola as integer
iPosizionePrimoPunto = InStr(Tipo2, ".")
iPosizionePrimaVirgola = InStr(Tipo2, ",")
if (iPosizionePrimoPunto = 0_
and iPosizionePrimaVirgola = 0) then
'Non ci sono nè virgole nè punti
'Potrebbe contenere del testo
'Ci sono varie cose da fare...
else
if iPosizionePrimoPunto = 0 then
'Ci sono solo virgole
if InStr(iPosizionePrimaVirgola + 1_
, Tipo2) > 0 then
'C'è più di una virgola, allora sarà
' un separatore di migliaia
'Lo rimuovo
Tipo2 = join(split(Tipo2, ","), "")
else
'Cè solo una virgola
if (((len(Tipo2) - iPosizionePrimaVirgola) <3)or_
((len(Tipo2) - iPosizionePrimaVirgola) > 4))
then
'La virgola ha meno di due o più di 4 alla
'sua destra, allora è quasi certamente
'un separatore di decimali
'Quindi non facciamo niente
else
'La virgola ha esattamente 3
cifre alla sua
'destra, può essere un separatore di
'decimali, ma anche un
separatore di migliaia,
'non posso decidere cosa fare...
end if
end if
end if
if iPosizionePrimaVirgola = 0 then
if InStr(iPosizionePrimoPunto + 1, Tipo2) > 0 then
'Cè più di un punto, allora sarà un
separatore di migliaia
'Lo rimuovo
Tipo2 = join(split(Tipo2, "."), "")
else
'C'è un solo punto
if (((len(Tipo2) - iPosizionePrimoPunto)
< 3) or _
((len(Tipo2) - iPosizionePrimoPunto)
> 4)) then
'Il punto ha meno di due o più di 4
alla sua destra,
'allora è quasi certamente
'un separatore di decimali
'Allora sostituiamo il punto con una
virgola
Tipo2 = join(split(Tipo2, "."), ",")
else
'Il punto ha esattamente 3 cifre
alla sua destra, può
'essere un separatore di
'decimali, ma anche un
separatore di migliaia, non
'posso decidere cosa fare...
end if
end if
end if
if ((iPosizionePrimoPunto > iPosizionePrimaVirgola)
and _
(iPosizionePrimaVirgola > 0)) then
'Ragionevolmente il punto sarà il separatore dei
decimali
'Togliamo le virgole come separatore delle migliaia
Tipo2 = join(split(Tipo2, ","),"")
'Sostituiamo il punto con la virgola come
separatore dei decimali
Tipo2 = join(split(Tipo2, "."),",")
end if
if ((iPosizionePrimoPunto < iPosizionePrimaVirgola)
and _
(iPosizionePrimoPunto > 0)) then
'Ragionevolmente la virgola sarà il separatore
dei decimali
'Togliamo i punto come separatori delle migliaia
Tipo2 = join(split(Tipo2, "."),"")
'E la virgola la lasciamo alsuo posto
end if
end if
'
' oFoglio.getCellByPosition(NumCol, g - 1).setValue(cDbl(Tipo2))
oFoglio.getCellByPosition(NumCol+1, g ).setValue(cDbl(Tipo2))
oMycell = oFoglio.getCellByPosition(NumCol+1, g )'.LTrim(Str(g))
' oMycell = oFoglio.getCellRangeByName(d + LTrim(Str(g)))
oMycell.NumberFormat = 4
end if
Next
end sub
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]