Showing results for 
Search instead for 
Do you mean 
Reply
Solved! Go to solution

"Parsing" a list in integer in vb. net?

To all

 

A question which must have been addressed or thought about by someone somewhere.

 

I have been looking at exporting / importing my own .txt file type containing elements and nodes list. The idea is to copy a list of user selected NX groups between NX files. I couldn’t find something that does it.

 

I have put together some code based on text file layout I have decided on, see end of the query, and it seems to work. I can select groups containing elements and/or nodes, export the data to a file and re-import it into another NX (file) to create identical groups.

 

Sure enough when I tried importing a file with a large numbers of groups containing a large number of elements and or nodes, the process was extremely slow and I had to kill NX. Alarm started to ring: The approach used is not “correct” (a bit of a brute force approach).

 

Currently using: Dim sLinesInTextFile() As String = File.ReadAllLines(stheInpFileName)

 

I am looking for a way to convert a long string of number (1,2,3,4,99,101,102,201,999) into something shorter resembling something like that:

1: 4,99:102,201,999

Or

1 THRU 4,99 THRU 102,201,999 (some people may recognise the nastran way of writing a SET)

 

I call it (rightly or wrongly) parsing the data.

 

Question: Is anybody aware of an existing Method/Class/Function which can do that? I have the feeling that If have the data “parsed” it might be a lot faster. At the moment each element and/or node ID must be allocated to a Dim theTaggedObjects() As TaggedObject. One can see the loops emerging here!

 

Dim ListofFEElmLabel As New List(Of Integer)
Dim theTaggedObjects() As TaggedObject
Redim theTaggedObjects(ListofFEElmLabel.Count-1)
j=0
For Each ilabel As Integer In ListofFEElmLabel					
	Dim theFEElm As CAE.FEElement = MyFn_GetFEElement(theCAEPart, ilabel)
	If theFEElm IsNot Nothing Then	theTaggedObjects(j)= theFEElm
j+=1
	End if
Next ilabel

 

Maybe there is a way of converting the List (of Integer) to an Array of TaggedObject. The array of taggedobject is needed later to (re-) create the group.

 

theCAEPart.CaeGroups.CreateGroup(stheCAEGroupName, theTaggedObjects)

The layout of the text file can be changed if deemed necessary

Thanks

Regards

 

Example of txt file layout

$-------------------------------------------

Group name = aaaa

Element list = e1,e2,e4,e6

Node list = n1,n2,n3,

'$----

Group name = bbbb

Element list = e1,e2,e40,e60

Node list = n10,n20,n30,

Production: NX9.0.3.4, NX10.0.2.6
Development: VB.NET (amateur level !)
7 REPLIES

Re: "Parsing" a list in integer in vb. net?

[ Edited ]

Use the .NET TextFieldParser class

 

https://msdn.microsoft.com/en-us/library/microsoft.visualbasic.fileio.textfieldparser(v=vs.110).aspx

 

Usage for a csv file would be something like:

 

Using FileReader As New Microsoft.VisualBasic.FileIO.TextFieldParser(myFileName)

    FileReader.TextFieldType = Microsoft.VisualBasic.FileIO.FieldType.Delimited
    FileReader.Delimiters = New String() {","}

    While Not FileReader.EndOfData

        Try

            Dim skipLine As String = FileReader.ReadLine()

            Dim lineFields As String() = FileReader.ReadFields()

        Catch ex As Microsoft.VisualBasic.FileIO.MalformedLineException

        End Try

    End While

    FileReader.Dispose()

End Using

 

 

Re: "Parsing" a list in integer in vb. net?

Thaks for that JimB. Much appreciated

 

I can see a couple of very usefule things in the TextFieldParser

 

What I am not sure is

 

  1. how to "force" the reader to skip a line (or 2)

If a line starting with  the string "group name = " is found then one needs to process the data on the next 2 lines (the FileReader.ReadFields() will do very nicely) because the lines correspond to the elements and nodes belonging to the group name. In other words one is always dealing with a block of 3 sucessive lines

 

2.As far as I can see there is no option to simplify a long line of integer (1,2,3,4,99,101,102,201,999) into something shorter resembling something like that:

1: 4,99:102,201,999

Or

1 THRU 4,99 THRU 102,201,999

when I "export" the data

 

and then recreate the original line when "importing" the data

Production: NX9.0.3.4, NX10.0.2.6
Development: VB.NET (amateur level !)

Re: "Parsing" a list in integer in vb. net?

1) I've modified the example above slightly. To skip a line, just use the ReadLine() method and don't do anything with the string it returns.

 

