04. oktober 2007 - 12:21Der 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>
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??
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
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>
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.
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
'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.
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...
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.
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:
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.
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.
Jo, det er rigtigt. Kun med afgivet svar, har man mulighed for at få tildelt point. Her kommer så mit... :-)
Synes godt om
Ny brugerNybegynder
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.