Avatar billede redbulldk Juniormester
04. oktober 2007 - 12:21 Der er 22 kommentarer og
2 løsninger

Automatiseret import af en XML

Hej

Jeg kunne godt tænke mig, at automatiseret import af en XML fil med link til en PDF fil i en access database.

Hver time modtager jeg en XML fil med en PDF fil, hvor XML filen har nedenstående struktur. Itemnumber er navnet på PDF filen.
XML og PDF filen modtager jeg i d:\job hvor disse 2 filer er gemt i en mappe, hvor mappens navn er det samme som JobNumber.

Det jeg gerne vil er, at få importeret XML informationerne helst i en Access database, hvor der er link til PDF filen. Dette skal ske automatisk f.eks. hver 10 minut. Når importen har fundet sted, skal mappen eller filerne flyttes til d:\arkiv, hvor linket i databasen henviser til PDF filen.

PC/serveren er tændt døgnet rundt. Access version 2003 eller 2007 eller anden version.

Hvordan gøres det?

XML fil struktur.
<?xml version="1.0" encoding="ISO-8859-1"?>
<Order>
<OrderHeader>
<DocType>105</DocType>
<Status>1</Status>
<JobNumber>103717316</JobNumber>
</OrderHeader>
<ItemLine>
<ItemNumber>1530021</ItemNumber>
<Description><!Jobline from mac 10></Description>
<Date>20070918</Date>
<LatestDate>20070920</LatestDate>
<Order></Order>
</ItemLine>
</Order>
Avatar billede terry Ekspert
04. oktober 2007 - 12:32 #1
I'm no expert at XML, but if you copy the XML to a file and try opening it in IE youget an error
Avatar billede ffsoft Praktikant
04. oktober 2007 - 14:08 #2
Fejlen ligger her:
<Description>
<!Jobline from mac 10>
</Description>

Data må ikke være inde i tags.
Sådan skal den se ud:

<Description>
!Jobline from mac 10
</Description>

Det betyder at den ikke kan vises i en browser, som Terry siger og at Access ikke vil importere den direkte.
Det betyder ikke at det ikke kan lade sig gøre, den kan jo bare importeres som
en tekstfil, men så skal der en del kode til at lægge data ud i tabeller.
Er det kun ItemNumber du er ude efter??
Avatar billede redbulldk Juniormester
04. oktober 2007 - 14:16 #3
Beklager Terry - fejl fra min side. Den rigtige struktur må være nedenstående.

<?xml version="1.0" encoding="ISO-8859-1"?>
<Order>
<OrderHeader>
<DocType>105</DocType>
<Status>1</Status>
<JobNumber>103717316</JobNumber>
</OrderHeader>
<ItemLine>
<ItemNumber>1530021</ItemNumber>
<Description>Jobline from mac 10</Description>
<Date>20070918</Date>
<LatestDate>20070920</LatestDate>
<Order></Order>
</ItemLine>
</Order>
Avatar billede redbulldk Juniormester
04. oktober 2007 - 14:20 #4
Hej ffsoft. De informationer jeg er interesseret i at få over i Access, er følgende:

103717316
1530021
Jobline from mac 10
20070918
20070920
Avatar billede terry Ekspert
04. oktober 2007 - 15:40 #5
If you use Access import wizrad Access will putthe data in two tables, OrderHeader and ItemLine. This is because there are two tables in the XML. Problem is there is no relationship between the two tables, so I think you will need to use an XSL file to help tranform the tables. I dont know enough about XML/XSL to help you with that
Avatar billede redbulldk Juniormester
04. oktober 2007 - 16:08 #6
Hej Terry, tak for hurtig forslag. Jeg kan bede dem der har sat logningen op, sådan at strukturen i XML ændres, til f.eks. nedenstående, hvor den kun laver en tabel.

En sidste mulighed, som vil være en nødløsning, vil være at ændre logning outputtet fra XML formateret til comma fil eller tredje.

