• Privacywetgeving
    Het is bij Helpmij.nl niet toegestaan om persoonsgegevens in een voorbeeld te plaatsen. Alle voorbeelden die persoonsgegevens bevatten zullen zonder opgaaf van reden verwijderd worden. In de vraag zal specifiek vermeld moeten worden dat het om fictieve namen gaat.

XML data rechtstreeks in variabele ipv via opgeslagen bestand [VBA]

Status
Niet open voor verdere reacties.

Ginger

Terugkerende gebruiker
Lid geworden
29 dec 2006
Berichten
2.972
L.s., ik ben samen met een van m'n Progress programmeurs bezig om vanuit Excel rechtstreeks een XML data-bericht in ons logistieke systeem te krijgen. Ik heb het voor elkaar gekregen om heel eenvoudig een XML-schema aan te maken en die te gebruiken bij het genereren van de tabel en daarna dus via OpslaanAls op te slaan als Excel-XML-data type. We - hij - hebben het voor elkaar gekregen om die gegevens in te laden in een variabele (da's niet zo lastig) en die dan door te zetten naar LINUX.
Maar nu wil ik nóg een stapje verder om het mooier te maken... Is het ook mogelijk om een XML dataset aan te maken zónder dat je dus éérst een bestand moet opslaan en die daarna inlezen?

In de bijlage het Excelbestand met daarin de tabel en het XML-schema. En daarnaast het outputbestand die je krijgt na het OpslaanAls en dan XML-data type.

[EDIT] Het XML bericht heb ik even voorzien van een .txt extensie. Haal deze er af om het bestand als .XML te zien.
 

Bijlagen

  • Basis AKPL voor HelpMij.xlsm
    24,2 KB · Weergaven: 48
  • AKPL-01-V1.xml.txt
    35,1 KB · Weergaven: 43
Zo?
Code:
Sub XML_doorzetten()
  Dim myFile As String, text As String, textline As String
  
'  myFile = "I:\Logistics\ICT_Logistiek\Acties\BasisBesteladviezen\AID_ontwikkel\AKPL-01-V1.xml"
'  Open myFile For Input As #1
'  Do Until EOF(1)
'    Line Input #1, textline
'    text = text & textline
'  Loop
'  Close #1
  text = GetXML
  Set objHTTP = CreateObject("WinHttp.WinHttpRequest.5.1")
'  URL = "https://####"
  objHTTP.Open "POST", URL, False
  objHTTP.setRequestHeader "User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)"
  objHTTP.setRequestHeader "Content-type", "application/xml"
  objHTTP.send (text)
End Sub

Function GetXML() As String
    Dim sXML As String
    Dim oRow As Range
    Dim oCell As Range
    Dim sXMLField As String
    sXML = "<?xml version=""1.0"" encoding=""UTF-8"" standalone=""yes""?>"
    sXML = sXML & vbNewLine & "<Artikelen xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"">"
    For Each oRow In Worksheets("Sheet1").ListObjects(1).DataBodyRange.Rows
        sXML = sXML & vbNewLine & "<Artikel>" & vbNewLine
        For Each oCell In oRow.Cells
            sXMLField = Intersect(oCell.EntireColumn, Worksheets("Sheet1").ListObjects(1).HeaderRowRange).Value
            sXML = sXML & "<" & sXMLField & ">"
            sXML = sXML & oCell.Value
            sXML = sXML & "</" & sXMLField & ">" & vbNewLine
        Next
        sXML = sXML & "</Artikel>"
    Next
    GetXML = sXML & "</Artikelen>"
End Function
 
Jan Karel, Dit is mooi zeg. Ik wilde al een eind aan deze vraag maken omdat m'n programmeur terug kwam met de wens om die foldergegevens in een aparte tag te zetten ipv bij elke artikel-tag. Excel kan volgens mij geen meerlaagse tags aan dacht ik. Vandaar dat ik 'm aangaf het dan wel regel voor regel op te gaan pakken en zo tussen tags bouwen (heb ik ooit al eerder voor een ander project gedaan).
Maar mijn oplossing toen was met allerlei "replaces" om zo het veld tussen de tags te krijgen. Maar jouw methode is een héél stuk efficiënter. Dank hiervoor. Ik ga er mee aan de bak.
 
Excel kan inderdaad geen meerlaagse tgs aan, maar met VBA kan je alles zelf regelen.
 
Of ?

