Object reference not set to an instance of an object when calling a function - vb.net

I call the function GetDataTable and when it gets to the return line, I get the error message:
Object reference not set to an instance of an object.
Dim DB As New DBConn
Dim gd As New DataAccess.GetData
Dim DT As New DataTable
Dim repotid1 As Decimal = 1150
Dim startdata1 As DateTime = "6/1/2012"
Dim EndDate1 As DateTime = "6/12/2012"
Dim StartDate3 As DateTime = "11/1/2011"
Dim Enddate3 As DateTime = "5/1/2012"
Dim sql1 As String = String.Format("EXEC [dbo].[usp_GetReportData_All] #ReportID=N'{0}', #StartDate=N'{1}' #EndDate=N'{2}', #StartDate2=N'{3}' #EndDate2=N'{4}'", repotid1, startdata1, EndDate1, StartDate3, Enddate3)
DT = DB.GetDataTable(sql1)
Public Class DBConn
Dim gd As New DataAccess.GetData
Public Function GetDataTable(ByVal sql As String) As DataTable
Dim _appID As String = "IS"
Dim _transID As String = "MSSQL01"
Return gd.getDataTable(_appID, _transID, sql) 'I get the error message here
End Function
End Class
Updated. I'll see if I can update with the DataAccess.GetData code. I didn't originally put it in there because our shop use it all the time and have no issues with it.

Without seeing what's in gd.getDataTable, there's not a lot we can do to help you. What kind of application are you writing that is calling this function? Can you put a breakpoint on that line in the editor and step into it to see where the error is occurring? Otherwise, do you have access to the DataAccess.GetData code? If so, you would get a lot more information from it if you threw the original exception without destroying the stack trace:
BAD!!!!
Try
'your code
Catch ex As Exception
Throw New Exception(ex.Message)
End Try
GOOD:
Try
'your code
Catch ex As Exception
Throw
End Try

Related

Variable 'reader' is used before it has been assigned a value. A null reference exception could result at run time

Trying to fix a warning and not sure how to restructure code as reader.IsClosed is throwing a warning that states "Variable 'reader' is used before it has been assigned a value. A null reference exception could result at run time." Logistically, since reader As SqlDataReader && reader is not initialized with a value then I could ignore as should be fine at runtime, but my inexperience would make me believe there is a better way?
Public Function GetTotalItems(ByVal userId As Long) As Int16
Dim lstParam As List(Of SqlParameter) = New List(Of SqlParameter)()
Dim tablMd = Me.GetMetaData()
Dim retList As ArrayList = New ArrayList()
lstParam.Add(New SqlClient.SqlParameter("#" + tablMd.PrimaryKey.ColumnName, 0))
lstParam.Add(New SqlClient.SqlParameter("#UserID", userId))
lstParam.Add(New SqlClient.SqlParameter("#ActionFlag", "SELECT_ITEMS_COUNT"))
Dim spName As String = Me.GetStoreProcname()
Dim reader As SqlDataReader
Try
reader = SqlHelper.ExecuteReader(
Utility.GetConnectionStringSetting(),
CommandType.StoredProcedure,
Me.GetStoreProcname(),
lstParam.ToArray()
)
If (reader.HasRows = True) Then
If (reader.Read()) Then
Dim value As Object = reader(0)
Return CInt(value)
End If
End If
Catch ex As Exception
Throw
Finally
If Not reader.IsClosed Then
reader.Close()
End If
End Try
Return 0
End Function
We can narrow the problem down to this excerpt:
Dim reader As SqlDataReader
Try
reader = SqlHelper.ExecuteReader( ... )
Finally
If Not reader.IsClosed Then reader.Close()
End Try
The problem comes if an exception is thrown by the ExecuteReader() function. In that event, the reader variable is never assigned a value. It's still Nothing when you try to evaluate reader.IsClosed, and that will cause an exception.
Given you don't actually do anything with the exception and the SqlHelper takes care of the connection and command objects, you can narrow the entire function down to just this:
Public Function GetTotalItems(ByVal userId As Long) As Int16
Dim lstParam = {
New SqlClient.SqlParameter("#" + Me.GetMetaData().PrimaryKey.ColumnName, 0),
New SqlClient.SqlParameter("#UserID", userId),
New SqlClient.SqlParameter("#ActionFlag", "SELECT_ITEMS_COUNT")
}
Using reader As SqlDataReader = SqlHelper.ExecuteReader(
Utility.GetConnectionStringSetting(),
CommandType.StoredProcedure,
Me.GetStoreProcname(),
lstParam)
If reader.Read() Then Return CInt(reader(0))
End Using
Return 0
End Function
#jmcilhinney, #o_O, #Chris Dunaway ... Thank you for the help + appreciation + admiration for your knowledge + reverence == deverence(); ... This removed the error:
Public Function GetTotalAmount(ByVal userId As Long) As Decimal
Dim lstParam As List(Of SqlParameter) = New List(Of SqlParameter)()
Dim tablMd = Me.GetMetaData()
Dim retList As ArrayList = New ArrayList()
lstParam.Add(New SqlClient.SqlParameter("#" + tablMd.PrimaryKey.ColumnName, 0))
lstParam.Add(New SqlClient.SqlParameter("#UserID", userId))
lstParam.Add(New SqlClient.SqlParameter("#ActionFlag", "SELECT_TOTAL_AMOUNT"))
Dim spName As String = Me.GetStoreProcname()
Using reader As SqlDataReader = SqlHelper.ExecuteReader(
Utility.GetConnectionStringSetting(),
CommandType.StoredProcedure,
Me.GetStoreProcname(),
lstParam.ToArray()
)
If (reader.HasRows = True) Then
If (reader.Read()) Then
Dim value As Object = reader(0)
Return CDec(value)
End If
End If
End Using
Return 0
End Function