<?xml version="1.0" encoding="ISO-8859-1"?>
<Order>
<ItemLine>
<JobNumber>103717316</JobNumber>
<ItemNumber>1530021</ItemNumber>
<Description>Jobline from mac 10</Description>
<Date>20070918</Date>
<LatestDate>20070920</LatestDate>
<Order></Order>
</ItemLine>
</Order>
Avatar billede terry Ekspert
04. oktober 2007 - 16:56 #7
It doesnt seem possible to automate the import wizard with XML files. So you can either make your own code or use a CSV file.

Here is a link which may give you some idea in making your own code. http://www.eksperten.dk/spm/757938 an dalos other links.

Look at the comment 25/01-2007 01:31:53 wher ethere is a function
Function xmlimport
Avatar billede kjulius Novice
04. oktober 2007 - 21:40 #8
"It doesnt seem possible to automate the import wizard with XML files. So you can either make your own code or use a CSV file."

I don't know what you mean by that, terry. The ImportXML method of the application object will take care of the import function. Just write

Application.ImportXML xmlfile, acStructureAndData
Avatar billede terry Ekspert
05. oktober 2007 - 10:13 #9
Hi kjulius
Well believe it or not I dont know everything about Access :o) So I wasnt aware/forgotten that there was a ImportXML method. But actually I said that the import wizard couldnt be automated/used with XML which as far as I know cant.

Docmd.TransferText .....

You learn something every day
Avatar billede terry Ekspert
06. oktober 2007 - 10:40 #10
redbulldk can you use the answr given by kjulius?
Avatar billede kjulius Novice
06. oktober 2007 - 15:48 #11
Hmmm... Siden terry ikke ser ud til at tage bolden, vil jeg gerne give mit forslag til en løsning:

1) Du opretter en form hvor du i Timer eventen angiver et TimerInterval på 600000 millisekunder (svarende til at den skal udføres hvert 10. minut). I VedTimerudløb vælger du [Hændelsesprocedure] og klikker på ... knappen.

2) I timerproceduren indsætter du koden:

Private Sub Form_Timer()
    ProcessPDF "d:\job", "d:\arkiv"
End Sub

3) Indsæt herefter yderligere:

Private Sub ProcessPDF(startpath As String, arkivpath As String)

    Dim path As String
    Dim dirname As String
    Dim arrMapper(100) As String
    Dim mapper As Integer
    Dim i As Integer
    Dim PDFfile As String
    Dim XMLfile As String
    Dim arkivPDFfile As String
    Dim rs1 As Recordset
    Dim rs2 As Recordset
   
   
    'Kig efter et directory...
    dirname = Dir$(startpath & "\*.*", vbDirectory)
    Do While dirname <> ""
        If Left(dirname, 1) <> "." Then
            'Et directory blev fundet...
            mapper = mapper + 1
            arrMapper(mapper) = dirname
        End If
        dirname = Dir$()
    Loop
    If mapper > 0 Then
       
        'Løb alle de fundne mapper igennem...
        For i = 1 To mapper
            dirname = arrMapper(i)
       
            'Indeholder det en PDF fil?
            path = startpath & "\" & dirname
            PDFfile = Dir$(path & "\*.PDF", vbNormal)
            If PDFfile <> "" Then
           
                'PDF filen blev fundet. Kig nu efter den tilhørende XML fil...
                XMLfile = Dir$(path & "\*.xml", vbNormal)
                If XMLfile <> "" Then
               
                    'XML filen blev fundet.
                   
                    'PDF filen kan nu flyttes til arkivet...
                    arkivPDFfile = arkivpath & "\" & dirname & "_" & PDFfile
                    FileCopy path & "\" & PDFfile, arkivPDFfile
                    Kill path & "\" & PDFfile
                   
                    'Clear importtabellerne så de er klar til at modtage data fra xml filen...
                    CurrentDb.Execute "DELETE FROM OrderHeader"
                    CurrentDb.Execute "DELETE FROM ItemLine"
                   
                    'Importer xml filen til importtabellerne...
                    Application.ImportXML path & "\" & XMLfile, acAppendData
                   
                    'Tilføj oplysningerne fra xml filen til en tabel sammen med et link til PDF filen...
                    Set rs1 = CurrentDb.OpenRecordset("SELECT * FROM OrderHeader, ItemLine")
                    Set rs2 = CurrentDb.OpenRecordset("PDF Links")
                    Do While Not rs1.EOF
                        rs2.AddNew
                        rs2.Fields("DocType") = rs1.Fields("DocType")
                        rs2.Fields("Status") = rs1.Fields("Status")
                        rs2.Fields("JobNumber") = rs1.Fields("JobNumber")
                        rs2.Fields("ItemNumber") = rs1.Fields("ItemNumber")
                        rs2.Fields("Description") = rs1.Fields("Description")
                        rs2.Fields("Date") = rs1.Fields("Date")
                        rs2.Fields("LatestDate") = rs1.Fields("LatestDate")
                        rs2.Fields("Order") = rs1.Fields("Order")
                        rs2.Fields("URI") = arkivPDFfile
                        rs2.Update
                       
                        rs1.MoveNext
                    Loop
                    rs2.Close
                    rs1.Close
                   
                    'Frigiv undermappen vha. dummy instruktion (ellers kan den ikke fjernes)...
                    Dir$ (startpath)
                   
                    'Ryd op. Fjern XML filen og mappen...
                    Kill path & "\" & XMLfile
                    RmDir path
                   
                End If
            End If
        Next
       
    End If
               
