Sum column on datatable with 2 different results - vb.net

I have a datatable with a Column: Total
this is the datatable:
Totale (datatype: decimal)
2,9
2,9
I need to sum of these columns, then I tried this code:
Dim Totale As Double = dt.AsEnumerable().Sum(Function(r) IIf(IsDBNull(r("Totale")), 0, r("Totale")))
Dim Totale As Decimal= dt.AsEnumerable().Where(Function(r) IsDBNull(r("Totale")) = False).Sum(Function(r) r("Totale"))
Dim Totale As Decimal= Convert.ToDecimal(dt.Compute("SUM(Totale)", "Totale is not null"))
This gives me the result of:
6
6
5,8
which only the last one is correct!
Why do the first 2 sum give me 6 as result?

Because you aren't casting the r("Totale"), so the iterator sums withouth precission, Try:
Dim Totale As Decimal= dt.AsEnumerable().Sum(Function(r) IIf(IsDBNull(r("Totale")), 0, Convert.ToDecimal(r("Totale"))))

It seems like Sum treats the values as integers which causes the rounding. You could try and typecast the values with CDec.
Dim Totale As Double = dt.AsEnumerable().Sum(Function(r) IIf(IsDBNull(r("Totale")), CDec(0), CDec(r("Totale"))))
Dim Totale As Decimal= dt.AsEnumerable().Where(Function(r) IsDBNull(r("Totale")) = False).Sum(Function(r) CDec(r("Totale")))
Dim Totale As Decimal= Convert.ToDecimal(dt.Compute("SUM(Totale)", "Totale is not null"))

Related

Calculating Prices with List Box

Calculating PreTax, Tax, and Total amounts based on items in list box. Here's how it looks currently when executed:
https://drive.google.com/open?id=0B3W0gSES_-fNMmdnU1VTSzR2dFk
Here is the code I have so far:
'load ListBox with test data:
For dblPrices As Double = 1 To 4
lstPrices.Items.Add(dblPrices.ToString("c2"))
Next dblPrices
'calculate pretax total:
Dim dblPretaxTotal As Double = 0
Dim dblSelectedPrice As Double
For intTax As Integer = 0 To lstPrices.Items.Count - 1
lstPrices.SelectedIndex = 0
Dim strPrice As String
strPrice = Convert.ToString(lstPrices.SelectedItem)
Double.TryParse(strPrice, dblSelectedPrice)
dblPretaxTotal = dblSelectedPrice
Next intTax
I only have it programmed to calc and display the PreTax Total currently. It should show $10.00. Any suggestions are welcome.
I think your problem is the failed double conversion.
try this:
dblPretaxTotal += Double.Parse(strPrice, NumberStyles.Currency) * taxRate;
instead of Double.TryParse() without checking for the result. NumberStyles.Currency and a taxrate was also missing.

How to get the count of digits after the comma of a double-number in VB.NET?

Examples:
Double-Number is 56.6789 result should be 4
Double-Number is 12345.67 result should be 2
Double-Number is 12345.6 result should be 1
I have a solution tinkering with strings, but I think there is an mathematical solution?
Please in VB.NET ...
Split the original number and get the length of the upper index (1)
myNumber = 12.3456
Dim count As Integer = Len(Split(CStr(myNumber), Application.DecimalSeparator)(1))
Debug.Print count // prints '4'
edit: replaced "." with decimal separator to ensure use across varying cultures
You can try like this:
Dim x As String = CStr(56.6789)
Dim count = x.Length - InStr(x, ".")
One way to do it is to keep knocking off the whole part, multiplying by 10, repeat until you have an integer:
Dim x As Double = 1.23456
Dim count As Integer = 0
While Math.Floor(x) <> x
x = (x - Math.Floor(x)) * 10D
count = count + 1
End While
Note this will fail if there is an infinite number of decimal places - so you could set a limit on it (If count > 100 Then Exit While)
Another way would be like this, which converts to a string but removes the need to hardcode the separator.
Dim x As Double = 1.23456
Dim x0 As Double = x - Math.Floor(x)
Dim x0String As String = x0.ToString()
Dim count As Integer = x0String.Substring(2, x0String.Length - 2).Length
Using Application.DecimalSeparator also allows a string to be used.
The method with a string will again lose information about an infinite-length fractional part, as it will truncate it.

How to multiply all the values of a column?

