Mappare automaticamente celle a elementi XSD



  • Mappare automaticamente celle a elementi XSD
    di Mohican1989 data: 11/07/2016 22:03:20

    Ciao a tutti,
    Ho la necessità di automatizzare il mapping degli elementi di uno schema xsd alle celle Excel.
    I file xsd sono scaricabili al seguente indirizzo (non vi posto il file perché lo stesso file XSD include altri file XSD per alcuni tipi di dato) h t t p:// www. autorit a.energia.it/it/ docs/16/006-16dmeg.htm. La cartella è presente tra gli allegati e si chiama XSD.

    Manualmente apro Excel dalla scheda sviluppo clicco su origine -> mapping xml -> aggiungo (nel mio caso ora sono interessato al file TML.xsd presente nella cartella letture) poi trascino cliccando sulla ROOT "Prestazione" tutto lo schema sulla cella A1 e ogni elemento si mappa sulle celle adiacenti, poi tasto destro sulla tabella che viene creata -> XML -> IMPORTA e mi importo i miei file.

    Ora non avendo mai fatto ciò in VBA ho registrato una macro che trovate sotto.

    Userò un filedialog per selezionare molteplici file e un for each per importarli tutti.

    Ciò che non riesco a simulare è il trascinamento dello schema sulla cella A1 e quindi mappare tutte gli elementi dello schema alle celle.

    Mi sono documentato un po' in giro e quello che più penso si avvicini alla risoluzione del problema sia l' utilizzo del metodo Range.Xpath.SetValue che non ho mai usato e facendo qualche prova sembra fallire miseramente.

    So che è una cavolata ma mi scoccerebbe ogni volta importare il file xsd e trascinarlo per poi lanciare la macro.

    Grazie a chiunque possa darmi una mano ;)


     
    Sub Macro1()
    '
    ' Macro1 Macro
    '
    
    '
        ActiveWorkbook.XmlMaps.Add( _
            "C:UsersCristinaDesktopWorkDMEG 6-2016XSD - SCHEMAlettureTML_0050.xsd" _
            , "Prestazione").Name = "Prestazione_mapping"
        Range("Tabella1[cod_flusso]").Select
        ActiveWorkbook.XmlMaps("Prestazione_mapping").Import URL:= _
            "C:UsersCristinaDesktopLETTUREAPGAS PLUS RETI GASTML_0050_02022200444_201605091004_1.xml"
        ActiveWorkbook.XmlMaps("Prestazione_mapping").Import URL:= _
            "C:UsersCristinaDesktopLETTUREAPRETE MORENICATML_0050_02022200444_03404300232_0416.xml"
    End Sub



  • di Thyke data: 11/07/2016 22:23:22

    non ho capito bene cosa vuoi fare ma se ho capito le tue intenzioni quello che ha in mente richiede un pochino di lavoro.
    per importare il singolo file a partire dalla cella "A1" puoi usare il codice sotto
    l'indirizzo del file l'ho messo prelevandolo dal tuo codice se devi aprire un'altro file devi modificarlo

    e fino ad un file problemi non ce ne sono, i problemi nascono dal gruppo di file, il primo file lo importi a partire dalla cella "A1" il secondo se utilizzi lo stesso riferimento di cella sovrascrive il primo e così via, quindi prima di importare il secondo file devi rilevare la prima cella utile e importare da li...e così via per il terzo, il quarto...
     
    Sub importaUrl()
        ActiveWorkbook.XmlImport URL:="C:UsersCristinaDesktopWorkDMEG 6-2016XSD - SCHEMAlettureTML_0050.xsd", _
        ImportMap:=Nothing, Overwrite:=True, Destination:=Range("$A$1")
    End Sub



  • di Mohican1989 data: 11/07/2016 23:18:29

    Ciao Thyke e grazie per l' interessamento.

    Il mio problema non è tanto importare i file, per cui farei un filedialog in cui vado a indicare i file che voglio importare, farei un loop dei file da caricare ma precedentemente avrò cambiato l' opzione "Durante l' aggiornamento o l' importazione dei dati" da -Sovrascrivi i dati esistenti con i nuovi dati- a -Aggiungi nuovi i nuovi dati alle tabelle XML esistenti- (praticamente la funziona append per scrivere un file senza sovrascriverlo).

    Allego un immagine per far vedere di cosa sto parlando ed il risultato. Come vedi sulla destra ho il mio "albero" con il file XSD caricato e sul foglio la tabella con 2 file xml importati. La tabella l ho creata trascinando la mappa di origine sulla cella A1 e automaticamente mappa ogni elemento come intestazione di colonna.
    Questo è il passaggio che tento di automatizzare.




  • di Mohican1989 data: 11/07/2016 23:46:31

    Aggiungo che guardando in giro modifico il codice come sotto.

    Solo che al momento di settare il valore dell xpath, mi restituisce un errore di run time -2147467259 (80004005) molto generico come errore.

    Attendo vostre ^^
     
    Sub Macro1()
    '
    ' Macro1 Macro
    'dim xp as variant
    
    '
        ActiveWorkbook.XmlMaps.Add( _
            "C:UsersCristinaDesktopWorkDMEG 6-2016XSD - SCHEMAlettureTML_0050.xsd" _
            , "Prestazione").Name = "Prestazione_mapping"
            
          strpath = "/Prestazione"
    
          Set xp = Range("a1").XPath
          xp.SetValue ActiveWorkbook.XmlMaps(1), strpath
        
        ActiveWorkbook.XmlMaps("Prestazione_mapping").Import URL:= _
            "C:UsersCristinaDesktopLETTUREAPGAS PLUS RETI GASTML_0050_02022200444_201605091004_1.xml"
        ActiveWorkbook.XmlMaps("Prestazione_mapping").Import URL:= _
            "C:UsersCristinaDesktopLETTUREAPRETE MORENICATML_0050_02022200444_03404300232_0416.xml"
    End Sub



  • di Thyke data: 12/07/2016 04:41:48

    @ Mohican1989

    stai lavorando su un foglio protetto da password?
    h t t p s://support.microsoft.com/it-it/kb/983119



  • di Mohican1989 data: 12/07/2016 08:57:06

    No assolutamente no è un foglio ex novo



  • di Mohican1989 data: 12/07/2016 22:18:56

    Su non fate i timidi, di sicuro qualcuno di voi avra già lavorato con xml/xsd non ci credo che non avete trovato un modo per mappa gli elementi xD



  • di patel data: 14/07/2016 06:51:06

    magari potresti spiegare cos'è un mapping di elementi xD





  • di Vecchio Frac data: 14/07/2016 14:57:50

    Perchè, invece di riapplicare lo schema esistente ad ogni passaggio di macro, non crei un documento Excel con lo schema xsd già importato e poi non automatizzi il solo refresh dei dati?

    Mi viene da pensare che tu faccia così perchè hai diversi e svariati schemi XML da riapplicare e poi riempire con i dati.

    Comunque è una bella gatta da pelare questa :)





  • di Mohican1989 data: 14/07/2016 23:14:38

    @Patel
    Mappare gli elementi significa che dalla "mappa" qual è il file XSD (il file XSD contiene al suo interno le regole di costrusione di un file xml, per esempio lo schema ho potete trovare nel link tra i tanti quello TML definisce le regole dei campi che l XML delle letture mensili gas devono rispettare, ad esempio, il codice PDR che identifica l' utenza gas di casa vostra ha 14 CIFRE, il campo tra i tag < cod_pd r> e < /cod_pdr > non potra mai contenere 15 cifre o valori di testo.In questo modo il file che viene passato tra i diversi operatori dovrà essere per tutti formato allo stesso modo) vado ad inserire questi elementi come intestazione di colonna e i rispetivvi campi sotto le intestazioni che andro ad importare tramite file XML seguiranno le regole imposta per l' elemento dallo schema XSD. Spero di essere stato esauriente ed essermi spiegato.
    @frac
    Si potrai tenere un file con lo schema già inserito ad ogni nuova macro pulire i dati già esistenti e importare con un loop quelli che vado a indicare, è vero, ma mi scoccia terribilmente sapere che esiste sicuramente un modo per poterlo fare non saperlo fare. :/



  • di Vecchio Frac data: 15/07/2016 10:28:32

    Non sono così sicuro che esista sicuramente un modo per poterlo fare.
    Credimi ho googlato un sacco ieri sera (trovando anche la discussione con il codice postato da te) e le uniche soluzioni valide prevedono la scansione dello schema XSD per recuperare i campi e quindi effettuare il mapping colonna per colonna. Non una gran bella soluzione direi. C'è parecchio codice e non sono neanche sicuro che sia del tutto affidabile. Penso che non ci sia la funzione builtin per il mapping come si fa manualmente (altrimenti pure il registratore l'avrebbe perlomeno abbozzata).