End Sub

4) Tabellerne til importen forventes at være oprettet i forvejen. Kør derfor importen af xml filen igennem én gang for at få tabellerne oprettet.

5) Der skal nu oprettes en tabel med alle felterne fra de to importtabeller + et felt til linket til PDF filen:

a) Åbn OrderHeader tabellen i Edit mode. Marker alle felter og kopier dem (Ctrl A, Ctrl C)
b) Klik på Ny.. for at oprette en ny tabel. Vælg Designvisning. Indsæt felterne med Ctrl V. Luk ikke...
c) Åbn nu ItemLine tabellen i design mode. Gentag proceduren fra før: Marker og kopier feltnavne og definitioner (Ctrl A, Ctrl C).
d) Skift igen til den nye tabel, og indsæt også disse felter (Ctrl V).
e) Tilføj endnu et felt til linket (jeg har kaldt det "PDF Link")
f) Luk ned for designet af den nye tabel. Accepter et autoId. Giv den navnet "PDF Links"

Det skulle sådan set være alt.
Du vil nu kunne arbejde videre med det (finde referencen til PDF filen i den nye tabel).

NB! Jeg er gået ud fra dit oprindelige XML format.
Avatar billede kjulius Novice
06. oktober 2007 - 15:51 #12
Ups. Igen en fejl! I punkt 5e) skulle feltnavnet have været "URI" for at passe med koden i subrutinen.
Avatar billede redbulldk Juniormester
08. oktober 2007 - 10:08 #13
Hej kjulius

Takker for oplægget. Jeg får afprøvet i midten af ugen.
Avatar billede redbulldk Juniormester
08. oktober 2007 - 18:15 #14
Pæne koder, dog desværre får jeg en fejl, når koden afvikles. Der kommer en VB popup med følgende fejl "Compile error: User-defined type not defined".

Når jeg klikker på ok, er der makeret en gul pil ud for linien:

Private Sub ProcessPDF(startpath As String, arkivpath As String)

