I want to sum column with blanks - vb.net

I have a column containing amount paid in a sales table. I want to sum the column and return the result to a textbox but I am having error when the table is empty or when there are Some empty fields in the column. Please help me out. The error message I get is Object cannot be cast from DBNull to other types. My code goes thus.
Try
con.open
using command=New OledbCommand("Select SUM(Amt_Paid) From Sales Where Customer = 'Abraham';".con)
Dim total = convert.Toint32(Command.ExecutrScalar)
Textbox1.Text = total.ToString
End Using
con.Close

Reference: SQL NULL Functions
Try using one of the suggested SQL NULL function in the provided link
For Example if the connection is to SQL Server then update the query to use ISNULL which will return a default value if the field is null.
Dim sql = "SELECT SUM(ISNULL(Amt_Paid, 0)) FROM Sales WHERE Customer = 'Abraham';"
Using command = New OleDbCommand(sql, con)
Dim total = convert.Toint32(command.ExecuteScalar)
Textbox1.Text = total.ToString
End Using
In the above any time a Amt_Paid is null it will default to 0 so that no errors will be encountered when summing up the value.
If using another data store refer to the reference link provided before and see if there is an equivalent version provided.

Related

Why is the value extracted from database not showing what is intended?

I have the following SQL Statement:
SELECT StockChild.ProductId, Sum(StockChild.Qty) AS SumOfQty,
PRODUCTDETAILS.Title, Sum(SALESORDERchild.Stockout) AS SumOfStockout
FROM (PRODUCTDETAILS
INNER JOIN SALESORDERchild
ON PRODUCTDETAILS.productID = SALESORDERchild.ProductId)
INNER JOIN StockChild
ON PRODUCTDETAILS.productID = StockChild.ProductID
WHERE (((StockChild.ProductID)=[Forms]![StockChild]![ProductId])
AND ((SALESORDERchild.ProductID)=[Forms]![StockChild]![ProductId]))
GROUP BY StockChild.ProductId, PRODUCTDETAILS.Title;
I'm trying to get the summation of values from 2 different tables using the above SQL Statement in access:
1) Sum of StockChild quantity based on productID
2) Sum of Salesorderchild Stockout based on productID
If i query it separately, i managed to get the values that i needed but i'm unable to put it into a single form.
but when i query it together as above, the values jump all over the place and i can't seem to understand why.
And if i add another record in the salesorderchild, of the already existing isbn, all the values will jump as well.
is there something that i am doing wrongly? or how should i go about to tackle this matter.
I added some explanations in the image attached.
Update:
I was trying another method whereby i just did a normal query for the initial stock to be displayed(which worked fine getting the numbers i need)
and over in the Total stockout i was trying out a
=DSum("[stockout]","[SALESORDERchild]","[ProductId]=" & [Forms]!
[StockChild]![ProductId])
but it was returning me a #Name? did i use this correctly?, should i do a vba code instead or is there a way to do it this way?
i tried the following vba code function as an alternative to select out the value but it was telling me the user-defined type not defined. am i missing out something? - (fixed this part by defining the reference of active x data object)
Private Sub Form_Current()
Dim intI As Integer
Dim fld As Field
Dim rst As ADODB.Recordset
Dim pid As String
pid = ProductID.Value
Set rst = New ADODB.Recordset
rst.Open "SELECT Sum(SALESORDERchild.Stockout) AS SumOfStockout FROM
SALESORDERchild WHERE SALESORDERchild.ProductID ='" & pid & "';",
CurrentProject.Connection, adOpenKeyset, adLockOptimistic
tb_stockout.Value = rst.Fields("SumOfStockout")
End Sub
Done Thanks everyone :)

What's missing / wrong with my SQL Query? (Doesn't return any row)

Why doesn't my query able to return any rows and not go to Else in my conditional statement?
For i As Integer = 0 To dtoffenseinfo2.Rows.Count - 1
Dim dtoffenseinfo3 As New DataTable
Dim adapter3 As New OleDbDataAdapter("SELECT SUM(Price) AS TPRICE FROM tblFuelTransactionLogs " & _
"WHERE Created_Date=#" & Format(dtoffenseinfo2.Rows(i).Item("Dates"), "Short Date") & "#", DBConnection)
If dtoffenseinfo3.Rows.Count <= 0 Then
Else
Dim x As Decimal = dtoffenseinfo3.Rows(0).Item("TPRICE")
cmd.ExecuteNonQuery()
End If
Next
In my query, the value of dtoffenseinfo2.Rows(i).Item("Dates") comes from a lookup table with dates (for the whole month of September), and per loop, the value of the dtoffenseinfo2.Rows.(i)Item("Dates") is 09/01/2014 up to 09/30/2014 respectively.
I already have 09/18/2014 in both tables but it still doesn't return any row. I am also not getting errors. Am I using SELECT SUM() wrong? Sorry for any obvious mistake.
You forgot
adapter3.Fill(dtoffenseinfo3)
That's what's missing. :)
Who says that your query can't return any rows? You're not actually executing it so how would you even know? What's the point of the data adapter if you don't call its Fill method?
There is no Problem in your query, you just need to Fill the adapter to let it know what to populate.

Can't generate a StockID above 10

This is the code that tries to grab the largest StockID from the database (Access database) , but my problem is that it generates StockID's up to "S10", after this it simply doesn't increment any further. This is the subroutine that generates the StockID:
Sub generate_Stock_ID()
Dim Stock_start As String = "S"
Dim Stock_Gen As String = "SELECT MAX(StockID) FROM tblStock WHERE StockID LIKE '" & Stock_start & "%%%' "
Dim da As OleDbDataAdapter = New OleDbDataAdapter(Stock_Gen, conn)
Dim ds As DataSet = New DataSet
da.Fill(ds, "StockID")
Dim dt As DataTable = ds.Tables("StockID")
Dim count As Integer = ds.Tables("StockID").Rows.Count
If ds.Tables("StockID").rows.count = 0 Then
StockID = "S1"
Else
StockID = ds.Tables("StockID").Rows(0).Item(0)
StockID = StockID.Substring(1, (StockID.Length - 1))
StockID = Stock_start & (StockID + 1)
End If
End Sub
Screenshot of my database
Note* there are multiple ID's for various other subroutines which all share the same incrementation issue, so if i fix this i fix the other ones too. So at the moment i think my problem lies in the syntax of my SQL statement, but im open to suggestions.
Thanks!
Don't treat an Integer as String. Otherwese MAX or ORDER BY will use lexicographical instead of numerical order which means that S11 is "lower" than S2.
So you should make this column an int-column and prepend S only where you display it. Then MAX(StockID) returns an Integer, you just have to cast it and add 1:
Using conn As New OleDbConnection("Connection-String")
Using cmd As New OleDbCommand(Stock_Gen, conn)
conn.Open()
Dim stockIDObj As Object = cmd.ExecuteScalar()
If stockIDObj IsNot Nothing Then
Dim maxStockId As Int32 = DirectCast(stockIDObj, Int32)
maxStockId += 1
' ...... '
End If
End Using
End Using
You should also change OPTION STRICT to ON. Then this would never compile since the same variable cannot be used for an Object, String and Integer which is very good since it prevents errors.
If you want to keep it as string you have to cast the substring always in the database which is less readable and less efficient. I also don't know how to do it in access.
If you want to change the type of column in an already populated table you should first add a new column with a similar name which is of type int. If all have S at the beginning you could first remove that, then you can update the new column with the casted int value. Finally you can delete the old column and rename the new to the old.
The root of this issue that StockID is a STRING and 'S1'>'S10' so for all StockId > 10 you get max = 'S1'.
As a fast fix try to change MAX(StockID) to:
SELECT 'S'+CAST(MAX(CAST(SUBSTRING(StockID,2,100) as int)) as varchar(100))
For ACCESS DB try to use:
SELECT "S" & cstr(MAX(CINT(MID(StockID,2,100))))

SQL variable returning 0

When I run the following SQL statement in SQL Server Management Studio it returns a count of 2
SELECT COUNT(*)
FROM Daisy_Copy2
WHERE ChargeCode = '1';
But for some reason when I run the following VB.net code the result variable returns a 0 and doesn't identify that duplicate codes exist.
Dim result As Integer
Using cmdb = New SqlCommand("SELECT COUNT(*) FROM Daisy_Copy2 WHERE ChargeCode = '1'", conn)
Int(result = cmdb.ExecuteScalar())
If result > 1 Then
MessageBox.Show("Duplicate Codes Exist!", "Billing", _
MessageBoxButtons.OK, MessageBoxIcon.Information)
Else
MsgBox(result)
End If
End Using
Can anyone help me understand why?
Any help greatly appreciated.
Instead of ExecuteNonQuery you should use ExecuteScalar
Dim result As Integer = CInt(cmd.ExecuteScalar())
ExecuteNonQuery is normally used for updates or inserts that don't leave a result, so it returns an integer telling you how many rows were affected, not the result itself.
What you most likely are meaning to use is ExecuteScalar which returns the first column of the first row in the result set returned by the query, in this case the integer containing your count.
this is just a way you can use:
Dim Sqlda = New SqlDataAdapter("SELECT COUNT(*) AS tCount FROM Daisy_Copy2 WHERE ChargeCode=1", conn)
Dim sqlds = New DataSet
Sqlda.Fill(sqlds, "Daisy_Copy2")
Dim tblRow As DataRow
For Each tblRow In sqlds.Tables("Daisy_Copy2").Rows
MsgBox(tblRow("tCount").ToString())
Next
use below link to read more about it
System.Data.SqlClient Namespace
Good luck

unable to find specified column in result set index out of bounds index out of range exception

i am having trouble putting a value in a textbox. Each time a ticket is sold i put the total price in a textbox, each time a ticket is sold for the same concert it increases by adding its self to the total price. It works at the first sale, but after that it breaks down. here is the code and thanks in advance.
Private Function DisplayMoneyTaken() As Integer
Dim totalMoney As Integer
'open the database connection
strSQL = "SELECT MAX(Total_Money) FROM Sales WHERE Concert_Id =" + Mid(cboVenue.Text, 1, 4)
conn.Open()
cmd.Connection = conn
cmd.CommandText = strSQL
cmd.CommandType = CommandType.Text
dr = cmd.ExecuteReader()
'read the record returned
dr.Read()
If IsDBNull(dr.Item(0)) Then
totalMoney = txtPrice.Text
Else
DisplayMoneyTaken = dr.Item("Total_Money") + Val(txtPrice.Text)
End If
'close the database
conn.Close()
Return totalMoney
End Function
It doesn't appear that your query has a column named "Total_Money". You didn't name the single column your query returns.
Michael,
When using an aggregate function, it is necessary to also assign an alias to that column.
For example
strSQL = "SELECT MAX(Total_Money) as CaChing FROM Sales WHERE Concert_Id =" + Mid(cboVenue.Text, 1, 4)
If you do not assign an alias, the server will sometimes assign one. But you have to know or guess what it will be. Its a lot better to just pick one that makes sense.
You can also index items with a number, this is what you did when you were checking for NULLs.
This same syntax could have been used when accessing the value.
DisplayMoneyTaken = dr.Item(0) + Val(txtPrice.Text)