manipolare testo HTML con vba



  • manipolare testo HTML con vba
    di Textomb data: 15/04/2015 12:43:50

    Vorrei condividere la mia esperienza al fine di acquisire i Vostri eventuali suggerimenti.
    Devo estrapolare dal sito Comuni-Italiani.it il numero delle famiglie censite nel 2012 di tutti i Comuni appartenenti ad una data provincia e riportarli in forma tabellare nel mio foglio di excel.
    Credevo che fosse più semplice. Ma poi è uscito un lavoro molto complesso e poco gestibile.
    Premetto che la provincia la seleziono da una combobox presente nel mio foglio di calcolo.
    A questo punto per estrapolare la stringa di testo che serve per comporre l'indirzzo web occorrente per aprire la relativa pagina web ho scritto la funzoine che pubblico di seguito.
    Poi la problematica si è trasferita per scrivere la routine che serve a ciclare tutti i Comuni appartenenti alla provicia scelta e tirare fuori il dato che serve (numero delle famiglie del 2012).
    PEr far questo ho scritto la routine "EstrapolaValori". Ma per es. per individuare il numero dei Comuni che appartengono alla provincia in esame non mi è risultato semplice. Infatti ci ho anche rinunciato... Lo prendo manualmente e lo scrivo nel range("C1")

    Vengo adesso al mio quesito.
    Può essere che per fare questa cosa mi sono complicato la vita? E quindi esistono delle istruzioni, che evidentemente non conosco, che mi avrebbero permesso di manipolare con maggiore flessibilità il testo HTML?
    Se è così, sarei curioso di approfondire la questione.
    Grazie a chi vorrà rispondere.
     
    ' La funzione estrapola la stringa numerica che identifica la provincia scelta dalla combobox
    Public Function f(prov As String) As String
        Dim ie As Object, Ele As Object
        
        Dim objRegExp As Object
        Set objRegExp = CreateObject("vbscript.regexp")
        
        objRegExp.Global = True
        objRegExp.Pattern = "[^0-9]"
        
     
      Set ie = CreateObject("InternetExplorer.Application")
        
                
                With ie
                    .silent = True
                    .navigate "h t t p : / /www.comuni-italiani.it"
                    .Visible = False
                    Do While .busy Or .ReadyState <> 4
                      DoEvents
                    Loop
                End With
        
                For Each Ele In ie.document.all
                        If Ele.innertext = prov Then
                            f = objRegExp.Replace(Ele.innerhtml, "")
                            Exit Function
                        End If
                Next
                
    End Function
    
    
    
    Sub EstrapolaValori()
    ' La routine serve per estrapolare il valore riferito al numero delle famiglie censite nel 2012
    ' in tutti i Comuni della Provincia scelta e memorizzata nel range("B1") del foglio di lavoro.
    ' poi registra il valore nel range B3 e seguenti.
        Dim ie As Object, Ele As Object
        Dim sWeb As String
        Dim w As Integer
        Dim str_w As String
        Dim i As Integer
        Dim prov As String
        Dim n_Prov As String
      
      prov = Range("B1") 'Nome della Provincia scelta
      n_Prov = f(prov) 'Restituisce la stringa che serve per comporre l'indirizzo web da aprire e da cui si può prelevare il valore cercato.
      Set ie = CreateObject("InternetExplorer.Application")
            For w = 1 To Range("C1") 'riporto manulamente il numero dei Comuni che appartengono alla provincia. Ma avrei voluto estrarlo in automatico...
            str_w = Format(w, "000")
                sWeb = " h t t p : / / www.comuni-italiani.it/" & n_Prov & "/" & str_w & "/statistiche/recenti.html"
                With ie
                    .silent = True
                    .navigate sWeb
                    .Visible = False
                    Do While .busy Or .ReadyState <> 4
                      DoEvents
                    Loop
                End With
                
                For Each Ele In ie.document.all
                i = i + 1
                If i = 1 Then Range("A" & w + 2).Value = Left(Ele.innertext, InStr(Ele.innertext, ":"))
                      If Ele.offsettop < 320 And Ele.offsettop > 315 And Ele.offsetleft < 320 And Ele.offsetleft > 315 Then
                    ' Non trovo altri elementi affidabili a parte la posizione per intercettare il dato che serve.
                    ' Ho però verificato che, la posizione del dato nella tabella web è sempre la stessa per tutti i Comuni.
                        Range("b" & w + 2).Value = CLng(Replace((Ele.innertext), ".", ""))
                        Range("b" & w + 2).NumberFormat = "#,#"
                    End If
                
                Next
              i = 0
            Next
        
    End Sub



  • di scossa data: 15/04/2015 13:19:36

    BRRRRR!!!! rabbrividisco!!

    dove hai lasciato ie.quit e set ie = Nothing ???


    Puoi allegare il file?



    scossa's web site
    Se tu hai una mela, ed io ho una mela, e ce le scambiamo, allora tu ed io abbiamo sempre una mela per uno.
    Ma se tu hai un'idea, ed io ho un'idea, e ce le scambiamo, allora abbiamo entrambi due idee. (George Bernard Shaw)



  • di Textomb data: 15/04/2015 14:26:07

    @scossa
    ho allegato il file... grazie.
    cit. BRRRRR!!!! rabbrividisco!!
    Sono convinto che le cose che ho fatto sono migliorabili e senza dubbio contengono errori ed imprecisioni.
    d'altra parte sono qui per imparare e mi sono esposto proprio per questa ragione...
    con stima.



  • di lepat (utente non iscritto) data: 16/04/2015 12:29:58

    ciao scossa, capisco che non è corretto tralasciare quelle istruzioni, ma perché addirittura rabbrividire ?



  • di scossa data: 17/04/2015 09:05:27

    cit. lepat: "capisco che non è corretto tralasciare quelle istruzioni, ma perché addirittura rabbrividire ? "

    Prova (col codice originale di textomb senza ie.quit) ad eseguire un po' di volte la sub EstrapolaValori(), poi chiudi Excel ed apri il task manager: conta quante istanze di iexplorer ci sono e trai la conclusione tu stesso.



    it. Textomb: "Sono convinto che le cose che ho fatto sono migliorabili e senza dubbio contengono errori ed imprecisioni.
    d'altra parte sono qui per imparare e mi sono esposto proprio per questa ragione... "


    Senza nessuna pretesa di insegnare qualcosa a qualcuno, nel weekend cercherò di fornire un contributo sul tema.


    scossa's web site
    Se tu hai una mela, ed io ho una mela, e ce le scambiamo, allora tu ed io abbiamo sempre una mela per uno.
    Ma se tu hai un'idea, ed io ho un'idea, e ce le scambiamo, allora abbiamo entrambi due idee. (George Bernard Shaw)



  • di lepat (utente non iscritto) data: 17/04/2015 11:19:02

    come al solito hai ragione, ma con i pc moderni non te ne accorgi nemmeno, per questo mi sembra che tu abbia un po' esagerato



  • di scossa data: 17/04/2015 11:40:21

    cit. lepat: " ma con i pc moderni non te ne accorgi nemmeno"

    Sì, finché non apri un altro file Excel particolarmente pesante e ti va tutto in crash e ti domandi perché

    "Fate vobis"!


    scossa's web site
    Se tu hai una mela, ed io ho una mela, e ce le scambiamo, allora tu ed io abbiamo sempre una mela per uno.
    Ma se tu hai un'idea, ed io ho un'idea, e ce le scambiamo, allora abbiamo entrambi due idee. (George Bernard Shaw)



  • di Textomb data: 18/04/2015 09:19:34

    condivido il pensiero ed il suggerimento di scossa a proposito delle istruzioni mancanti.
    difatti nel file che ho poi pubblicato le ho inserite...
    Resterò fiducioso in attesa di conoscere il contributo che vorrà essere fornito sulla tematica...



  • di lepat (utente non iscritto) data: 18/04/2015 09:41:21

    Mi sembra di essere stato capito male, anche io sono convinto che occorre sempre rilasciare gli oggetti, ho contestato soltanto l'espressione "rabbrividire", non esplode alcun pc, al limite si blocca in casi eccezionali.
    E' più o meno come non dichiarare le variabili, spesso va tutto bene, ma non sempre.



  • di scossa data: 18/04/2015 12:21:50

    cit. lepat: "... ho contestato soltanto l'espressione "rabbrividire", non esplode alcun pc, al limite si blocca in casi eccezionali ..."

    C'è chi rabbrividisce all'idea di condire gli spaghetti con la maionese, chi quando vede un film horror ...
    io rabbrividisco quando vedo il metodo .Quit applicato ad Excel e quando non lo vedo applicato a ie.


    scossa's web site
    Se tu hai una mela, ed io ho una mela, e ce le scambiamo, allora tu ed io abbiamo sempre una mela per uno.
    Ma se tu hai un'idea, ed io ho un'idea, e ce le scambiamo, allora abbiamo entrambi due idee. (George Bernard Shaw)



  • di scossa data: 18/04/2015 13:22:05

    Ciao,

    ho esaminato il file e, se ho capito il suo "scopo/utilizzo", direi sia meglio non utilizzare istanze di Internet Explorer (troppo lento) e sfruttare invece WinHTTP (info qui: Windows HTTP Services,
    e qui: Using WinHTTP)

    In pratica, il servizio WinHTTP restituisce una stringa col contenuto (HTML) della pagina Web da cui, tramite Regular-Expression, estrarremo i dati necessari.

    Non posso pubblicare il codice in quanto i pattern delle regex contengono tag html che rendono illegibile il codice pubblicato, ma allego il file Stat_Comuni.xlsm nel cui codice ho spiegato i pattern che ho utilizzato.

    Due parole sull'uso, sperando di aver interpretato correttamente l'esigenza di Textomb:

    Il pulsante  Aggiorna PROVINCIE  serve ad aggiornare la tabella delle provincie scaricando i dati dal sito. Operazione da compiere una-tantum.

    Scegliendo una provincia dalla combobox presente in D1, verranno automaticamente scaricati i dati di quella provincia.
    Mi sono attenuto allo schema di Textomb e quindi mostro solo il nome ed il numero di famiglie, ma il codice carica i dati di tutti e 5 gli sticky:
      - Popolazione (anno)
      - Num Famiglie (anno)
      - Eta' Media (anno)
      - Reddito Medio (anno)
      - Tasso Nativita' (anno)

    Ogni commento srà gradito.


    scossa's web site
    Se tu hai una mela, ed io ho una mela, e ce le scambiamo, allora tu ed io abbiamo sempre una mela per uno.
    Ma se tu hai un'idea, ed io ho un'idea, e ce le scambiamo, allora abbiamo entrambi due idee. (George Bernard Shaw)




  • di Textomb data: 18/04/2015 16:05:56

    ho visto velocemente il contenuto del file elaborato da scossa.
    Purtroppo devo uscire con la famiglia e non ho avuto molto tempo... mi riprometto di esaminarlo con maggiore attenzione al rientro.
    Mi sento però di ringraziarti per l'impegno ed il tempo che hai dedicato alla questione.
    Non so da dove scrivi e da dove vieni ma qualora dovessi mai un giorno incontrarti sappi che avrò il piacere di offrirti da bere!!!



  • di Textomb data: 18/04/2015 19:03:26

    Dunque,
    dopo un'analisi un pò più approfondita confermo che si tratta di un lavoro eccellente.
    Ovviamente il bravo scossa ha voluto inserire il dato della popolazione invece che quello delle famiglie per verificare che io fossi attento a rilevare la cosa.
    Non nascondo che me l'aspettavo...
    Ma, visto che la routine registra tutte le grandezze presenti, (popolazione, numero famiglie, età media, ecc) non è stato difficile estrapolare il dato che mi serve.
    Difatti è bastato chiedere l'estrapolazione del terzo elemento della matrice vDati ed il gioco è stato fatto!
    Non escludo che tornerò sull'argomento per richiedere approfondimenti sulla dinamica di funzionamento del servizio WinHTTP e sui pattern utilizzati per estrapolare i valori.
    In ogni caso ho capito che la problematica non era così semplice. Ovviamente per le mie flebili conoscenze.



  • di Textomb data: 18/04/2015 19:30:16

    per me è più che esaustivo... Pertanto è risolto!



  • di scossa data: 19/04/2015 11:34:15

    Bene, grazie per il riscontro.

    cit. lepat: "E' più o meno come non dichiarare le variabili, spesso va tutto bene, ma non sempre"

    per me, invece, è come andare in bagno e non tirare l'acqua: non esploderà la casa ma .....


    scossa's web site
    Se tu hai una mela, ed io ho una mela, e ce le scambiamo, allora tu ed io abbiamo sempre una mela per uno.
    Ma se tu hai un'idea, ed io ho un'idea, e ce le scambiamo, allora abbiamo entrambi due idee. (George Bernard Shaw)



  • di lepat (utente non iscritto) data: 19/04/2015 12:19:04

    non mi sembra un paragone calzante, se anche una sola volta non tiri l'aqua il risultato è sicuramente avvertibile da tutti, se lanci il codice iniziale una sola volta non ci sono ripercussioni



  • di scossa data: 19/04/2015 12:34:36

    cit.: "on mi sembra un paragone calzante"

    il paragone è effettivamente un po' forzato; allora diciamo che è come spazzare il pavimento e mettere la polvere sotto il tappeto.
    Paragoni che servono solo ad evidenziare un errato principio sottostante: "chi se ne frega, tanto nessuno se ne accorge ....."


    scossa's web site
    Se tu hai una mela, ed io ho una mela, e ce le scambiamo, allora tu ed io abbiamo sempre una mela per uno.
    Ma se tu hai un'idea, ed io ho un'idea, e ce le scambiamo, allora abbiamo entrambi due idee. (George Bernard Shaw)



  • di lepat (utente non iscritto) data: 19/04/2015 16:35:54

    tornando al nocciolo della soluzione, ce l'avevi già pronta o l'hai preparata lì per lì ?



  • di scossa data: 19/04/2015 16:55:41

    cit. lepat: "... ce l'avevi già pronta o l'hai preparata lì per lì ?"

    Cucinata e sfornata calda calda al momento.



    scossa's web site
    Se tu hai una mela, ed io ho una mela, e ce le scambiamo, allora tu ed io abbiamo sempre una mela per uno.
    Ma se tu hai un'idea, ed io ho un'idea, e ce le scambiamo, allora abbiamo entrambi due idee. (George Bernard Shaw)



  • di lepat (utente non iscritto) data: 19/04/2015 17:45:10

    complimenti !!!