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]

Rispondere a