When I use Mid function
MsgBox(Mid(RXdata, RXdataLen - 3, 1))
in vb.net, I always get the following message
Additional information: Argument 'Start' must be greater than zero.
I think it is impossible since the RdataLen is 9, the 'Start' is definitely larger than 9. RXdata is the data that I read from SerialPort.
Any thought on how come it happens?
Thanks
Related
I'm getting an exception report from a vb.net Windows Forms app I made via the exception reporting system I built into it. Some users are getting an exception with message "Value was either too large or too small for a Decimal.Couldn't store <8> in PrdHrs Column. Expected type is Decimal."
The stack trace included tells me the method, and that message narrows down where the exception is being hit, but I can't figure out what "<8>" means. Does that just mean the value of 8, but it's displayed with less than/greater than symbols around it? Or does that imply a certain value type? Google is basically impossible to search for this.
I suspect that that '8' actually is an infinity symbol but it's not displayed properly in whatever you're seeing. I just tried this code:
Dim dbl = Double.PositiveInfinity
Dim table As New DataTable
table.Columns.Add("Number", GetType(Decimal))
table.Rows.Add(dbl)
and this was the message I got:
System.ArgumentException HResult=0x80070057 Message=Value was either too large or too small for a Decimal.Couldn't store <∞> in
Number Column. Expected type is Decimal. Source=System.Data
StackTrace: at System.Data.DataColumn.set_Item(Int32 record, Object
value) at System.Data.DataTable.NewRecordFromArray(Object[] value)
at System.Data.DataRowCollection.Add(Object[] values) at
ConsoleApp1.Module1.Main() in C:\Users\johnm\AppData\Local\Temporary
Projects\ConsoleApp1\Module1.vb:line 12
Inner Exception 1: OverflowException: Value was either too large or
too small for a Decimal.
It's not ideal that you are working with Double values and then storing the results as Decimal values. It may be unavoidable but, if so, you need to do a bit better at validation. You are probably dividing by zero, which is legal for Double values and produces either Double.PositiveInfinity or Double.NegativeInfinity.
The following code is showing result as Nan% if values are zero:
=FORMAT(((Sum(IIF(Fields!flag.Value=1,CINT(Fields!area1.Value),0)))
/ (Sum(IIF(Fields!flag.Value=1,CINT(Fields!UnitArea.Value),0))) *100),"N") + "%"
The simplest way to avoid the divide by zero error here is to not create it in the first place! If you replace the 0 as second return value in the divisor Iif expression with a 1, then the problem goes away.
That said I think your whole expression could do with simplifying somewhat. If I read it correctly you want to determine the proportion of area1 within UnitArea but only when the value of flag is 1. The expression could be thus written:
=Format(
Iif(
Fields!flag.Value = 1,
CInt(Fields!area1.Value) / CInt(Fields!UnitArea.Value),
Nothing
),
"Percent"
)
Note that I've dropped the multiplier and instead used the Format function to return the result of the division as a percentage (you could also simply further by removing the Format function entirely and handling the formatting in the designer).
You don't have to layout the expression with indentation as I have, but the expression builder ignores the whitespace and it does make larger expressions easier to read, so I think its a good habit to get into.
Going to be answering my own question here, but I wanted to post this to get some attention in case anyone else ever comes across this.
Within the BusinessObjects Data Services Designer, I have two decimal(36, 10) values, and I'd like to divide one by the other. In order to account for divide-by-zero situations, I have to first check if the denominator is zero, so I end up with an ifthenelse statement like the following:
ifthenelse(Query.Denominator = 0, 0, Query.Numerator / Query.Denominator)
When I execute my job, however, I end up always getting 0 or 1, rather than a decimal value.
And as I said, I already had an answer here, just wanted to provide this for the community.
An ifthenelse statement is interesting, in that it takes its data type from the second parameter. In the code example above, it assumes the correct data type is the data type of the parameter "0", which happens to be an integer.
When the ifthenelse receives a value from "else", it converts it to an integer. So a value of 0.356 becomes 0 and 0.576 becomes 1.
The trick is to cast the "0" to a decimal(36, 10):
ifthenelse(Query.Denominator = 0, cast(0, 'Decimal(36, 10)'), Query.Numerator / Query.Denominator)
Thanks for this, I thought I was going crazy!
Incidentally, for something slightly simpler, this also works:
ifthenelse(Query.Denominator = 0, 0.0, Query.Numerator / Query.Denominator)
I have a report with a field whose value was the expression:
Fields!TotalPrice.Value/Fields!TotalSlots.Value
Although sometimes TotalSlots was blank and thus I was getting a divide by zero runtime error. So I changed the expression to this:
=IIF(Fields!TotalSlots.Value > 0, Fields!TotalPrice.Value/Fields!TotalSlots.Value,"unknown")
but I'm still getting a divide by zero error. How do I work around this zero divisor issue.
Jamie F's answer is correct. As a tip, you can add a function to your report code to make the division a bit easier to implement in multiple cells, e.g.
Public Function Divider (ByVal Dividend As Double, ByVal Divisor As Double)
If IsNothing(Divisor) Or Divisor = 0
Return 0
Else
Return Dividend/Divisor
End If
End Function
You can then call this in a cell like so:
=Code.Divider(Fields!FieldA.Value, Fields!FieldB.Value)
The VB IIF evaluates all arguments, so it will throw an error if any argument throws an error:
Your formula can be written as:
=IIF(Fields!TotalSlots.Value > 0,
Fields!TotalPrice.Value /
IIF(Fields!TotalSlots.Value > 0,
Fields!TotalSlots.Value,
1 ),
"unknown")
Then even when TotalSlots is zero, the formula still won't encounter a division problem.
I don't think your error is on the calculation. First of all, SSRS deals automatically with this situation. See my third column. And the forth shows your expression:
Your problem is probably somewhere else
This only seems to happens when the division is one of the results of an IIF, not if you just write a formula to divide one by the other, e.g.
=IIF(thing=1,10/0,0)
Before it has evaluated thing, it has already tried to calculate both results, causing an error. You can't use IIF in this way to protect from zero, you have to put the IIF on the bottom line of the division, e.g.
=IIF(thing=1, 10/IIF(divisor=0,-99999999999,divisor),0)
This is not satisfactory, since we've introcudes a weird small non zero number as the result, but it may be ok if you just want a non-error.
Technically, the #error is the correct answer.
Function IIF(arg1, arg2, arg3) always calculates all arguments, before returns a result, so your 2nd argument Fields!TotalPrice.Value/Fields!TotalSlots.Value can return #Error.
Try to use IF(arg1, arg2, arg3) function instead IIF.
=IF(Fields!TotalSlots.Value > 0,
Fields!TotalPrice.Value/Fields!TotalSlots.Value,
"unknown")
When I was 'man fread', I got this:
RETURN VALUE
fread() and fwrite() return the number of items successfully read or written (i.e., not the number of characters). If an error
occurs, or the end-
of-file is reached, the return value is a short item count (or zero).
fread() does not distinguish between end-of-file and error, and callers must use feof(3) and ferror(3) to determine which occurred.
So my question is to how to understand "short item count". Please bear with my English. Why here involves type "short"? Can you someone give an example of what does "short item count" look like? Thanks.
The meaning of "short" in fread man page does not refer to a data type.
"Short" in this case means "less then expected". If fread() expected to read 4 objects, but only read 3, it will return the value 3.
I believe that the the man page should be re-written to say:
"If an error occurs, or the end-of-file is reached, the return value is the number of items successfully read or written up until the error or EOF occurred.
If you want 4, and you have 3, then you're short 1.