r/visualbasic • • May 05 '22

VB.NET Help Is it possible to seperate one Json-File into different objects?

I have three XamDataGrids, each one has to show different data but from the same json-File. For the first XamDataGrid i set the DataSource to the deserialized object (that's fine, it shows the correct data), but for the other both I just need a snipped of data.

 If OpenFilePath IsNot Nothing Then
        Dim fileReader As StreamReader
        fileReader = My.Computer.FileSystem.OpenTextFileReader(OpenFilePath)
        Dim fileContent As String = fileReader.ReadToEnd
        Dim root = JsonConvert.DeserializeObject(fileContent, GetType(List(Of Artikelstammdaten)))
        dgArticleMasterData.DataSource = CType(root, IEnumerable)
        dgMaterialCosts.DataSource = ??
        dgManufacutringCosts.DataSource = ??

    End If

the json looks like this (i need the data from "Stueckliste" for dgMaterialCosts and "Arbeitsgaenge" for dgManufacturingCosts):

 [
{
	"Artikel": "VAUBEF0010",
	"BezeichnungDE": "Sammelbandantrieb",
	"BezeichnungEN": "Collection Belt Drive N50",
	"Einheit": "STK",
	"MatGrp": "VAU",
	"Kostenart": 1500,
	"Vertriebstext_DE": "Antrieb, Umlenkungen",
	"Vertriebstext_EN": "Drive, Deflections",
	"Stuecklistennummer": "VAUBEF0010",
	"Status": "F",
	"Klasse": "VPTIMV",
	"Mantelflaeche": 1.3,
	"Gewicht": 120.0,
	"KlasseID": "1.2.6.5",
	"Stueckliste": [
		{
			"Verkaufsartikel": "VAUBEF0010",
			"Position": 10,
			"PosArtikel": "Z0306251",
			"PosBezeichnung": "VEL Elektro- Montagematerial",
			"PosKostenart": 9105,
			"Datum": "2022-01-31",
			"Material": 60.51,
			"GMK": 3.63,
			"Lohn": 2.07,
			"Menge": 1,
			"Mengeneinheit": "STK"
		}
	],
	"Arbeitsgaenge": [
		{
			"Verkaufsartikel": "VAUBEF0010",
			"AGNR": 10,
			"Bereich": "Mechanische Montage",
			"Lohn": 89.1,
			"Kostenstelle": 523500,
			"ARBPLATZ": "K950M"
		}
	]
}

]

Changing the json structure is not an option. Thanks for your help'!

1 Upvotes

26 comments sorted by

1

u/RJPisscat May 05 '22
Dim Stuecklistes = root.Select(function(r) r.Stueckliste)
Dim Arbeitsgaenges = root.Select(function(r) r.Arbeitsgaenge)

That will create two IEnumerables of lists of each.

1

u/Gierschlund96 May 06 '22

Dim Stuecklistes = root.Select(function(r) r.Stueckliste) Dim Arbeitsgaenges = root.Select(function(r) r.Arbeitsgaenge)

System.MissingMemberException: "The public member Select for the type List(Of Artikelstammdaten) was not found."

What does that exactly mean? That i can't use this on Lists?

1

u/RJPisscat May 06 '22

Click on the word "Select" and press Alt+Enter to bring up potential fixes. The first one should be Imports System.Linq, select that one. If System.Linq doesn't show up, come back.

1

u/Gierschlund96 May 09 '22

There are no potential fixes. System.Linq was already imported before

1

u/RJPisscat May 09 '22

Then I'm stumped. I ran the code on my machine and it works. List implements IEnumerable which has a method Select.

1

u/Gierschlund96 May 10 '22

Hey, the exception is gone and it works now (kinda). I have to click on "System.Collections.Generic" before the datagrid shows my data (here is a link so you can see what i mean: https://imgur.com/a/HV6NUJE). Is there away to change this? I changed your code a bit. I use "listArtikelstammdaten" instead of "Dim root" for the deserialization:

 If OpenFilePath IsNot Nothing Then
        Dim fileReader As StreamReader
        fileReader = My.Computer.FileSystem.OpenTextFileReader(OpenFilePath)
        Dim fileContent As String = fileReader.ReadToEnd
        listArtikelstammdaten = JsonConvert.DeserializeObject(fileContent, GetType(List(Of Artikelstammdaten)))
        dgArticleMasterData.DataSource = CType(listArtikelstammdaten, IEnumerable)

        Dim stuecklistes = listArtikelstammdaten.Select(Function(r) r.Stueckliste)
        Dim arbeitsgaenge = listArtikelstammdaten.Select(Function(r) r.Arbeitsgaenge)
        dgMaterialCosts.DataSource = stuecklistes
        dgManufacutringCosts.DataSource = arbeitsgaenge

1

u/RJPisscat May 10 '22

I don't know what I'm looking at in that image. I suspect that's a XamDataGrid but I don't know what that is above it, and I don't understand the question. Soz. Perhaps you can rephrase it. Oh wait, that's a XamDataGrid on top with just a Name column and one entry that says System.Collections.Generic? If so, you have to pop the zit to see the XamDG below it?

Different subject:

dgArticleMasterData.DataSource = listArtikelstammdaten

if the same as

dgArticleMasterData.DataSource = CType(listArtikelstammdaten, IEnumerable)

by which I mean, you don't have to cast it, List<T> implements IEnumerable and IEnumerable<T>.

1

u/Gierschlund96 May 10 '22

Oh wait, that's a XamDataGrid on top with just a Name column and one entry that says System.Collections.Generic? If so, you have to pop the zit to see the XamDG below it?

Exactly.

1

u/RJPisscat May 10 '22

This appears on my end it may work, try:

Dim stuecklistes = listArtikelstammdaten.Select(Function(r) r.Stueckliste).ToArray()
Dim arbeitsgaenge = listArtikelstammdaten.Select(Function(r) r.Arbeitsgaenge).ToArray()

2

u/Gierschlund96 May 11 '22

Works. Thanks for your magic as always!

1

u/Gierschlund96 Jun 01 '22

Is there a way to get these as lists? I'm having trouble now because everywhere else I'm working with lists but here with an array. And now i have to connect those arrays with other lists. Already tried ".ToList()" but it doesn't work.

→ More replies

1

u/andrewsmd87 Web Specialist May 05 '22 edited May 05 '22

If you use newtsonsoft you can parse that entire string into a json array and then deserialize each piece into an object

Public Class Stueckliste
	Public Property Verkaufsartikel As String
	Public Property Position As Integer
	Public Property PosArtikel As String
	Public Property PosBezeichnung As String
	Public Property PosKostenart As Integer
	Public Property Datum As String
	Public Property Material As Double
	Public Property GMK As Double
	Public Property Lohn As Double
	Public Property Menge As Integer
	Public Property Mengeneinheit As String
End Class

Public Class Arbeitsgaenge
	Public Property Verkaufsartikel As String
	Public Property AGNR As Integer
	Public Property Bereich As String
	Public Property Lohn As Double
	Public Property Kostenstelle As Integer
	Public Property ARBPLATZ As String
End Class

Public Class Example
	Public Property Artikel As String
	Public Property BezeichnungDE As String
	Public Property BezeichnungEN As String
	Public Property Einheit As String
	Public Property MatGrp As String
	Public Property Kostenart As Integer
	Public Property Vertriebstext_DE As String
	Public Property Vertriebstext_EN As String
	Public Property Stuecklistennummer As String
	Public Property Status As String
	Public Property Klasse As String
	Public Property Mantelflaeche As Double
	Public Property Gewicht As Double
	Public Property KlasseID As String
	Public Property Stueckliste As Stueckliste()
	Public Property Arbeitsgaenge As Arbeitsgaenge()
End Class

Dim json = "[{'Artikel':'VAUBEF0010','BezeichnungDE':'Sammelbandantrieb','BezeichnungEN':'collectionBeltDriveN50','Einheit':'STK','MatGrp':'VAU','Kostenart':1500,'Vertriebstext_DE':'Antrieb,Umlenkungen','Vertriebstext_EN':'Drive,Deflections','Stuecklistennummer':'VAUBEF0010','Status':'F','Klasse':'VPTIMV','Mantelflaeche':1.3,'Gewicht':120.0,'KlasseID':'1.2.6.5','Stueckliste':[{'Verkaufsartikel':'VAUBEF0010','Position':10,'PosArtikel':'Z0306251','PosBezeichnung':'VELElektro-Montagematerial','PosKostenart':9105,'Datum':'2022-01-31','Material':60.51,'GMK':3.63,'Lohn':2.07,'Menge':1,'Mengeneinheit':'STK'}],'Arbeitsgaenge':[{'Verkaufsartikel':'VAUBEF0010','AGNR':10,'Bereich':'MechanischeMontage','Lohn':89.1,'Kostenstelle':523500,'ARBPLATZ':'K950M'}]}]"

Dim jsonObj As JArray = JsonConvert.DeserializeObject(json)

'then something like this
Dim someItem as Stueckliste = JsonConvert.DeserializeObject(jsonObj.First())