2) Depends on how you define "Simplify" Smiley Happy  That is always the tradeoff between machine-readable and human-readable (or human enterable) text. You could still use the TextFieldPaser to split into the comma separated fields but you would have to subsequently test to see if any of the fields contained a "THRU" string and fill in the missing values in code.

Re: "Parsing" a list in integer in vb. net?

Thanks. I see the ReadLine() thing now. 

 

Will attempt to include the FileReader insted of the approach I used. May speed up the breaking of the lines where I define all the elements and nodes label.

 

I think the speed issue might related to converting the List of integer (element Label) into an Array of of valid tagged object (fro teh NX group creation). I  know one can do MyList.ToArray but I don't think I can change the type. At the moment I simply loop though each item in the List

 

Thanks

Regards

Production: NX9.0.3.4, NX10.0.2.6
Development: VB.NET (amateur level !)

Re: "Parsing" a list in integer in vb. net?

re-writing the "import" function bae don the suggestiion. Looks a lot neater

So far

 

Using FileReader As New Microsoft.VisualBasic.FileIO.TextFieldParser(stheInpFileName)

	FileReader.TextFieldType = Microsoft.VisualBasic.FileIO.FieldType.Delimited
	FileReader.Delimiters = New String() {",","="}
	FileReader.TrimWhiteSpace = True
	

	While Not FileReader.EndOfData
	
		Try
			Dim currentLine As String = FileReader.ReadLine()

			If DEBUG Then theLW.WriteLine("DEBUG: Line being processed: " & currentLine)
			
			If currentLine.Contains("group name = ") Then
				astemp = currentLine.split("=")
				stheCAEGroupName = astemp(1)

				'Deal with the next 2 lines in the file
				Dim ListofFEElmLabel As New List(Of Integer)
				Dim ListofFENodeLabel As New List(Of Integer)
				
				For i = 1 To 2 ' 1=Element 2 = Node
				
					'Field 0 is "Element List" or "Node List"
					Dim asLineFields As String() = FileReader.ReadFields()
					
					If i = 1 Then
						For j = 1 to asLineFields.Length-1
							ListofFEElmLabel.Add(CInt(Trim(asLineFields(j))))
						Next
					Else 'Node
						For j = 1 to asLineFields.Length-1
							ListofFENodeLabel.Add(CInt(Trim(asLineFields(j))))
						Next
					End if
					
				Next i
			End if
						
		Catch ex As Microsoft.VisualBasic.FileIO.MalformedLineException
			
		End Try

	End While
	FileReader.Dispose()
End Using
Production: NX9.0.3.4, NX10.0.2.6
Development: VB.NET (amateur level !)
Solution
Solution
Accepted by topic author selex_ct
‎03-11-2016 06:54 AM

Re: "Parsing" a list in integer in vb. net?

Another suggestion:

 

Using FileReader As New Microsoft.VisualBasic.FileIO.TextFieldParser(stheInpFileName)

    FileReader.TextFieldType = Microsoft.VisualBasic.FileIO.FieldType.Delimited
    FileReader.Delimiters = New String() {",", "="}
    FileReader.TrimWhiteSpace = True

    While Not FileReader.EndOfData

        Try
            Dim currentLine As String = FileReader.ReadLine()

            If DEBUG Then theLw.WriteLine("DEBUG: Line being processed: " & currentLine)

            If currentLine.StartsWith("group name = ") Then
                stheCAEGroupName = currentLine.Split("=")(1)

                'Deal with the next 2 lines in the file
                Dim ListofFEElmLabel As New List(Of Integer)(readStringFieldsToIntList(FileReader))
                Dim ListofFENodeLabel As New List(Of Integer)(readStringFieldsToIntList(FileReader))

            End If

        Catch ex As Microsoft.VisualBasic.FileIO.MalformedLineException

        End Try

    End While
    FileReader.Dispose()
End Using

 

Where readStringFieldsToInt() is defined as:

 

Function readStringFieldsToIntList(ByRef FileReader As Microsoft.VisualBasic.FileIO.TextFieldParser) As List(Of Integer)

    readStringFieldsToIntList = New List(Of Integer)

    For Each stringField As String In FileReader.ReadFields()
        readStringFieldsToIntList.Add(CInt(Trim(stringField)))
    Next stringField

End Function

Re: "Parsing" a list in integer in vb. net?

[ Edited ]

Very neat. Thanks a lot. Learn everyday. Currently looking at incorporating my current conversion of the List(Of Integer) to a an array of taggedobject into the modified code. I have a couple of ideas which will hopefully speed up the process. Will pass the entire  list of integer to the function which searches for the CAE.FEElement. 

Production: NX9.0.3.4, NX10.0.2.6
Development: VB.NET (amateur level !)