IndexOutOfRangeException was unhandled VBNET

I have a form that retrieves the CurrentYearyear_now and NextYearyear_next from the database. It gives me the error 'IndexOutOfRangeException was unhandled' bcoz I think there is no row to be retrieved. And I wanted to do is, even though there's no data from the table, I can still load the forms and give me a null value to be displayed. I tried everything I know to make it work but I cant resolve the problem. Is there anyway to recode this.
Sub LoadSchoolYear()
Dim conn1 As New MySqlConnection("server=localhost; userid=root; password=root; database=uecp_cens")
Dim dAdapter1 As New MySqlDataAdapter("SELECT year_now, year_next FROM uecp_cens.tblschoolyear", conn1)
Dim dTable1 As New DataSet
Try
dAdapter1.Fill(dTable1, "uecp_cens")
lblYearNow.Text = dTable1.Tables("uecp_cens").Rows(0).Item(0).ToString
lblYearNext.Text = dTable1.Tables("uecp_cens").Rows(0).Item(1).ToString
Catch ex As MySqlException
MsgBox(ex.Message)
Finally
conn1.Dispose()
End Try
End Sub
Any help is appreciated.
If there is no row in the table as you've mentioned you get that error. So check Rows.Count:
Dim yearNow As String = Nothing
Dim yearNext As String = Nothing
If dTable1.Tables("uecp_cens").Rows.Count > 0 Then
yearNow = dTable1.Tables("uecp_cens").Rows(0).Item(0).ToString()
yearNext = dTable1.Tables("uecp_cens").Rows(0).Item(1).ToString()
End If
lblYearNow.Text = yearNow
lblYearNext.Text = yearNext
If instead the field is NULL in the DB it is DBNull.Value and you get an exception if you use Rows(0).Item(0).ToString(). Then use DataRow.IsNull to check it:
If dTable1.Tables("uecp_cens").Rows.Count > 0 Then
Dim row = dTable1.Tables("uecp_cens").Rows(0)
yearNow = If(row.IsNull(0), Nothing, row.Item(0).ToString())
yearNext = If(row.IsNull(1), Nothing, row.Item(1).ToString())
End If

.NET How to get Sql response to string?

After inserting something into the DB I would like to get the server's response.
For example "x rows effected" or other messages, and put them into a string variable.
How do I implement this in code? C# or VB - doesn't matter to me.
I couldn't find anything specific on this, but I am a n00b # programming.
Thank you kindly.Could you kindly provide an example for me? Here is my code:
Private Function insertScr(ByVal byte2insert As Byte()) As Boolean
Dim _con As SqlConnection
Dim queryStmt As String
Dim _cmd As SqlCommand
Dim param As SqlParameter
Try
_con = New SqlConnection(My.Settings.DBconnStr)
queryStmt = "update ErrorLog set screen = #Content where(ErrorLogID = 2)"
_cmd = New SqlCommand(queryStmt, _con)
param = _cmd.Parameters.Add("#Content", SqlDbType.VarBinary)
param.Value = byte2insert
_con.Open()
_cmd.ExecuteNonQuery()
_con.Close()
Return True
Catch ex As Exception
Return False
End Try
End Function
Assuming SQL Server, the SqlConnection object has an InfoMessage event that is raised for each of these sorts of messages (it also has a mode that can be enabled so that error messages are delivered via the same event, see FireInfoMessageEventOnUserErrors)
You would access the text of these messages by extracting the Message property from the second argument passed to your event handler.
Something like:
...
_con = New SqlConnection(My.Settings.DBconnStr)
AddHandler _con.InfoMessage,Sub(sender,e)
MessageBox.Show(e.Message)
End Sub
queryStmt = "update ErrorLog set screen = #Content where(ErrorLogID = 2)"
...
The ExecuteNonQuery() method of the ADO .NET SQLCommand returns rows affected count.
Stored procedures can return values through output parameters or through RETURN value parameter
Private Function insertScr(ByVal byte2insert As Byte()) As Boolean
Dim _con As SqlConnection
Dim queryStmt As String
Dim _cmd As SqlCommand
Dim param As SqlParameter
Dim RowsAffected as Int
Try
_con = New SqlConnection(My.Settings.DBconnStr)
queryStmt = "update ErrorLog set screen = #Content where(ErrorLogID = 2)"
_cmd = New SqlCommand(queryStmt, _con)
param = _cmd.Parameters.Add("#Content", SqlDbType.VarBinary)
param.Value = byte2insert
_con.Open()
RowsAffected = _cmd.ExecuteNonQuery()
_con.Close()
Return True
Catch ex As Exception
Return False
End Try
End Function

