• 0

visual basic 2010


Question

HI,

I am a newbie programmer. I am trying to write an array to a text file. The array gets its data from a linq query using .ToArray. Everytime the array goes to file I get this in the file: VB$AnonymousType_5`4[system.String,System.String,System.String,System.String][]

My code snippet is this:

Dim search As String

search = InputBox("Enter search string")

If File.Exists("MyData.txt") Then

Dim myfile() As String = File.ReadAllLines("MyData.txt")

Dim query1 = From line In myfile

Let Data = line.Split(":"c)

Let iname = Data(0)

Let idescrip = Data(1)

Let ilocation = Data(2)

Let ivalue = FormatCurrency(Data(3))

Where (search <> iname)

Select iname, idescrip, ilocation, ivalue

Dim newFile() = query1.ToArray

lstDisplay.Items.Add(newFile)

Dim myfile2 = File.CreateText("MyData.txt")

Dim outputLine = newFile

myfile2.WriteLine(outputLine)

myfile2.Close()

Any help would be greatly appreciated! Thanks! :blink:

Link to comment
Share on other sites

12 answers to this question

Recommended Posts

  • 0

It's an array of what?

Assuming it's an array of strings, you can simply use the System.IO.File.WriteAllLines() method, passing in the name of the file and the result of your query.

If it's some other type of object then you can't simply write that to a text file, how is .NET supposed to know how you want it written? It'll just write the name of the type, which in case of a LINQ query is an anonymous compiler-generated enumerable type (VB$AnonymousType_5`4[system.String,System.String,System.String,System.String][]) - actually, looking at that type definition, it does appear to be an enumerable of strings, so File.WriteAllLines() should do the trick.

To make things more clear:

File.WriteLine(x) will call x.ToString(), which in most cases is the name of the type of x. Exceptions to that rule would be the String type itself, numeric types, and any type that overrides ToString() to provide a more meaningful string representation.

File.WriteAllLines() will iterate over the collection passed to it, essentially calling File.WriteLine() on each element. So depending on the type of elements it may or not may not do what you want.

So assuming your collection is an IEnumerable of string, File.WriteLine() will write its type, i.e. that cryptic name you got, while File.WriteAllLines will write its actual contents, and assuming that's strings (probably is), that should do what you want.

I hope that makes sense, otherwise feel free to bug me again for more explanations. :wacko:

Link to comment
Share on other sites

  • 0

Thanks for your help. You are correct that Im just trying to print an array of strings. Are you saying in the code above, that the line: myfile2.WriteLine(outputLine) should be myfile2.WriteallLines(outputLine) ? Or where Im actually opening the file :

Dim myfile2 = File.CreateText("MyData.txt")? I tried it where I am writing the file in the first example, but the option WriteAllLines is not available there. If I try it where I am opening the file I get errors referring to WriteAllLines being of type string and the query being of anonymous type. I apologize if my questions seem a little silly, but I am rather green around the gills!

Thanks again.

Link to comment
Share on other sites

  • 0

The program is doing exactly what you're telling it to do, writing the array object to the file, but you want to write the values inside of the array to the text file.

As Dr_Asik recommended, Replace this

Dim newFile() = query1.ToArray
lstDisplay.Items.Add(newFile)
Dim myfile2 = File.CreateText("MyData.txt")
Dim outputLine = newFile

With this. (WriteAllLines will create the file.)

File.WriteAllLines("MyData.txt",query1.ToArray)

If you were writing non-string values (or wanted more control over what gets written) you would most likely need to use a loop.

The For Loop loops through each index of the array and writes each value on a new line.

Dim f = File.CreateText("MyData.txt")
Dim qArray = query1.ToArray

For index As Integer = 1 To UBound(qArray)
	f.WriteLine(qArray(index));
Next