I've a DataGridView like this layout:
I would like to find a way to multiply all values of the column "Quota", in particular, I wrote a code like this:
If MetroGrid1.Rows.Count > 0 Then
If MetroGrid1.Columns.Contains("Quota") Then
Dim CostTotal As Decimal = MetroGrid1.Rows.Cast(Of DataGridViewRow) _
.Select(
Function(x)
Return CDec(x.Cells("Quota").Value)
End Function
).Sum
Dim risultato = CostTotal * giocata
The problem is that the only mode available is the sum and average, but there is no multiplication. I would like to find a way to replace .Sum with some command that allows me to multiply or totally change the algorithm if necessary.
To multiply every cell as you go through the grid you can loop through multiplying the values and adding it to a variable... First we'll make sure there is a value and if so lets try and cast that value as a double. If so multiply the old values with the new one and so on...
Dim dblTotal As Double = 0
Dim dblValue As Double = 0
For i As Integer = 0 To MetroGrid1.Rows.Count - 1
If MetroGrid1.Rows(i).Cells("Quota").Value IsNot DBNull.Value Then
If Double.TryParse(MetroGrid1.Rows(i).Cells("Quota").Value.ToString, dblValue) Then
dblTotal *= dblValue
End If
End If
Next

How to manipulate DataSet

i have problem in manipulating DataSet, how can i filter rows without getting the whole records in tables.
here is my codes:
For j As Integer = 0 To sDataSet.Tables(tran_ar_so_t.Name).Rows.Count - 1
Dim nQty, nPrice, nAmount As Double
With sDataSet.Tables(tran_ar_so_t.Name)
nQty = IIf(.Rows(j).Item("nQty") Is DBNull.Value, 0, .Rows(j).Item("nQty")) : nPrice = IIf(.Rows(j).Item("nPrice") Is DBNull.Value, 0, .Rows(j).Item("nPrice"))
ComputeNet(j)
nAmount = net * nQty
.Rows(j).Item("nAmountDue") = nAmount
End With
Next
Maybe DataTable.Select() method can resolve your problem; check this example:
Dim filterCondition As String = "nQty > 10" 'A where statement you need
Dim filteredRows As DataRow() = sDataSet.Tables(tran_ar_so_t.Name).Select(filterCondition)
Replace "nQty > 0" with your filtered condition, then in filteredRows you'll find only the DataRow that match with given condition.

Populating 2 dimensional array using a For loop

Currently I'm trying to fill a 3x3 square with random x's and o's to make a tic tac toe
game. Unfortunately the game doesn't seem to output all the x's and o's. Logically, from what I can see, it should be able to but it's not. Any help would be appreciated.
Shared Sub twodimension()
Dim tic(2, 2) As String
Dim min As Integer
Dim x As String
Dim random As New Random()
Dim i As Integer
Dim x1 As Integer
Dim bound0 As Integer = tic.GetUpperBound(0)
Dim bound1 As Integer = tic.GetLowerBound(1)
For i = 0 To bound0
For x1 = 0 To bound1
min = random.Next(2)
If min = 0 Then
x = "x"
Console.WriteLine("{0}", x)
Else
x = "o"
Console.WriteLine("{0}", x)
End If
Console.Write(" "c)
Next
Console.WriteLine()
Next
End Sub
So presumably you've got this declaration somewhere, right?
Public Shared Tic(2, 2) As String
In your code you've got GetLowerBound which will (almost) always returns zero and instead you should have GetUpperBound().
Dim bound0 As Integer = tic.GetUpperBound(0)
Dim bound1 As Integer = Tic.GetUpperBound(1)
EDIT (in response to comment)
GetUpperBound(int) returns the highest number that you can use for the dimension that you specify.
So for the following array:
Dim MyArray(4, 6, 8) As Integer
Trace.WriteLine(MyArray.GetUpperBound(0)) ''//Returns 4
Trace.WriteLine(MyArray.GetUpperBound(1)) ''//Returns 6
Trace.WriteLine(MyArray.GetUpperBound(2)) ''//Returns 8
GetLowerBound(int) returns the lowest number that you can use for the dimension that you specify. In almost every case this is zero but in older versions of VB (and using some COM interop) you can create arrays that don't "start" at zero and instead start at whatever you wanted. So in old VB you could actually say Dim Bob(1 To 4) As Integer and GetLowerBound(0) would return 1 instead of 0. For the most part there is no reason to even be aware that GetLowerBound exists even.