Risolto Prelievo Internet da più siti Web

Mark87

Utente abituale
21 Aprile 2018
250
18
Milano
Excel 2010
0
Grazie a Rubik72 @Rubik72 ho risolto un problema importantissimo ovvero prelevare dati da Internet e metterli sul foglio Excel. Ora devo risolvere un problema a più ampio spettro. Inserisco l'immagine di quello che compare quando faccio alt+F11 sul codice Excel.


Ho un file Excel con molti fogli di lavoro. A tal proposito le domande sono le seguenti:

1) Inserisco il codice "standard"

Visual Basic:
Private Sub Workbook_Open()
    Call ImportaTitolo
End Sub
in Questa_cartella_di_lavoro? Corretto?

2) Se ci sono 18 fogli di lavoro e per tutti e 18 devo "prelevare" da Internet un valore da un sito diverso e con un elemento di classe diverso devo creare 18 moduli, corretto? Quello che però non mi è chiaro è come fa il codice a capire esattamente quel modulo a quale foglio di lavoro è collegato. Non so se è chiara la domanda. Per esempio un foglio di lavoro si chiama CEFL e l'altro foglio di lavoro si chiama MORL. Ora, una volta creato il modulo lo rinomino e lo chiamo MORL e CEFL rispettivamente? Questo è un modo per by passare il problema? Va bene?

3) Poi in ogni codice, "quello standard per intenderci" inserisco il sito Web di riferimento e l'elemento con la solita procedura F12 nel sito Web.

Il punto 2 è il reale problema.
 

Powerwin

VBA Expert
Expert
17 Marzo 2016
4.510
83
vicino a Milano
2019
94
Ti do un ultimo aiuto dopodiché se vedo che non ci metti un pò di impegno e tanto studio prima di fare domande ti blocco come utente perchè mi stai facendo spazientire.....

La ImportaTitolo ha i parametri del primo sito, inserisci un Modulo e nel Modulo che si chiamerà Modulo1 (se non ne hai aperti altri a caso) copi più volte la ImportaTitolo cambiandole nome (es. ImportaTitoloPippo, ImportaTitoloPluto) per quanti titoli/fogli devi scaricare valori, ed in ogni macro cambierai i parametri e i riferimenti di dove prendere il dato e dove copiare/incollare, poi nella Private Workbook_Open() inserisci Call ImportaTitoloPippo e sotto Call ImportaTitoloPluto...
 

Mark87

Utente abituale
21 Aprile 2018
250
18
Milano
Excel 2010
0
Ti do un ultimo aiuto dopodiché se vedo che non ci metti un pò di impegno e tanto studio prima di fare domande ti blocco come utente perchè mi stai facendo spazientire.....

La ImportaTitolo ha i parametri del primo sito, inserisci un Modulo e nel Modulo che si chiamerà Modulo1 (se non ne hai aperti altri a caso) copi più volte la ImportaTitolo cambiandole nome (es. ImportaTitoloPippo, ImportaTitoloPluto) per quanti titoli/fogli devi scaricare valori, ed in ogni macro cambierai i parametri e i riferimenti di dove prendere il dato e dove copiare/incollare, poi nella Private Workbook_Open() inserisci Call ImportaTitoloPippo e sotto Call ImportaTitoloPluto...
Grazie per il suggerimento. Sì però da qui a bloccarmi mi sembra un attimo eccessivo per il semplice fatto che se si rimane nell'educazione nel rispetto e non si offende nessuno mi sembra un pò troppo. Poi sei libero di fare quello che vuoi. Però gli amministratori del sito avranno certamente notato che sono rimasto nel rispetto educazione in qualsiasi messaggio anche se altri hanno scritto cose poco carine.

Comunque, venendo a noi volevo fare un codice, in base ai tuoi suggerimenti come questo:

Visual Basic:
Sub ImportaTitolo MORL()
    'dichiarazione variabili
    Dim IE As Object
    Dim Doc As Object
    Dim HTMLAs As Object
    Dim HTMLA As Object

    Set IE = CreateObject("InternetExplorer.Application") 'variabile Internet Explorer

    IE.navigate "https://finance.yahoo.com/quote/MORL?p=MORL&.tsrc=fin-srch" 'naviga pagina
    IE.Visible = True 'finestra visibile (si può impostare anche a False)
    Do While IE.Busy: DoEvents: Loop 'Attesa not busy
    Do While IE.readyState <> 4: DoEvents: Loop 'Attesa documento

    Set Doc = IE.document 'variabile documento

    Set HTMLAs = Doc.GetElementsByClassName("Trsdu(0.3s) Fw(b) Fz(36px) Mb(-4px) D(ib)") 'collezione di elementi di tipo Class
    For Each HTMLA In HTMLAs 'ciclo per ogni elemento della collezione
        i = i + 3 'indice di riga
        Range("D" & i) = HTMLA.innerText 'scivi nella colonna A il contenuto dell'elemento
    Next

    IE.Quit 'chiusura IE

    'eliminazione variabili
    Set IE = Nothing
    Set Doc = Nothing
    Set HTMLAs = Nothing