Unrelated note: VB context is horrible (and I'm sure there are multiple errors in the loop code)

Link to comment
Share on other sites

  • 0

Ah. I understand. However, when I do that I get this error:

Error 1 Overload resolution failed because no accessible 'WriteAllLines' can be called with these arguments:

'Public Shared Sub WriteAllLines(path As String, contents As System.Collections.Generic.IEnumerable(Of String))': Option Strict On disallows implicit conversions from '1-dimensional array of <anonymous type> (line 59)' to 'System.Collections.Generic.IEnumerable(Of String)'.

'Public Shared Sub WriteAllLines(path As String, contents() As String)': Value of type '1-dimensional array of <anonymous type> (line 59)' cannot be converted to '1-dimensional array of String' because '<anonymous type> (line 59)' is not derived from 'String'. F:\VB\VB2\MyStuff\MyStuff\frmDisplay.vb 75 13

I even tried turning option strict off, but still got this error.

Link to comment
Share on other sites

  • 0

Somehow I missed your last snippet.

Dim f = File.CreateText("MyData.txt")

Dim qArray = query1.ToArray

For index As Integer = 1 To UBound(qArray)

f.WriteLine(qArray(index));

Next

Tried that and now i just get an empty file.

Link to comment
Share on other sites

  • 0

Try this:

System.IO.File.WriteAllLines("MyData.txt", query1.ToArray())

That will only work if query1 is some sort of List of Strings.

Link to comment
Share on other sites

  • 0

Try this:

System.IO.File.WriteAllLines("MyData.txt", query1.ToArray())

That will only work if query1 is some sort of List of Strings.

You don't even need to call ToArray(), in theory, as WriteAllLines takes any IEnumerable, and the result of a LINQ query is an IEnumerable.

Code:

Dim query = From ... In ... Select ... 
File.WriteAllLines("MyFile.txt", query)

It's that simple. The method creates the file if it doesn't exist, overwrites it otherwise. See System.IO.File.

Link to comment
Share on other sites

  • 0

It does seem awfully simple. But Im still getting this error. :

Error 1 Overload resolution failed because no accessible 'WriteAllLines' can be called with these arguments:

'Public Shared Sub WriteAllLines(path As String, contents As System.Collections.Generic.IEnumerable(Of String))': 'System.Collections.Generic.IEnumerable(Of <anonymous type>)' cannot be converted to 'System.Collections.Generic.IEnumerable(Of String)' because '<anonymous type> (line 59)' is not derived from 'String', as required for the 'Out' generic parameter 'T' in 'Interface IEnumerable(Of Out T)'.

'Public Shared Sub WriteAllLines(path As String, contents() As String)': Option Strict On disallows implicit conversions from 'System.Collections.Generic.IEnumerable(Of <anonymous type>)' to '1-dimensional array of String'.

So, it seems to me to be a problem with anonymous type being converted to string type. Which I'm not understanding because I'm just creating a query from a text file of string data... Am I missing something???

Link to comment
Share on other sites

  • 0

In your LINQ query, this:

Select iname, idescrip, ilocation, ivalue

says each object in the collection is actually 4 strings. So, I was wrong, you don't have an enumerable of strings, you have an enumerable of a type that has 4 members, 4 strings.

You need to do something with it before it's writable to a text file. It could be as simple as concatenating all 4 strings as one:

Select iname + idescrip + ilocation + ivalue ' now you have a collection of strings and you can use WriteAllLines

Or performing it when writing to the file:

        Dim myFile = File.CreateText("MyFile.txt")
        For Each elem In query
            myFile.Write(elem.iname)
            myFile.Write(elem.idescrip)
            'etc
        Next

(Fun fact, C# is MORE verbose than VB here:

select new { iname,  idescrip, ilocation, ivalue }

)

Link to comment
Share on other sites

  • 0

I thought of that too nub...

Select New String iname, idescrip, ilocation, ivalue But it looks for an end of statement, and i tried several combinations with no luck.

Link to comment
Share on other sites

  • 0

Dr_Asik,

This:

Dim myFile = File.CreateText("MyFile.txt")

For Each elem In query

myFile.Write(elem.iname)

myFile.Write(elem.idescrip)

'etc

Next

Did the trick! Thank you very much for your help! And thanks to everyone else for the knowledgeable suggestions, it was definitely a learning experience! :woot:

Link to comment
Share on other sites

This topic is now closed to further replies.
  • Recently Browsing   0 members

    • No registered users viewing this page.