My program has a method for adding dictionaries through a text file to the database. Said text file consists of a word, what manner of word it is (i.e. noun, verb, etc.) and then the associated image's file name, all formatted in the form of:
word#type#filename
word2#type#filename2
and so on. To avoid repeats of word entries, I use a MySqlDataReader in conjunction with a query to run through all of the rows and then add any rows that are not yet added. The code looks like this:
Private Sub btnCreateBank_Click(sender As Object, e As EventArgs) Handles btnCreateBank.Click
Dim newOpenDialog As New OpenFileDialog
Dim newFileStream As FileStream = Nothing
newOpenDialog.InitialDirectory = GetFolderPath(SpecialFolder.MyDocuments)
newOpenDialog.Filter = "Text Files (*.txt)|*.txt|All Files (*.*)|*.*"
newOpenDialog.FilterIndex = 1
newOpenDialog.ShowDialog()
Try
newFileStream = newOpenDialog.OpenFile()
If (newFileStream IsNot Nothing) Then
Dim sr As New StreamReader(newFileStream)
Dim fileContents As String = sr.ReadToEnd()
Dim fileContentsArray() As String = Split(fileContents, vbNewLine)
Dim fullSplitArray As New List(Of String)
For i As Integer = 0 To fileContentsArray.Length - 1
fullSplitArray.AddRange(Split(fileContentsArray(i).ToString, "#"))
Next
For j As Integer = 0 To fullSplitArray.Count - 1 Step 3
Dim connString As String = "server=localhost;user=root;database=jakub_project;port=3306;password=password;"
Try
Using conn As New MySqlConnection(connString)
conn.Open()
Dim command As New MySqlCommand("SELECT COUNT(word) FROM words WHERE word=#inputWord", conn)
command.Prepare()
command.Parameters.AddWithValue("#inputWord", fullSplitArray.Item(j))
Dim dataReader As MySqlDataReader = command.ExecuteReader()
While dataReader.Read()
If dataReader.Item(0) = 1 Then
MsgBox(fullSplitArray.Item(j) & " added to system.")
Else
Using conn2 As New MySqlConnection(connString)
conn2.Open()
Dim addCmd As New MySqlCommand("INSERT INTO words(word, wordType, wordFilename) VALUES(#inputWord, #inputType, #inputFilename);", conn2)
addCmd.Prepare()
addCmd.Parameters.AddWithValue("#inputWord", fullSplitArray.Item(j))
addCmd.Parameters.AddWithValue("#inputType", fullSplitArray.Item(j + 1))
addCmd.Parameters.AddWithValue("#inputFilename", fullSplitArray.Item(j + 2))
addCmd.ExecuteNonQuery()
MsgBox(fullSplitArray.Item(j) & " added to system.")
conn2.Close()
End Using
End If
End While
dataReader.Close()
conn.Close()
End Using
Catch ex As Exception
MsgBox("Error: " & ex.ToString())
End Try
Next
End If
Catch ex As Exception
MsgBox("Error: " & ex.ToString())
End Try
End Sub
A prior variant in which I did not include the second connection had given me the right result the first time, adding in eight rows. However, all successive attempts gave out errors that stem from what is supposedly a lack of that second connection. But now, all attempts with this subroutine output a table like this.
+--------+----------------------+----------------------+--------------------------+
| wordID | word | wordType | wordFilename |
+--------+----------------------+----------------------+--------------------------+
| 1 | acorn | noun | acorn.jpg |
| 2 | beach | noun | beach.jpg |
| 3 | chicken | noun | chicken.jpg |
| 4 | dance | verb | dance.jpg |
| 5 | elbow | noun | elbow.gif |
| 6 | fight | verb | fight.gif |
| 7 | grow | verb | grow.jpg |
| 8 | hat | noun | hat.jpg |
| 11 | acorn noun acorn.jpg | beach noun beach.jpg | chicken noun chicken.jpg |
| 12 | dance verb dance.jpg | elbow noun elbow.jpg | fight verb fight.gif |
+--------+----------------------+----------------------+--------------------------+
What I want is for the data to be loaded as seen in the first set of rows, rather than what I am now receiving in the bottom two. But I am unsure where the source of the problem lay.
The error messages don't really tell me what is going on, either. The first error message to appear tells me that the data is too long for the column it is attempting to insert it into. The second error tells me that the integer j in my For loop is out of bounds, which is occurring now because of the system seeming to read the whole string rather than three substrings.
If I am understanding you properly,
To me it looks like there was a possible flaw in your text file splitting sequence. Which is not noticeable in your posted code because you may have corrected the error after finding it?
As for the errors...
The first error is telling you that the data for the field in question (you did not mention which field it was) is too big to field into the allocated space. This too can be quantified as being caused by incorrect splitting
in your splitting sequence.
As for the second error it is unclear but I would assume do not get that error after you corrected the splitting issue?
Finally, it is recommended to move your Command.Prepare so it comes AFTER you have added all your command parameters.
Conclusion After Your Extra Info
After reading your comments below, I was still of the mind that the initial cause of the problems were in your splitting routine.
After use the watch tool to look at the splitting results, it was obvious what was happening. You can see the watch window below
Further more it seems to make more sense to have two separate routines for checking if the word exists and to add a new word if it doesn't exist.
By separating them out of your main processing block it makes it a lot easier to see what is going on...
So I have done that and tested it and it seems to work fine.
The main difference is that I skipped the step where you are reading in a data file and kind of simulated the contents of the in a string....
Private Sub btnCreateBank_Click(sender As Object, e As EventArgs) Handles btnCreateBank.Click
'
Dim counta As Integer = 0
Dim fullSplitArray As New List(Of String)
Dim fileContents As String = ""
Dim fileContentsArray() As String
Dim tmpWord As String = Nothing
Dim tmpType As String = Nothing
Dim tmpFile As String = Nothing
Dim Test As Boolean = False
'
Try
fileContents = "1#acorn#noun#acorn.jpg" & vbNewLine & "2#beach#noun#beach.jpg" & vbNewLine & "3#chicken#noun#chicken.jpg" & vbCrLf & "4#dance#verb#dance.jpg" & vbNewLine & "5#elbow#noun#elbow.gif" & vbNewLine & "6#fight#verb#fight.gif" & vbNewLine & "7#grow#verb#grow.jpg" & vbNewLine & "8#hat#noun#hat.jpg"
fileContentsArray = Split(fileContents, vbNewLine)
For i As Integer = 0 To fileContentsArray.Length - 1
fullSplitArray.AddRange(Split(fileContentsArray(i).ToString, "#"))
Next
For j As Integer = 0 To fullSplitArray.Count - 1 Step 4
Test = False
Try
Test = IsWordAlreadyListed(fullSplitArray(j + 1), tmpWord, tmpType, tmpFile)
If Test Then
MsgBox(fullSplitArray.Item(j + 1) & " already listed in system (" & Trim(tmpWord) & ", " & Trim(tmpType) & ", " & Trim(tmpFile) & ")")
Else
Test = AddNewRow(fullSplitArray(j + 1), fullSplitArray(j + 2), fullSplitArray(j + 3))
End If
Catch ex As Exception
MsgBox("Error: " & ex.ToString())
End Try
Next
Catch ex As Exception
MsgBox("Error: " & ex.ToString())
End Try
Test = Nothing
'
End Sub
Function IsWordAlreadyListed(ByVal ParamWord As String, ByRef pRtnWord As String, ByRef pRtnType As String, ByRef pRtnFile As String) As Boolean
'
'-> Locals
Dim iwalConn As Data.SqlClient.SqlConnection = Nothing
Dim iwalCmd As Data.SqlClient.SqlCommand = Nothing
Dim iwalAdapter As Data.SqlClient.SqlDataReader = Nothing
Dim iwalQuery As String = Nothing
'-> Init
IsWordAlreadyListed = False
iwalConn = New System.Data.SqlClient.SqlConnection()
iwalConn.ConnectionString = "YOUR-CONNECTION-STRING-HERE"
'-> Process Request
If Trim(paramword) <> "" Then
iwalQuery = "SELECT * FROM words WHERE word='" & Trim(ParamWord) & "'"
'-> Query Databanks
iwalCmd = New Data.SqlClient.SqlCommand(iwalQuery, iwalConn)
If iwalCmd.Connection.State = Data.ConnectionState.Closed Then iwalCmd.Connection.Open()
iwalAdapter = iwalCmd.ExecuteReader(Data.CommandBehavior.CloseConnection)
If iwalAdapter.HasRows Then
iwalAdapter.Read()
pRtnWord = iwalAdapter.GetValue(iwalAdapter.GetOrdinal("word"))
pRtnType = iwalAdapter.GetValue(iwalAdapter.GetOrdinal("wordType"))
pRtnFile = iwalAdapter.GetValue(iwalAdapter.GetOrdinal("wordFilename"))
IsWordAlreadyListed = True
End If
If iwalCmd.Connection.State = Data.ConnectionState.Open Then iwalCmd.Connection.Close()
Else
MsgBox("Error: Invalid or missing word parameter!")
End If
'-> tidy up
iwalCmd = Nothing
iwalAdapter = Nothing
iwalQuery = Nothing
iwalConn = Nothing
'
End Function
Function AddNewRow(ByVal ParamWord As String, ByVal ParamType As String, ParamFile As String) As Boolean
'
AddNewRow = False
Dim arnConn As System.Data.SqlClient.SqlConnection = Nothing
Dim arnConnString As String = "YOUR CONNECTION STRING HERE"
arnConn = New System.Data.SqlClient.SqlConnection(arnConnString)
arnConn.Open()
Try
Using arnConn
Dim addCmd As New System.Data.SqlClient.SqlCommand("INSERT INTO words(word, wordType, wordFilename) VALUES(#inputWord, #inputType, #inputFilename);", arnConn)
addCmd.Parameters.AddWithValue("#inputWord", ParamWord)
addCmd.Parameters.AddWithValue("#inputType", ParamType)
addCmd.Parameters.AddWithValue("#inputFilename", ParamFile)
'addCmd.Prepare()
addCmd.ExecuteNonQuery()
MsgBox(ParamWord & " added to system.")
AddNewRow = True
End Using
Catch ex As Exception
MsgBox("Error: " & ex.ToString())
Finally
arnConn.Close()
End Try
End Function
Related
I have an example data in Access2010 .mdb as described below, the PipeId is the same for the three TVObservations. The FS, OB and RB describes the kind of observation, I need in to count the number of observations.
SampleData:
| PipeID | TVObservation | NumberOf |
|--------|---------------|----------|
| 301 | FS | 2 |
| 301 | OB | 2 |
| 301 | RB | 1 |
Needed output:
| PipeID | NumberOf |
|--------|---------------------|
| 301 | FS: 2, OB: 2, RB: 1 |
I can get the number of observations, but returning the observations with a Name/title before it, in one cell is proving difficult.
Count(Iif([TVObservation]="FS",True,IIf([TVObservation]="OB",True,IIf(TVObservation]="RB",True,Null)))) AS NumberOf
As a follow-on from what #krish-km mentioned, here's a function I've adapted from Allen Browne's ConcatRelated function (note that I've removed a lot of the original's general purpose utility, so should only be used for your specific scenario).
Put this in a VBA module...
Public Function ConcatRelated(strField1 As String, _
strField2 As String, _
strRelField As String, _
lngRelFieldVal As Long, _
strOrderBy As String, _
strTable As String, _
Optional strSeparator = ", ") As Variant
On Error GoTo Err_Handler
Dim db As DAO.Database ' Database
Dim rs As DAO.Recordset '
Dim strSql As String ' SQL statement
Dim strOut As String ' Output string to concatenate to.
Dim lngLen As Long ' Length of string.
' Initialize to Null
ConcatRelated = Null
' Find related records limited by related field
strSql = "SELECT " & strRelField & ", " & strField1 & ", " & strField2 _
& " FROM " & strTable & " WHERE " & strRelField & " = " & lngRelFieldVal _
& " ORDER BY " & strOrderBy
Set db = CurrentDb
Set rs = db.OpenRecordset(strSql)
' Loop through related fields to build comma separated list
Do While Not rs.EOF
strOut = strOut & rs.Fields(strField1) & ": " & rs.Fields(strField2) & strSeparator
rs.MoveNext
Loop
rs.Close
' Return the string without the trailing separator.
lngLen = Len(strOut) - Len(strSeparator)
If _
lngLen > 0 _
Then
ConcatRelated = Left(strOut, lngLen)
End If
Exit_Handler:
'Clean up
Set rs = Nothing
Set db = Nothing
Exit Function
Err_Handler:
MsgBox "Error " & Err.Number & ": " & Err.Description, vbExclamation, "ConcatRelated()"
Resume Exit_Handler
End Function
You'll then be able to use this function in an SQL statement.
The first and second arguments are your 2 fields that you want to concatenate in to the comma-separated list; these are passed as strings so use double-quotes.
The third and forth argument is the the field whose value is the same across the records you're trying to summarise (in your case it's PipeID). Note that argument 3 needs to be in double-quotes "PipeID" and argument 4 is the sql-reference field, so mustn't be in quotes tblTvObservations.PipeID.
The fifth argument is the field you've specified in either strField or strField2 that you want the comma separated list to be ordered by.
The sixth and final argument is the table/query name where this data comes from.
Here's an example of it used in an sql query...
SELECT tblTvObservations.PipeID, ConcatRelated("TVObservation","NumberOf","PipeID",tblTvObservations.PipeID,"TVObservation","tblTvObservations") AS NumberOf
FROM tblTvObservations;
...to get the following result:
I need to send an update query to mysql like the following:
UPDATE myTableName SET OldField = NewField, NewField = 'New Value'
WHERE myFieldName = 'myFieldValue'
I need to store the old value of the field "NewField" in the field "OldField" when updating but I also need to update using parameters.
The problem is that I don't know how to send "NewField" (as name of a field) as a parameter like in the following function:
Public Function DBUpdate(ByVal connectionString As String, ByVal Tbl As String, ByVal FldsNValues As Dictionary(Of String, String), Optional ByVal Whe As String = "") As Boolean
Dim iReturn As Boolean
Using SQLConnection As New MySqlConnection(connectionString)
Using sqlCommand As New MySqlCommand()
Dim CmdTxt$ = "UPDATE " & Tbl & " SET "
For Each k In FldsNValues.Keys
CmdTxt &= k & " = #" & k & ", "
Next
CmdTxt = CmdTxt.Substring(0, CmdTxt.Length - 2)
If Whe <> "" Then
CmdTxt &= " WHERE " & Whe
End If
With sqlCommand
.CommandText = CmdTxt
.Connection = SQLConnection
.CommandType = CommandType.Text
For Each k In FldsNValues.Keys
.Parameters.AddWithValue("#" & k, FldsNValues(k))
Next
End With
Try
SQLConnection.Open()
sqlCommand.ExecuteNonQuery()
iReturn = True
Catch ex As MySqlException
MsgBox(ex.Message.ToString)
iReturn = False
Finally
SQLConnection.Close()
End Try
End Using
End Using
Return iReturn
End Function
How can I set a Field Name as parameter?
Is it possible?
This is an example of what I want:
TABLE "Baby" RECORD BEFORE UPDATE
Fld_Id | Fld_Name | Fld_OldValue | Fld_NewValue
1 | Sally | 12 years old | 14 years old
Then I update with:
UPDATE Baby SET Fld_OldValue = Fld_NewValue, Fld_NewValue = '15 years old'
WHERE Fld_Name = 'Sally'
So, after udate:
TABLE "Baby" RECORD AFTER UPDATE
Fld_Id | Fld_Name | Fld_OldValue | Fld_NewValue
1 | Sally | 14 years old | 15 years old
I would like to do this using the function above (so I can use it for all my update queries)
Okay, I think I get what you're asking now. Hopefully the third time's the charm.
It seems the problem is that you're trying to parameterize SET Fld_OldValue = Fld_NewValue, but are unable to pass the column Fld_NewValue as a parameter. (Instead, your function is probably passing the string "Fld_NewValue".)
Unfortunately, you can't do what you want the way you are trying to do it. Parameters are, by definition, a column and a value. They are part of the VB.NET sqlControl class that pass data along with your SQL command, but they cannot pass SQL instructions themselves. (In fact, this behavior is one of the primary reasons to use parameters, because this is how parameterization prevents SQL injection in strings.)
The good news is that there's always a way to get the result you're looking for if you're willing to work around such issues. I can think of two ways make your function work as intended:
1) Write a secondary function that returns the correct value for each field.
This function should (1) determine if the "value" stored in your dictionary is truly a value or is in fact a column name, (2) perform a query to get the value stored in the appropriate column when passed a column name, and (3) return the appropriate value. You can then use this function in the function above to make sure the correct values are set.
2) Use non-parameterized SQL for the columns in question.
This will require a significant rewrite of your function, because the syntax SET k = #k will not always be correct. You will have to add each command (and, if appropriate, parameter) individually in the same loop. Something like:
.CommandText &= k & " = "
If isColumn(k) Then 'You must determine how to evaluate this yourself
.CommandText &= FldsNValues(k)
Else
.CommandText &= "#" & k
.Parameters.AddWithValue("#" & k, FldsNValues(k))
End If
I created a VBA script to pull prices from websites by getting the value within an HTML Class.
Please see VBA Script pull data from website for more context.
This works really well however there are some cases where there is only 1 price (no RRP & sale price) and therefore i need to somehow incorporate an if statement to look for the a class name, if that doesn't exist look for another.
For example I have the following spreadsheet:
| A | B | C |
| | Item | Price |
| | bfd/garden-structures/arbours/arbours-sunflower | |
| | bfd/garden-structures/arbours/tatton-corner-arbour-seat | |
| | bsd/garden-storage/wooden-storage/4-x-2-windsor-garden-storage-chest | |
In this example the first 2 work with the code below: (looking int class VariantPrice & NowValue) however the 3rd example doesn't work as the classes VariantPrice & NowValue do not exist, however it does have the class price & SinglePrice.
The code I have used is below:
Sub BuyDeckingDirect()
Dim ie As New InternetExplorer
Dim doc As HTMLDocument
Dim result As IHTMLElement
Dim result2 As IHTMLElement
Dim item As String
Dim lRow As Long
'ie.Visible = True'
lRow = 2
item = Worksheets("BuyDeckingDirect").Range("B" & lRow).Value
MsgBox "Price Dump Started"
Do Until item = ""
ie.navigate "http://www.buydeckingdirect.co.uk/" & item
Do
DoEvents
Loop Until ie.readyState = READYSTATE_COMPLETE
Set doc = ie.document
Set result = doc.querySelector(".VariantPrice")
Set result2 = result.querySelector(".NowValue")
Worksheets("BuyDeckingDirect").Range("C" & lRow).Value = result2.innerText
lRow = lRow + 1
item = Worksheets("BuyDeckingDirect").Range("B" & lRow).Value
Loop
MsgBox "BuyDeckingDirect Price Dump Complete"
End Sub
Any help would be really appreciated!
Thanks
Jess
Combine both classes in the call to querySelector and if result is Nothing, call it again with the alternative class.
Example:
' ...
Set result = doc.querySelector(".VariantPrice .NowValue")
If result Is Nothing Then
Set result = doc.querySelector(".VariantPrice .price")
End If
' You should consider the fact that you can have neither
If result Is Nothing Then
Worksheets(...etc...).Value = "N/A"
Else
Worksheets(...etc...).Value = result.innerText
End If
Of course you can also check for the existence of the NowValue class after setting result like so:
' ...
Set result = doc.querySelector(".VariantPrice")
If IsNull(result.querySelector(".NowValue")) Then
Set result2 = result.querySelector(".price")
Else
Set result2 = result.querySelector(".NowValue")
End If
Personally, I prefer the 1st option but it's up to your use case.
I have a SQL table which looks like:
+-------------------+
| id member req |
+-------------------+
| 1 Jim 0 |
| 2 Mary 0 |
| 3 Hunter 0 |
+-------------------+
I need to get the id of a certain member through my vb.net application (WinForms) in Visual Basic 2010.
Lets say I wanted to get Mary's id. What is the SQL query to return the id for Mary?
Whats the Query for that?
--------------------------------------------------------------------------------
Possible Query Code:
'My.Settings.username is the name I'm looking up in the database to get the member id.
Dim SQLID As String = "SELECT id FROM members WHERE member= '"
& My.Settings.username & "'"
submitRequest(SQLID)
vagueID.Text = 'ID Here'
First, download the MySQL connector.
Second, add a reference to the MySQL connection to your project.
Third, import the Namespace of which you'll be using many of the classes from to reduce typing (at top of .vb file):
Imports MySql.Data.MySqlClient
Finally in your Form's Load event handler (or other event handler where you wish to display the ID in the label):
'Change to your specific connection string.
Dim strConnectionString As String = "Database=YourDatabaseName;Data Source=localhost;User Id=YourUser;Password=YourPassword"
Dim sqlConnection As New MySqlConnection(strConnectionString)
Dim strCommandText = "SELECT id FROM members WHERE member = #Member"
'Assumes that the ID field is an INT type. Use a Long type if the type is a BIGINT.
Dim intID as Integer
Try
'Open the connection.
sqlConnection.Open()
'Create a command to get the ID.
Dim sqlCommand As MySqlCommand = New MySqlCommand(strCommandText, sqlConnection)
'It is always a good idea to use parameters.
sqlCommand.Parameters.AddWithValue("#Member", My.Settings.username)
vagueID.Text = Convert.ToString(sqlCommand.ExecuteScalar())
Catch ex As Exception
'Error handling goes here.
MsgBox(ex.Message)
Finally
'Always close the connection!
sqlConnection.Close()
End Try
MySQLCon = New MySqlConnection
MySQLCon.ConnectionString = "Database=localhost;Data Source=host;User Id=root;Password=root"
Dim READER As MySqlDataReader
Dim COMMAND As MySqlCommand
Try
MySQLCon.Open()
Dim SQLID As String = "SELECT id FROM members WHERE member='" & My.Settings.username & "'"
COMMAND = New MySqlCommand(SQLID, MySQLCon)
READER = COMMAND.ExecuteReader()
While READER.Read
vagueID.Value2 = READER.GetInt32("id")
End While
MySQLCon.Close()
MySQLCon.Dispose()
Catch ex As Exception
'Do Something
End Try
I have written some code for retrieving 3 seperate columns from my database, yet for some reason it isn't loading all of the records which result from my query.
Or well, at least it doesn't seem to do so.
Also, for some reason it won't show me a messagebox which should tell me howmany records have been read after the reader is closed.
Here's my code:
Public Class frmPlayerLocations
Dim str(2), loc As String
Dim xx, yy As Integer
Dim itm As ListViewItem
Private Sub frmPlayerLocations_Load(sender As Object, e As EventArgs) Handles MyBase.Load
ListView1.Columns.Add("ID", 60, HorizontalAlignment.Left)
ListView1.Columns.Add("Name", 115, HorizontalAlignment.Left)
ListView1.Columns.Add("Approximate Location", 115, HorizontalAlignment.Left)
Dim qry = "SELECT profile.unique_id, profile.name, survivor.worldspace FROM profile, survivor WHERE survivor.unique_id = profile.unique_id AND survivor.is_dead = '0' ORDER BY profile.name"
Dim connection As MySqlConnection
connection = New MySqlConnection()
connection.ConnectionString = "Host=" & adminPanel.IP & ";port=" & adminPanel.port & ";user=" & adminPanel.username & ";password=" & adminPanel.password & ";database=" & adminPanel.DBname & ";"
connection.Open()
Dim cmd As New MySqlCommand(qry, connection)
Dim reader As MySqlDataReader = cmd.ExecuteReader()
Dim count As Integer = 0
While reader.Read()
count += 1
str(0) = reader.GetString(0)
str(1) = reader.GetString(1)
loc = reader.GetString(2)
loc = Mid(loc, loc.IndexOf(",") + 3)
xx = CInt(Replace(Mid(loc, 1, loc.IndexOf(",")), ".", ",", 1, -1, CompareMethod.Text))
xx = (xx / 10000)
loc = Mid(loc, loc.IndexOf(",") + 2)
yy = CInt(Replace(Mid(loc, 1, loc.IndexOf(",")), ".", ",", 1, -1, CompareMethod.Text))
yy = 152 - (yy / 10000)
If xx < 100 Then
If xx < 10 Then
loc = "00" & xx.ToString & " | "
Else
loc = "0" & xx.ToString & " | "
End If
Else : loc = xx.ToString & " | "
End If
If yy < 100 Then
If yy < 10 Then
loc &= "00" & yy.ToString
Else
loc &= "0" & yy.ToString
End If
Else : loc &= yy.ToString
End If
str(2) = loc
itm = New ListViewItem(str)
ListView1.Items.Add(itm)
End While
reader.Close()
connection.Close()
MessageBox.Show(count)
End Sub
End Class
Edit: I noticed that when calling the form twice in a row, the second time I do get this error:
An unhandled exception of type 'System.ArgumentException' occurred in Microsoft.VisualBasic.dll
Additional information: Argument 'Length' must be greater or equal to zero.
And it refers to this line of code:
yy = CInt(Replace(Mid(loc, 1, loc.IndexOf(",")), ".", ",", 1, -1, CompareMethod.Text))
Last but not least, the values which are used in that line of code:
loc "7.305e-04]]" String
yy 131 Integer
PS: This may be helpful: the values which are in survivor.worldspace are in this format initially:
[168,[1291.16,5343.54,0.27]]
If the message box is not being displayed then the most likely situation is that an exception is being thrown inside the while loop which is probably silently caught somewhere else.
Unfortunately there are just too many places where an exception might occur withing that while loop so it's hard to say from just looking at that code. It could be trying to cast a DBNull to string, or an index out of bounds, etc.
My suggestion is to either step through with the debugger and identify the offending line, or put a try catch inside the while loop and put a break-point inside the catch. That should give you information about what (and where) the exception is occurring is..
Based on your update it looks like the problem is the arguments passed to the Mid() functions. Based on your data it looks like you are attempting to get a sub-string of loc using the start index of 1 and the end index of -1 which is what loc.IndexOf(",") returns in that case because there is no , (comma) in loc.
You probably want to re-factor that code a bit.. In particular it looks like you are actually trying to replace . with , but doing it after your attempt to call Mid(). That seems to be your problem!