Code:
Sub M_snb()
  sn = Cells(1).CurrentRegion
  c01 = "<?xml version=""1.0"" encoding=""UTF-8"" standalone=""yes"" ?>" & vbLf & "<Artikelen xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"">"
    
  For j = 2 To UBound(sn)
    c00 = "<Artikel>" & vbLf & "<>" & Join(Application.Index(sn, j), "</>" & vbLf & "<>") & "</>" & vbLf & "</Artikel>"
    For jj = 1 To UBound(sn, 2)
      c00 = Replace(Replace(c00, "<>", "<" & sn(1, jj) & ">", , 1), "</>", "</" & sn(1, jj) & ">", , 1)
    Next
    c01 = c01 & vbLf & c00 & vblf & "</Artikelen>"
  Next

  CreateObject("scripting.filesystemobject").createtextfile("G:\OF\ginger.xml").write c01
End Sub

c01 bevat dus het gehele XML-bestand.
 
Laatst bewerkt:
Het kan ook met DOMDOCUMENT, de code zorgt dan zelf voor de closing tags (\)
Hier een voorbeeldje met een google maps kml bestand (is dus xml).
Deze oplossing zit dus tussen eenlaags excel en een meerlaags text bestand in.
Je zou hier gestructureerder mee kunnen werken, zelfs met attributes.

Zie ook http://www.freevbcode.com/ShowCode.asp?ID=1919 voor een eenvoudiger voorbeeld.
 

Bijlagen

  • worksheet adressen kml google maps xml update 2.xls
    48 KB · Weergaven: 36
Laatst bewerkt:
Op basis van het door jou geplaatste bestand zet je het xml bestand zo in variabele c00:

Code:
Sub M_snb()
    ThisWorkbook.XmlMaps("Artikelen_Map").Export "G:\OF\ginger.xml", -1
    c00 = CreateObject("scripting.filesystemobject").opentextfile("G:\OF\ginger.xml").readall
End Sub
 
Even niet op het forum geweest... Maar nu dus ook mijn dank snb en alphamax. Zijn weer fijne bijdragen aan m'n project. M'n programmeur vond vooral die laatste one-liner wel leuk, maar verder hebben we toch maar samen besloten om het stuk van OpslaanAls .XML overboord te gooien en alles zelf op te bouwen. Dit kwam ook door het feit dat die programmeur nog een andere opzet in z'n tags wilde hebben (zoals hij zelf zei "toekomst bestendiger").
Nogmaals dank aan alle bijdragers.
 
Zo'n formulering
die programmeur nog een andere opzet in z'n tags wilde hebben (zoals hij zelf zei "toekomst bestendiger").

maakt mij meteen nieuwsgierig....
 
@snb, ha ha ha.... Onverbeterlijk ben je... :D

Hij wilde het aankunnen om meerdere periodes tegelijk in te kunnen lezen, en heeft nu deze structuur opgezet (fake gegevens !!!)
Code:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<actieperioden xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <actieperiode>
		<actieomschrijving>F16 - Najaar: Frankrijk - 2017</actieomschrijving>
		<startweek>201745</startweek>
		<eindweek>201748</eindweek>
		<artikelen/>
    </actieperiode>
    <actieperiode>
		<actieomschrijving>F15 - Zomer: Frankrijk - 2017</actieomschrijving>
		<startweek>201727</startweek>
		<eindweek>201728</eindweek>
		<artikelen>
			<artikel>
				<startweek>201727</startweek>
				<eindweek>201728</eindweek>
				<artikelnummer>101117</artikelnummer>
				<prognose>1234</prognose>
			</artikel>
		</artikelen>
    </actieperiode>
</actieperioden>
In dit voorbeeld zou dus een actieperiode worden aangemaakt (week 45-48) zonder dat daar artikelen voor zijn.
 
nog een andere methode, gebruik makend van de celopmaak:

Code:
Sub M_snb()
    Sheet1.ListObjects(1).DataBodyRange.Copy
    
    With GetObject("New:{1C3B4210-F441-11CE-B9EA-00AA006B1A69}")
       .GetFromClipboard
       c00 = .GetText
       MsgBox Replace(c00, vbTab, vbLf)
    End With
    
    Application.CutCopyMode = False
End Sub

Daarmee kan je laatste opzet lijkt mij bijzonder eenvoudig gerealiseerd worden.
 

Bijlagen

  • __Basis AKPL voor HelpMij.xlsb
    42,8 KB · Weergaven: 42
Laatst bewerkt:
@snb, Maar da's een hele gave procedure! Ik ga 'ns kijken of ik hier ook iets mee kan bereiken. Dank voor deze extra code.
 
Status
Niet open voor verdere reacties.
Terug
Bovenaan Onderaan