End Sub
poi
Visual Basic:
Sub ImportaTitolo CEFL()
  
  
End Sub
Mentre nella cartella_di_lavoro farei una cosa di questo tipo:

Visual Basic:
Private Sub Workbook_Open()
    Call ImportaTitolo MORL
    Call ImportaTitolo CEFL
   Call ImportaTitolo XXXX
    
End Sub
 

alfrimpa

VBA Expert
Supermoderatore
Expert
18 Dicembre 2015
20.682
1.713
66
Napoli
2013
398
Mark87 @Mark87

Qui nessuno ha detto che sei stato poco rispettoso nei confronti di altri e si può senz'altro dire che nessuno è stato irrispettoso nei tuoi confronti per il solo fatto di averti invitato a studiare il VBA (e su questo direi che hai glissato).

Dopo la chiusura della precedente discussione mi sarei aspettato di veder trascorrere un lasso di tempo non breve prima dell'apertura di una nuova discussione.

Tu invece ne hai aperto subito un'altra e sempre sul web scraping e presumo che le tue conoscenze generali e di base del VBA siano rimaste le stesse.
 
  • Like
Reactions: Mark87

Mark87

Utente abituale
21 Aprile 2018
250
18
Milano
Excel 2010
0
Ho provato a fare come dici, ma sbaglio qualcosa.

Visual Basic:
Sub ImportaTitolo(MORL)
'dichiarazione variabili
    Dim IE As Object
    Dim Doc As Object
    Dim HTMLAs As Object
    Dim HTMLA As Object

    Set IE = CreateObject("InternetExplorer.Application") 'variabile Internet Explorer

    IE.navigate "https://finance.yahoo.com/quote/MORL?p=MORL&.tsrc=fin-srch" 'naviga pagina
    IE.Visible = True 'finestra visibile (si può impostare anche a False)
    Do While IE.Busy: DoEvents: Loop 'Attesa not busy
    Do While IE.readyState <> 4: DoEvents: Loop 'Attesa documento

    Set Doc = IE.document 'variabile documento

    Set HTMLAs = Doc.GetElementsByClassName("Trsdu(0.3s) Fw(b) Fz(36px) Mb(-4px) D(ib)") 'collezione di elementi di tipo Class
    For Each HTMLA In HTMLAs 'ciclo per ogni elemento della collezione
        i = i + 3 'indice di riga
        Range("D" & i) = HTMLA.innerText 'scivi nella colonna A il contenuto dell'elemento
    Next

    IE.Quit 'chiusura IE

    'eliminazione variabili
    Set IE = Nothing
    Set Doc = Nothing
    Set HTMLAs = Nothing
End Sub

Sub ImportaTitolo(CEFL)
'dichiarazione variabili
    Dim IE As Object
    Dim Doc As Object
    Dim HTMLAs As Object
    Dim HTMLA As Object

    Set IE = CreateObject("InternetExplorer.Application") 'variabile Internet Explorer

    IE.navigate "https://finance.yahoo.com/quote/MORL?p=MORL&.tsrc=fin-srch" 'naviga pagina
    IE.Visible = True 'finestra visibile (si può impostare anche a False)
    Do While IE.Busy: DoEvents: Loop 'Attesa not busy
    Do While IE.readyState <> 4: DoEvents: Loop 'Attesa documento

    Set Doc = IE.document 'variabile documento

    Set HTMLAs = Doc.GetElementsByClassName("Trsdu(0.3s) Fw(b) Fz(36px) Mb(-4px) D(ib)") 'collezione di elementi di tipo Class
    For Each HTMLA In HTMLAs 'ciclo per ogni elemento della collezione
        i = i + 3 'indice di riga
        Range("D" & i) = HTMLA.innerText 'scivi nella colonna A il contenuto dell'elemento
    Next

    IE.Quit 'chiusura IE

    'eliminazione variabili
    Set IE = Nothing
    Set Doc = Nothing
    Set HTMLAs = Nothing
End Sub
Cosa sbaglio di particolare questa volta?
 

rollis13

Utente assiduo
15 Novembre 2015
1.602
63
Cordenons
Office 2016 x64
82
Certo, sbagli un fondamentale; i nomi delle macro vanno scritti per lo meno così:
Sub ImportaTitoloMORL()e non così Sub ImportaTitolo(MORL)
 
  • Like
Reactions: Mark87

alfrimpa