og linien " Dim rs1 As Recordset" er "rs1 As Recordset" makeret (med blåt)
Avatar billede kjulius Novice
08. oktober 2007 - 21:59 #15
Undskyld, jeg skød lidt genvej. Oprindeligt var ProcessPDF subrutinen placeret i et modul, og ikke i koden til selve formen. Da jeg så skulle lave spisesedlen, var det jo nemmere at indsætte koden lige under event-koden. Men man skal aldrig hoppe over hvor gærdet er lavest! :-(

Opret i stedet et modul og indsæt koden heri. I stedet for Private Sub skal der så stå Public Sub i toppen. Det burde klare problemet...
Avatar billede kjulius Novice
08. oktober 2007 - 22:19 #16
Nej, det er vist ikke det der er problemet. Hos mig kører det også i formens kodevindue. Prøv at tjekke dine referencer. Du skal have et tjek i Microsoft DAO x.x Object Library. Referencerne finder du ved at klikke på menupunktet Referencer i kodevinduet.
Avatar billede kjulius Novice
08. oktober 2007 - 23:17 #17
Jeg mente naturligvis menupunktet Tools og undermenuen Referencer...
Avatar billede redbulldk Juniormester
09. oktober 2007 - 09:32 #18
Hej kjulius

Så sker der noget. Desværre opstår der en ny fejl. Der kommer en VBA boks op ”Run-time error ’3265’: Elementet blev ikke fundet i denne samling.”

Når jeg klikker på ”Debug”, er linien ”rs2.Fields("URI") = arkivPDFfile” makeret med gult.

Samtidigt er PDF filen flyttet over i Arkiv mappen, hvor PDF navnet er tilføjet med XML filnavnet informationerne separeret med _

Dvs. PDF1530021.pdf bliver til 1530021_1530021.pdf. XML filen

Jeg har også prøvet ved forskellig XML og PDF navne, med samme resultat.

Hmm, når det virker hos dig, så må jeg jo lave en fejl.
Avatar billede kjulius Novice
09. oktober 2007 - 10:33 #19
Hmmm.. Det kunne tyde på, at du ikke har læst min kommentar 06/10-2007 15:51:24.

Ikke at feltnavnet betyder noget, bare der er overensstemmelse mellem det feltnavn der er i tabellen og det der bruges i koden.  Så enten skal feltnavnet ændres i tabellen, eller også skal det ændres i koden.

Det er rigtigt, at jeg (uvidende som jeg er om den valgte navnekonvention) for en sikkerheds skyld har tilføjet mappenavnet som et prefix under kopieringen til arkiv-mappen. Hvis du ikke ønsker det, skal det ændres:

arkivPDFfile = arkivpath & "\" & dirname & "_" & PDFfile
ændres til
arkivPDFfile = arkivpath & "\" & PDFfile

Filnavnet blev nu for øvrigt til 1530021_PDF1530021.pdf (PDF i filnavnet smides ikke væk, der bliver alene tilføjet et prefix).
Avatar billede redbulldk Juniormester
09. oktober 2007 - 11:54 #20
Hej kjulius – Det med predix, giver mening. Det er en god måde at kunne foretage evt. spore tilbage.

Den fejl jeg skrev om, er en fejl 40 fra min side. Jeg er kommet til at tage udgangspunkt ved database opbygning, fra en forkert XML fil, så det beklager jeg. Nu har jeg foretaget ny oprettelse af databasen, hvor importen og flytning af PDF + sletningen af XML filen kører der ud af.

Dog når koden skal til at slette biblioteket, kommer der en VBA fejl ”Run-Time error’75’: Path/File access error”.

Debug stopper i linien  ” RmDir path”.

Jeg har prøvet at ændre min brugeprofil til fuld rettigheder, desværre med samme fejl.

Når jeg fjerne ”RmDir path”, kører koden fint, dog selvfølgelig uden at slette biblioteket.

Har du en formodning hvad dette skyldes?
Avatar billede kjulius Novice
09. oktober 2007 - 13:49 #21
Der skal åbenbart ikke så meget til for, at mappen/biblioteket/directoriet ikke kan slettes. Det kan være nok, at du måske har haft mappen åben for at kigge i den fra explorer eller lign. mens koden kørte (for at følge slagets gang).

Jeg var også nødt til at indsætte en dummy Dir instruktion i koden for at flytte dir instruktionens scope fra der hvor der blev læst fra, til et andet dir.
Avatar billede redbulldk Juniormester
09. oktober 2007 - 14:01 #22
Hej kjulius

Jeg siger mange tak.
Avatar billede redbulldk Juniormester
09. oktober 2007 - 14:03 #23
kjulius - skal jeg ikke have et "svar" fra dig, for at jeg kan tildele point til dig?
Avatar billede kjulius Novice
09. oktober 2007 - 14:15 #24
Jo, det er rigtigt. Kun med afgivet svar, har man mulighed for at få tildelt point. Her kommer så mit... :-)
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Dyk ned i databasernes verden på et af vores praksisnære Access-kurser

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester