Access-o-Mania

Access-Forum (Deutsch/German) => Access Programmierung => Thema gestartet von: Michel72 am Oktober 24, 2016, 10:16:21

Titel: Excel XML Import per VBA aus Access steuern.
Beitrag von: Michel72 am Oktober 24, 2016, 10:16:21
Moin,

ich muss eine XML Datei in Access importieren. Leider macht mir Access daraus 4 Tabellen die auch keinen Bezug zueinander haben, so dass ich diese miteinander in Relation setzen könnte. Excel macht aus der gleichen Datei nur ein Tabellenblatt, genau so wie ich es benötige.
Jetzt gibt es für mich 2 Lösungen, entweder händig den Import in Access programmieren oder was ich mir gedacht habe,
Per Access Excel so zu steuern dass die XML Datei importiert und als xls Datei gespeichert wird, damit ich die Datei dann in Access einlese.
Hmm wenn ich das jetzt so schreibe finde ich das irgendwie umständlich.
Gibt es eine Möglichkeit den XML Import in Access zu steuern?
Wieso macht Excel ein Tabellenblatt und Access 4 Tabellen die keine Beziehung zueinander haben. Keine Schlüsselspalte mit der ich Joinen könnte :-(
Ich muss auch zugeben das ich jetzt nicht der XML Profi bin.

Danke und Viele Grüße
Michael


<?xml version="1.0"?>
<srf:RackFlows xmlns:srf="RackFlowSchema.xsd">
<srf:RackFlow>
    <srf:RelativeStartTime>0</srf:RelativeStartTime>
    <srf:AbsoluteStartTime>29340000</srf:AbsoluteStartTime>
    <srf:RackID>1</srf:RackID>
    <srf:RackEntry>0</srf:RackEntry>
    <srf:RackProcess>228500</srf:RackProcess>
    <srf:RackOut>1607500</srf:RackOut>
    <srf:RackType>D</srf:RackType>
    <srf:RackLoadingTime>29340000</srf:RackLoadingTime>
    <srf:RackIDReading>29340000</srf:RackIDReading>
    <srf:LastSamplePipetting>29544000</srf:LastSamplePipetting>
    <srf:RackMovedOut>29568500</srf:RackMovedOut>
    <srf:LastResultReported>31176000</srf:LastResultReported>
    <srf:RackTAT>1836000</srf:RackTAT>
    <srf:SamplesIDsOnRack>1,2,3,4,5</srf:SamplesIDsOnRack>
    <srf:InputFilesSamples>
      <srf:InputFileSample>
        <srf:SampleId>816487100EDTA-Plasma tfg.</srf:SampleId>
        <srf:Tests>
          <srf:TestInformation IsEflow="false">
            <srf:TestName>PTH</srf:TestName>
            <srf:TestAcn>10061</srf:TestAcn>
          </srf:TestInformation>
        </srf:Tests>
      </srf:InputFileSample>
      <srf:InputFileSample>
        <srf:SampleId>832015553Serum</srf:SampleId>
        <srf:Tests>
          <srf:TestInformation IsEflow="false">
            <srf:TestName>AHCV 2</srf:TestName>
            <srf:TestAcn>10104</srf:TestAcn>
          </srf:TestInformation>
          <srf:TestInformation IsEflow="false">
            <srf:TestName>HIVCOMPT</srf:TestName>
            <srf:TestAcn>10053</srf:TestAcn>
          </srf:TestInformation>
        </srf:Tests>
      </srf:InputFileSample>
      <srf:InputFileSample>
        <srf:SampleId>864759885Serum</srf:SampleId>
        <srf:Tests>
          <srf:TestInformation IsEflow="false">
            <srf:TestName>HCG-BETA</srf:TestName>
            <srf:TestAcn>10072</srf:TestAcn>
          </srf:TestInformation>
        </srf:Tests>
      </srf:InputFileSample>
      <srf:InputFileSample>
        <srf:SampleId>864759888Serum</srf:SampleId>
        <srf:Tests>
          <srf:TestInformation IsEflow="false">
            <srf:TestName>AHAV</srf:TestName>
            <srf:TestAcn>10095</srf:TestAcn>
          </srf:TestInformation>
          <srf:TestInformation IsEflow="false">
            <srf:TestName>AHBS</srf:TestName>
            <srf:TestAcn>10031</srf:TestAcn>
          </srf:TestInformation>
        </srf:Tests>
      </srf:InputFileSample>
      <srf:InputFileSample>
        <srf:SampleId>864759889Serum</srf:SampleId>
        <srf:Tests>
          <srf:TestInformation IsEflow="false">
            <srf:TestName>AHBC</srf:TestName>
            <srf:TestAcn>10037</srf:TestAcn>
          </srf:TestInformation>
        </srf:Tests>
      </srf:InputFileSample>
    </srf:InputFilesSamples>
  </srf:RackFlow>
</srf:RackFlows>
Titel: Re: Excel XML Import per VBA aus Access steuern.
Beitrag von: Wurliwurm am Oktober 24, 2016, 12:33:13
Was Excel kann, ist einfach alles flach machen beim Import, was die Struktur aber eigentlich verhunzt. In der Datei gibt es ja 1:n-Beziehungen von Rackflow zu InputFileSample und von InputFileSample zu TestInformation. Access will das zerlegen beim Import. Warum es keine Surrogatschlüssel hinzufügt, damit man das wieder joinen kann, wundert mich auch. So sind die schön zerlegten Daten nämlich wertlos.

Ich würde an Deiner Stelle jetzt entweder eine XSL-Transformation bauen oder die Datei unter Verwendung der DOM-Bibliothek programmgesteuert importieren.
Titel: Re: Excel XML Import per VBA aus Access steuern.
Beitrag von: Michel72 am Dezember 26, 2016, 17:05:48
Hi Wurliwurm,

Danke für Deine Antwort. Ich hatte bisher nicht wirklich viel Zeit mich mehr damit zu beschäftigen und bin jetzt wieder dran.
XSLT raff ich nicht wirklich wie ich da den Import steuern kann. Hättest Du ein Grundgerüst für den Import mittels DOM Bibl.?

Danke und Grüße
Michael
Titel: Re: Excel XML Import per VBA aus Access steuern.
Beitrag von: Michel72 am Dezember 26, 2016, 17:20:16
ok, hat sich erledigt habe das hier gefunden

http://www.access-im-unternehmen.de/179.0.html (http://www.access-im-unternehmen.de/179.0.html)

Titel: Re: Excel XML Import per VBA aus Access steuern.
Beitrag von: Michel72 am Dezember 28, 2016, 19:59:13
hat sich doch noch nicht erledigt. XML ist nicht meine Welt.
Ich habe anhand des Beispielcodes mal versucht das ganze zu parsen, was mir auch im groben gelingt.
Allerdings bekomme ich nicht den XML-Knoten mit den Tests sauber zerlegt. Ich habe auch keinen blassen schimmer woran es liegt. Der Code ist auch so beschi**** zu lesen von der Beispielseite das es nicht wirklich Spaß macht. Vielleicht hat Jemand eine elegantere Lösung.

Die Hierarchie ist ein Rack kann mehrere Samples haben ein Sample kann mehrere Tests haben.
Hier mal mein Code der Zumindest bis auf die einzelnen Tests pro Sample funktioniert.

Danke.


Public Function ProjekteSchreiben(strDateiname As String)
  Dim objXMLDocument As New MSXML2.DOMDocument
  Dim objXMLDocumentElement As Object
  Dim objXMLProjekt As Object
  Dim objXMLProjektphase As Object
  Dim objXMLProjektleiter As Object
  Dim objXMLTest As Object
  Dim objXMLTests As Object
 

 
 
  Dim cnn As ADODB.Connection
  Dim rstRackFlow As New ADODB.Recordset
  Dim i As Integer
  Dim j As Integer
 
  Dim strRelativeStartTime As Double
 
  Set cnn = CurrentProject.Connection
  rstRackFlow.Open "tblRackFlow", cnn, adOpenDynamic, adLockOptimistic
 
  With objXMLDocument
    .async = False
    .preserveWhiteSpace = False
    .validateOnParse = True
    .resolveExternals = False
  End With
  If objXMLDocument.Load(strDateiname) = True Then
    Set objXMLDocumentElement = objXMLDocument.documentElement
    For i = 0 To objXMLDocumentElement.childNodes.length - 1
      Set objXMLProjekt = objXMLDocumentElement.childNodes.Item(i)
      If objXMLProjekt.nodeName = "srf:RackFlow" Then
        With rstRackFlow
          .AddNew
          strRelativeStartTime = objXMLProjekt.selectSingleNode("srf:RelativeStartTime").Text
          strAbsoluteStartTime = objXMLProjekt.selectSingleNode("srf:AbsoluteStartTime").Text
          strRackID = objXMLProjekt.selectSingleNode("srf:RackID").Text
          strRackEntry = objXMLProjekt.selectSingleNode("srf:RackEntry").Text
          strRackProcess = objXMLProjekt.selectSingleNode("srf:RackProcess").Text
          strRackOut = objXMLProjekt.selectSingleNode("srf:RackOut").Text
          strRackType = objXMLProjekt.selectSingleNode("srf:RackType").Text
          strRackLoadingTime = objXMLProjekt.selectSingleNode("srf:RackLoadingTime").Text
          strRackIDReading = objXMLProjekt.selectSingleNode("srf:RackIDReading").Text
          strLastSamplePipetting = objXMLProjekt.selectSingleNode("srf:LastSamplePipetting").Text
          strRackMovedOut = objXMLProjekt.selectSingleNode("srf:RackMovedOut").Text
          strLastResultReported = objXMLProjekt.selectSingleNode("srf:LastResultReported").Text
          strRackTat = objXMLProjekt.selectSingleNode("srf:RackTAT").Text
          strSamplesIDsOnRack = objXMLProjekt.selectSingleNode("srf:SamplesIDsOnRack").Text
         
         
          ' Einzelne Samples pro Rack parsen
         
          Set objXMLProjektphasen = objXMLProjekt.selectSingleNode("srf:InputFilesSamples")
          If Not objXMLProjektphasen Is Nothing Then
            For j = 0 To objXMLProjektphasen.childNodes.length - 1
            Set objXMLProjektphase = objXMLProjektphasen.childNodes.Item(j)
             
            '  Debug.Print objXMLProjektphasen.nodeName
              If objXMLProjektphase.nodeName = "srf:InputFileSample" Then
                strSampleID = objXMLProjektphase.selectSingleNode("srf:SampleId").Text
               
                ' Tests im Detail bis zu x Tests pro Sample
               
               
                 Set objXMLTests = objXMLProjektphase.selectSingleNode("srf:Tests")
                 If Not objXMLTests Is Nothing Then
                    For k = 0 To objXMLTests.childNodes.length - 1
                    Set objXMLTest = objXMLTests.childNodes.Item(k)
             
                    If objXMLTest.nodeName = "srf:TestInformation" Then

                         strIseFlow = objXMLTest.getAttribute("IsEflow")
                         'strTestName = objXMLTest.selectSingleNode("srf:TestName")
                         'strTestAcn = objXMLTest.selectSingleNode("srf:TestAcn")
                 
                        !RelativeStartTime = strRelativeStartTime
                        !AbsoluteStartTime = strAbsoluteStartTime
                        !RackID = strRackID
                        !RackEntry = RackEntry
                        !RackProcess = strRackProcess
                        !RackIDReading = strRackIDReading
                        !RackLoadingTime = strRackLoadingTime
                        !RackOut = strRackOut
                        !RackType = strRackType
                        !LastSamplePipetting = strLastSamplePipetting
                        !RackMovedOut = strRackMovedOut
                        !RackTAT = strRackTat
                        !SamplesIDsOnRack = strSamplesIDsOnRack
                        !LastResultReported = strLastResultReported
                        !SampleId = strSampleID
                        !IseFlow = strIseFlow
                        !TestName = strTestName
                        !TestAcn = strTestAcn
                       .Update
                      End If
                    Next k
                  End If
              End If
            Next j
          End If
        End With
      End If
    Next i
  Else
    MsgBox objXMLDocument.parseError.reason
  End If
  rstRackFlow.Close
  Set rstProjektphasen = Nothing
  Set rstProjekte = Nothing
  Set cnn = Nothing
End Function

Titel: Re: Excel XML Import per VBA aus Access steuern.
Beitrag von: Michel72 am Dezember 28, 2016, 21:06:41
schön wenn man die Lösung doch noch selbst findet.
Ich hatte die Anweisung .AddNew an falscher Stelle. Hier die Korrektur, relativ weit unten im Code:



If objXMLTest.nodeName = "srf:TestInformation" Then

                         strIseFlow = objXMLTest.getAttribute("IsEflow")
                         strTestName = objXMLTest.selectSingleNode("srf:TestName").Text
                         strTestAcn = objXMLTest.selectSingleNode("srf:TestAcn").Text
                        .AddNew