VBA Expert
Supermoderatore
Expert
18 Dicembre 2015
20.682
1.713
66
Napoli
2013
398
Mark87 @Mark87

Ancora un errore che se avessi recepito gli innumerevoli fatti da tutte le parti a studiare non avresti mai fatto.
 
  • Like
Reactions: Mark87

Mark87

Utente abituale
21 Aprile 2018
250
18
Milano
Excel 2010
0
Certo, sbagli un fondamentale; i nomi delle macro vanno scritti per lo meno così:
Sub ImportaTitoloMORL()e non così Sub ImportaTitolo(MORL)
Sì hai perfettamente ragione. Però, per completare il tutto mi sa che il codice corretto prevede che Internet explorer venga chiuso alla fine di tutto e non ogni volta. Però ti dico capita che il valore si aggiorna però poi di fatto subito dopo succede che ritorna al valore precedente. Io ora metto il codice che è uno step successivo però penso di aver capito che bisogna fare chiusra di IE semplicemente
Visual Basic:
Sub ImportaTitoloMORL()
'dichiarazione variabili
    Dim IE As Object
    Dim Doc As Object
    Dim HTMLAs As Object
    Dim HTMLA As Object

    Set IE = CreateObject("InternetExplorer.Application") 'variabile Internet Explorer

    IE.navigate "https://finance.yahoo.com/quote/MORL?p=MORL&.tsrc=fin-srch" 'naviga pagina
    IE.Visible = True 'finestra visibile (si può impostare anche a False)
    Do While IE.Busy: DoEvents: Loop 'Attesa not busy
    Do While IE.readyState <> 4: DoEvents: Loop 'Attesa documento

    Set Doc = IE.document 'variabile documento

    Set HTMLAs = Doc.GetElementsByClassName("Trsdu(0.3s) Fw(b) Fz(36px) Mb(-4px) D(ib)") 'collezione di elementi di tipo Class
    For Each HTMLA In HTMLAs 'ciclo per ogni elemento della collezione
        i = 2
        i = i + 1 'indice di riga
        Range("D" & i) = HTMLA.innerText 'scivi nella colonna A il contenuto dell'elemento
    Next

    IE.Quit 'chiusura IE

    'eliminazione variabili
    Set IE = Nothing
    Set Doc = Nothing
    Set HTMLAs = Nothing
End Sub

Sub ImportaTitoloCEFL()
'dichiarazione variabili
    Dim IE As Object
    Dim Doc As Object
    Dim HTMLAs As Object
    Dim HTMLA As Object

    Set IE = CreateObject("InternetExplorer.Application") 'variabile Internet Explorer

    IE.navigate "https://finance.yahoo.com/quote/CEFL?p=CEFL&.tsrc=fin-srch" 'naviga pagina
    IE.Visible = True 'finestra visibile (si può impostare anche a False)
    Do While IE.Busy: DoEvents: Loop 'Attesa not busy
    Do While IE.readyState <> 4: DoEvents: Loop 'Attesa documento

    Set Doc = IE.document 'variabile documento

    Set HTMLAs = Doc.GetElementsByClassName("Trsdu(0.3s) Fw(b) Fz(36px) Mb(-4px) D(ib)") 'collezione di elementi di tipo Class
    For Each HTMLA In HTMLAs 'ciclo per ogni elemento della collezione
        i = 2
        i = i + 1 'indice di riga
        Range("D" & i) = HTMLA.innerText 'scivi nella colonna A il contenuto dell'elemento
    Next

    IE.Quit 'chiusura IE

    'eliminazione variabili
    Set IE = Nothing
    Set Doc = Nothing
    Set HTMLAs = Nothing
End Sub
alla fine di tutto, corretto?

Ci sono delle righe di codice che sicuramente sono dei doppioni e non vanno inserite. Di questo ne sono sicuro. Però devo scoprire con esattezza quali sono.
 

Mark87

Utente abituale
21 Aprile 2018
250
18
Milano
Excel 2010
0
Allora ho provato il codice con la stringa

Visual Basic:
    IE.Quit 'chiusura IE
con l'apice perchè vuol dire che è un commento. Facendo in questo modo effettivamente il codice va meglio. Però vorrei che qualcuno ci butta un altro occhio per capire:

1) Si può ottimizzarlo ancora?
2) Si può mettere con apice qualche stringa di codice ulteriore in modo che il codice va ancora più veloce.
3) Varie ed eventuali
 

rollis13

Utente assiduo
15 Novembre 2015
1.602
63
Cordenons
Office 2016 x64
82
Ogni macro è autonoma pertanto ha bisogno di tutte le righe. Solo se ne crei una cumulativa completa di 'cicli' e magari anche un 'array' puoi eliminare quello che sembra ridondante (quando sono più macro separate ma fotocopie).
 