VB .NET error handling, pass error to caller

this is my very first project on vb.net and i am now struggling to migrate a vba working add in to a vb.net COM Add-in. I think i'm sort of getting the hang, but error handling has me stymied.
This is a test i've been using to understand the try-catch and how to pass exception to caller
Public Sub test()
Dim ActWkSh As Excel.Worksheet
Dim ActRng As Excel.Range
Dim ActCll As Excel.Range
Dim sVar01 As String
Dim iVar01 As Integer
Dim sVar02 As String
Dim iVar02 As Integer
Dim objVar01 As Object
ActWkSh = Me.Application.ActiveSheet
ActRng = Me.Application.Selection
ActCll = Me.Application.ActiveCell
iVar01 = iVar02 = 1
sVar01 = CStr(ActCll.Value)
sVar02 = CStr(ActCll.Offset(1, 0).Value)
Try
objVar01 = GetValuesV(sVar01, sVar02)
'DO SOMETHING HERE
Catch ex As Exception
MsgBox("ERROR: " + ex.Message)
'LOG ERROR SOMEWHERE
Finally
MsgBox("DONE!")
End Try
End Sub
Private Function GetValuesV(ByVal QryStr As Object, ByVal qryConn As String) As Object
Dim cnn As Object
Dim rs As Object
Try
cnn = CreateObject("ADODB.Connection")
cnn.Open(qryConn)
rs = CreateObject("ADODB.recordset")
rs = cnn.Execute(QryStr)
If rs.EOF = False Then
GetValuesV = rs.GetRows
Else
Throw New System.Exception("Query Return Empty Set")
End If
Catch ex As Exception
Throw ex
Finally
rs.Close()
cnn.Close()
End Try
End Function
i'd like to have the error message up to test, but
MsgBox("ERRORE: " + ex.Message)
pops out something unexpected (Object variable or With block variable not set)
What am i doing wrong here??
Thanks
D
It may be because you're doing a
Throw ex
Try using
Throw
instead. This maintains the error stack, instead of generating a new one each time.
Based on your comments, I think the specific problem you're getting is in your Finally block. You're trying to close the recordset and the connection, but if you got an error when you instantiated them, they will not exist; therefore, you get the Object variable or with block error.
(I would put the connection is a using statement anyway).

How to I call a variable somewhere else in my code in VB?

So, I have the following VB code:
Try
Using verSR As New StreamReader(appDataVersionLoc)
Dim txtVern As String
txtVern = verSR.ReadToEnd()
End Using
Catch ex As Exception
Dim verFile As System.IO.FileStream
verFile = System.IO.File.Create(appDataVersionLoc)
My.Computer.FileSystem.WriteAllText("appDataVersionLoc", "0.0.0.0", True)
MessageBox.Show("Version file missing/corrupt, created a new one.")
End Try
See that variable called "txtVern?" I'm trying to use that somewhere else in my code outside of the Try-End Try block.
Pretty much this:
Try
Using verSR As New StreamReader(appDataVersionLoc)
Dim txtVern As String
txtVern = verSR.ReadToEnd()
End Using
Catch ex As Exception
Dim verFile As System.IO.FileStream
verFile = System.IO.File.Create(appDataVersionLoc)
My.Computer.FileSystem.WriteAllText("appDataVersionLoc", "0.0.0.0", True)
MessageBox.Show("Version file missing/corrupt, created a new one.")
End Try
blahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblah
Dim currentversion As String = txtVern
Now, I'm a complete VB noob, and I'm getting this error:
'txtVern' is not declared. It may be inaccessible due to its
protection level.
How can I fix this?
Thanks!
Variable declared inside any block is visible only inside that block. You have to move declaration before Try block:
Dim txtVern As String = String.Empty
Try
Using verSR As New StreamReader(appDataVersionLoc)
txtVern = verSR.ReadToEnd()
End Using
Catch ex As Exception
Dim verFile As System.IO.FileStream
verFile = System.IO.File.Create(appDataVersionLoc)
My.Computer.FileSystem.WriteAllText("appDataVersionLoc", "0.0.0.0", True)
MessageBox.Show("Version file missing/corrupt, created a new one.")
End Try
blahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblahblah
Dim currentversion As String = txtVern
In declaring your variable txtVern in your try block you are limiting their scope to the try block. Try declaring them at the beginning of your subroutine.