Ultima modifica:

Mark87

Utente abituale
21 Aprile 2018
250
18
Milano
Excel 2010
0
Ogni macro è autonoma pertanto ha bisogno di tutte le righe. Solo ne crei una cumulativa completa di 'cicli' e magari anche un 'array' puoi eliminare quello che sembra ridondante (quando sono due macro separate pur se fotocopie).
Il punto nevralgico è che io ho 18 fogli di lavoro e ho quindi ogni volta che apro il file la necessità di aggiornare 18 valori. Quindi avevo pensato di replicare questo codice (che grosso modo funziona anche) per 18 volte. Però come dici tu le mie perplessità sono le seguenti:

1) Questa struttura dove copio e incollo come un deficiente il codice può essere scalabile come soluzione? Credo proprio di no. Se ci sentisse Rubik72 @Rubik72 sicuramente non sarebbe d'accordo.

2) Se avessi altri fogli di lavoro (cioè altri titoli) sarebbe un casino. Se arrivo a 30? Come si fa?

Pertanto credo che Rubik72 @Rubik72 santo uomo deve darmi qualche istruzione perchè altrimenti la soluzione A la vedo molto macchinosa. Secondo me funziona anche ma non la vedo una soluzione definita.

Tu hai capito cosa intendo?
 

rollis13

Utente assiduo
15 Novembre 2015
1.602
63
Cordenons
Office 2016 x64
82
Allo stato attuale delle cose credo che la soluzione più semplice è memorizzare in Internet Explorer diciotto Preferiti e metterli tutti nella sua Pagina di Apertura. All'avvio di IE avrai immediatamente disponibile i risultati di tutti i Titoli (nessun problema per aggiungerne altri) che poi basta riportare in Excel per eventuali ulteriori elaborazioni.
 

Mark87

Utente abituale
21 Aprile 2018
250
18
Milano
Excel 2010
0
Allo stato attuale delle cose credo che la soluzione più semplice è memorizzare in Internet Explorer diciotto Preferiti e metterli tutti nella sua Pagina di Apertura. All'avvio di IE avrai immediatamente disponibile i risultati di tutti i Titoli (nessun problema per aggiungerne altri) che poi basta riportare in Excel per eventuali ulteriori elaborazioni.
Eh vorrei evitare di fare questa cosa perchè non c'è nessun automatismo. Aspettiamo il commento di Rubik che sicuramente sarà sorprenderci con qualche sua idea geniale.
 

Mark87

Utente abituale
21 Aprile 2018
250
18
Milano
Excel 2010
0
Ho bisogno però di un suggerimento:

Vorrei che il primo foglio di lavoro venga saltato. Così come sta fatta la routine escono tre valori (non so perchè) nei primi 3 fogli di lavoro. Come mai? Qualcuno sa aiutarmi?


Il problema è Sheet1(Totale). La routine scrive anche nella cella D3 cosa che non dovrebbe fare. Cioè in pratica in

1) Sheet1 (Foglio di lavoro chiamato Totale) cella D3
2) Foglio di lavoro MORL

Viene inserito lo stesso valore. Mi piacerebbe che in Sheet1 (e quindi foglio di lavoro Totale) non venga inserito nessun valore.
 
Ultima modifica:

alfrimpa

VBA Expert
Supermoderatore
Expert
18 Dicembre 2015
20.682
1.713
66
Napoli
2013
398
Rispondo in maniera assolutamente generale.

In VBA ai fogli ci si può riferire in due modi
  1. tramite il loro nome in questo modo Sheets("nomefoglio"
  2. tramite un numero che indica la posizione del foglio all'interno del file Sheets(3)
Però se si vuole escludere un foglio occorre impostare un ciclo For che valuti i nomi dei fogli ed escluda quello interessato più o meno in questo modo

Visual Basic:
For i = 1 to Sheets.Count
If Sheets(i).Name <> "Pippo"
....codice
End if
Next i
 
Ultima modifica:

ges

Excel/VBA Expert
Amministratore
Expert
21 Giugno 2015
21.644
1.733
Como
2011MAC 2016WIN
462
Un saluto a Alfredo cappello_saluta che in preda al torrido caldo estivo si è dimenticato del terzo metodo...
3) tramite il nome oggetto Foglio3
 

alfrimpa

VBA Expert
Supermoderatore
Expert
18 Dicembre 2015
20.682
1.713
66
Napoli
2013
398
Un saluto a Alfredo cappello_saluta che in preda al torrido caldo estivo si è dimenticato del terzo metodo...
3) tramite il nome oggetto Foglio3
Hai perfettamente ragione ges @ges in casa ho 30 gradi 😡
 

Sostieni ForumExcel

Aiutaci a sostenere le spese e a mantenere online la community attraverso una libera donazione!