How many .ToString("N0") can I have? - vb.net

I am getting a warning:
Severity Code Description Project File Line Suppression State
Warning BC42322 Runtime errors might occur when converting 'String' to 'IFormatProvider'.
I have 2 .ToString("N0") in my code in the same Sub. Can I not have 2 in the same sub? They go to different labels but, I am new to VB as well so please do not judge. Thanks!
If Integer.TryParse(input, infantry) Then
Dim hpai = Integer.Parse(frmMainGame.lblHPAI.Text, Globalization.NumberStyles.AllowThousands, Globalization.CultureInfo.InvariantCulture)
frmMainGame.lblHPAI.Text = (hpai - infantry * 2).ToString("N0")
frmMainGame.lblInfantryNumberPlayer.Text -= input.ToString("N0") '<---- One that gets the warning
Else
' handle not an int inputted case
End If

Let's look at this line:
frmMainGame.lblInfantryNumberPlayer.Text -= input.ToString("N0")
You're applying the -= operator to STRINGS. This operator has no meaning for strings. Are you trying to apply some kind of reverse-concatenation? Removing any occurrence of input from within the label text? That code just doesn't make sense at all.
If you're actually trying to do a numeric operation, you need to actually work with numbers... convert the label string to an integer, not the integer to a string.
If Integer.TryParse(input, infantry) Then
Dim hpai = Integer.Parse(frmMainGame.lblHPAI.Text, Globalization.NumberStyles.AllowThousands, Globalization.CultureInfo.InvariantCulture)
frmMainGame.lblHPAI.Text = (hpai - infantry * 2).ToString("N0")
Dim numPlayer = Integer.Parse(frmMainGame.lblInfantryNumberPlayer.Text)
frmMainGame.lblInfantryNumberPlayer.Text = (numplayer - input).ToString("N0") '<---- One that gets the warning
Else
' handle not an int inputted case
End If

Related

Argument not optional, how can I change it?

I'm getting a message Argument not optional running the code below:
Private Sub CommandButton1_Click()
Dim linia As AcadLine
Dim Pt1(0 To 2) As Double
Dim stopien(0 To 3) As Double
Dim segment As Variant
Dim n As Double
Dim h As Double
n = CDbl(TextBox1)
h = CDbl(TextBox2)
Pt1(0) = 10# '
Pt1(1) = 10# '
Pt1(2) = 0# '
segment = Pt1
For Licznik = 0 To n - 1
stopien(0) = segment(0)
stopien(1) = segment(1)
stopien(2) = segment(0) + h
stopien(3) = segment(1)
Set linia = ThisDrawing.ModelSpace.AddLine(stopien)
segment(0) = stopien(2)
segment(1) = stopien(3)
Next
End Sub
I can debug it , but if I write something in the TextBox1 or TextBox2 I get this message.
I don't know how I can fix it
The error message is telling you exactly what the issue is... namely, that you are not supplying a needed argument. In this case, the offending line is below:
Set linia = ThisDrawing.ModelSpace.AddLine(stopien)
The AddLine method takes both a StartPoint and an EndPoint, and you are only supplying one of them.
CDbl to the textbox.. hmm.. Shouldn't that be Textbox1.value ? I think you need more uh error handling on the input for Textbox1 and Textbox2.
For example do something like this before you start converting - so put a breakpoint on your first value set of n = CDbl(Textbox1). Then make sure you can see the debug / immediate views in VBA editor. Then write something like this or add Textbox1 to a watch, and expand it's properties to make sure you are using the object's values correctly.
Debug.print(Textbox1)
Debug.print(Textbox1.value)
To handle problems in conversion or w/e, you want to add error handles to the value checks before you set the values to variables.
MrExcel classic discussion on userform handling input errors

Exception thrown: 'System.IndexOutOfRangeException' in VB.net

So I keep getting the error
Exception thrown: 'System.IndexOutOfRangeException'
For my array counter. I'm still learning Visual Basic but I have programming knowledge in other languages, so I'm not sure if I'm just not translating between syntax properly here, or if it's just a logic error I'm not seeing.
The arrayNumsMultiply() array is an Integer array declared with 6 values. My counter variable was also declared as an Integer previously in the program.
The following code is meant to count through the 6 numbers, check if they have two integers in them (ex: 47, so 4 and 7), and then add them together. From there, it stores it back into the array and wipes the previous value. I have a System.Console.WriteLine in the code to see if the If statement is even being initiated and it's not, but the counter console log is. Any idea on what I may be doing wrong? (The specific line where the error is being thrown is the If arrayNumsMultiply(counter).ToString.Length = 2 Then)
For counter = 0 To 5
If arrayNumsMultiply(counter).ToString.Length = 2 Then
Dim numOne As String = arrayNumsMultiply(counter).ToString().Substring(1, 1)
Dim numTwo As String = arrayNumsMultiply(counter).ToString().Substring(2, 1)
Convert.ToInt32(numOne)
Convert.ToInt32(numTwo)
Dim totalNum As Integer
totalNum = numOne + numTwo
arrayNumsMultiply(counter) = totalNum
System.Console.WriteLine("If statement for adding in an integer working")
End If
System.Console.WriteLine("Counter working")
Next counter
If the length of you string is 2, the the first character is at position 0 and the second character is at position 1. Like most things in .net this is zero based. So the correct code for these lines is...
Dim numOne As String = arrayNumsMultiply(counter).ToString().Substring(0, 1)
Dim numTwo As String = arrayNumsMultiply(counter).ToString().Substring(1, 1)

Type mismatch in for loop including tests of worksheet cell values

I am receiving a type mismatch error in my VBA macro. Here is the essential part of my code:
Public Function CalculateSum(codes As Collection, ws As Worksheet) As Double
On Error GoTo ErrorHandler
If ws Is Nothing Then
MsgBox ("Worksheet is necessery")
Exit Function
End If
Dim balanceColumnIndex, codesCulumnIndex As Integer
Dim searchStartRow, searchEndRow As Integer
balanceColumnIndex = 17
codesColumnIndex = 4
searchStartRow = 7
searchEndRow = ws.Cells(ws.Rows.Count, codesColumnIndex).End(xlUp).Row
Dim result As Double
result = 0#
For counter = searchStartRow To searchEndRow
If Len(ws.Cells(counter, codesColumnIndex)) > 0 And Len(ws.Cells(counter, balanceColumnIndex)) > 0 And _
IsNumeric(ws.Cells(counter, codesColumnIndex).Value) And IsNumeric(ws.Cells(counter, balanceColumnIndex).Value) Then
If Contains(codes, CLng(ws.Cells(counter, codesColumnIndex).Value)) Then
result = result + ws.Cells(counter, balanceColumnIndex).Value
''' ^^^ This line throws a type-mismatch error
End If
End If
Next counter
CalculateSum = result
ErrorHandler:
Debug.Print ("counter: " & counter & "\ncode: " & ws.Cells(counter, codesColumnIndex).Value & "\namount: " & ws.Cells(counter, balanceColumnIndex).Value)
End Function
Now what happens is that a type-mismatch error occures on the line where current row balance is added to result even though:
searchEndRow equals 129, and somehow counter equals 130
cells under current address are empty, yet somehow they pass test for length and numeric values (I stopped to debug at this point, IsNumeric(ws.Cells(counter, codesColumnIndex).Value) returns true!
Now I am simply confused and I don't know what to do. Please help.
As commenters have noted, Cells(...).Value is a Variant. This means that operators may not apply to .Value the way you expect. For tests using Len or other string operations, expressly convert to a string. For example, instead of Len(ws.Cells(...)), try Len(CStr(ws.Cells(...).Value)). That way you will know that Len is giving you the result you expect.
Similarly, where you add to result, use result = result + CDbl(ws.Cells(...).Value) to make sure you are adding Double values together.
To answer your question regarding errors that happen differently on different computers, what I have most often experienced is that it is the specific data in question. As one of the commenters pointed out, Empty is indeed numeric since it implicitly converts to 0! As a result, IsNumeric(Empty) is True. Using CStr guards against that in your code because IsNumeric(CStr(Empty)) = IsNumeric("") = False. Using IsNumeric(CStr(...)) prevents you from trying to add 0# + "", which is a type mismatch. So perhaps the user has an empty cell that you don't have in your test data, and that's causing the problem. That's not the only possibility, just the one I have encountered most.

PDF to Text using PDFSharp

I wrote the following function to read the text out of a PDF file. It is pretty close, but I'm just not familiar enough with all the op codes to get the line spacing right. For example, I'm currently inserting a new line when I see "ET" but that doesn't seem quite right since it may just be the end of a text run, mid line. Could someone help me adjust the parsing? My goal is something similar to Adobe Reader's "Save as other" --> "Text"
Public Function ReadPDFFile(filePath As String,
Optional maxLength As Integer = 0) As String
Dim sbContents As New StringBuilder
Dim cArrayType As Type = GetType(CArray)
Dim cCommentType As Type = GetType(CComment)
Dim cIntegerType As Type = GetType(CInteger)
Dim cNameType As Type = GetType(CName)
Dim cNumberType As Type = GetType(CNumber)
Dim cOperatorType As Type = GetType(COperator)
Dim cRealType As Type = GetType(CReal)
Dim cSequenceType As Type = GetType(CSequence)
Dim cStringType As Type = GetType(CString)
Dim opCodeNameType As Type = GetType(OpCodeName)
Dim ReadObject As Action(Of CObject) = Sub(obj As CObject)
Dim objType As Type = obj.GetType
Select Case objType
Case cArrayType
Dim arrObj As CArray = DirectCast(obj, CArray)
For Each member As CObject In arrObj
ReadObject(member)
Next
Case cOperatorType
Dim opObj As COperator = DirectCast(obj, COperator)
Select Case System.Enum.GetName(opCodeNameType, opObj.OpCode.OpCodeName)
Case "ET", "Tx"
sbContents.Append(vbNewLine)
Case "Tj", "TJ"
For Each operand As CObject In opObj.Operands
ReadObject(operand)
Next
Case "QuoteSingle", "QuoteDbl"
sbContents.Append(vbNewLine)
For Each operand As CObject In opObj.Operands
ReadObject(operand)
Next
Case Else
'Do Nothing
End Select
Case cSequenceType
Dim seqObj As CSequence = DirectCast(obj, CSequence)
For Each member As CObject In seqObj
ReadObject(member)
Next
Case cStringType
sbContents.Append(DirectCast(obj, CString).Value)
Case cCommentType, cIntegerType, cNameType, cNumberType, cRealType
'Do Nothing
Case Else
Throw New NotImplementedException(obj.GetType().AssemblyQualifiedName)
End Select
End Sub
Using pd As PdfDocument = PdfReader.Open(filePath, PdfDocumentOpenMode.ReadOnly)
For Each page As PdfPage In pd.Pages
ReadObject(ContentReader.ReadContent(page))
If maxLength > 0 And sbContents.Length >= maxLength Then
If sbContents.Length > maxLength Then
sbContents.Remove(maxLength - 1, sbContents.Length - maxLength)
End If
Exit For
End If
sbContents.Append(vbNewLine)
Next
End Using
Return sbContents.ToString
End Function
Your code is ignoring almost all operations which change the line. You do consider ' and " which most often imply a change of line but which in the wild are seldom used.
Inside a text object (BT .. ET) you, therefore, should also look out for
tx ty Td Move to the start of the next line, offset from the start of the current line by (tx, ty).
tx ty TD Move to the start of the next line, offset from the start of the current line by (tx, ty). As a side effect, this operator shall set the leading parameter in the text state.
a b c d e f Tm Set the text matrix, Tm, and the text line matrix, Tlm.
T* Move to the start of the next line.
To interpret ', " and T* correctly, you should also look out for
leading TL Set the text leading, Tl, to leading.
If you find multiple text objects (BT .. ET .. BT .. ET), the second one is not necessarily on a new line. You should look out for the special graphics state operators between them:
a b c d e f cm Modify the current transformation matrix (CTM) by concatenating
the specified matrix
q Save the current graphics state
Q Restore the graphics state
Your code is ignoring all numeric arguments to the operations. You should not ignore them, especially:
You should check the parameters of the operators listed above; e.g. while 0 -20 Td starts a new line 20 units down, 20 0 Td remains on the same line and merely starts drawing text 20 units right of the former line start.
You should check the numeric elements of the array parameter of TJ as they may (or may not!) indicate space between two words.
Your code is assuming the Value of CString instances to already contain Unicode encoded character data. This assumption in general is incorrect, the encoding used in PDF strings drawn in text drawing operations is ruled by the font. Thus, you furthermore should also look out for
font size Tf Set the text font, Tf, to font and the text font size, Tfs, to size. font shall be the name of a font resource in the Font subdictionary of the current resource dictionary.
For details you should first and foremost study the PDF specification ISO-32000-1, especially chapter 9 Text with a solid background from chapter 8 Graphics.

Is possible to ignore the TextBox?

I'm creating a program to calculate the average. There are 12 TextBox and I want to create the possibility to leave some fields blank. Now there are only errors and the crash of the program. Is possible to create that?
This is part of code:
ItalianoScritto = (TextBox1.Text)
MatematicaScritto = (TextBox2.Text)
IngleseScritto = (TextBox3.Text)
InformaticaScritto = (TextBox4.Text)
ScienzeScritto = (TextBox5.Text)
FisicaScritto = (TextBox6.Text)
MediaScritto = (ItalianoScritto + MatematicaScritto + IngleseScritto + InformaticaScritto + ScienzeScritto + FisicaScritto) / 6
Label10.Text = Str(MediaScritto)
If i leave blank the textbox1 when I click on the button to calculate the average Vb says Cast not valid from the string "" to type 'Single' and the bar of te textbox1 become yellow
I would do the following:
Iterate over the textboxes and check if you can parse the value into an iteger. If yes, add it to a value list.
Then add all values from that list and divide it by the number of cases.
It is faster than big if-statements and resilient against error
dim TBList as new list(of Textbox)
'add your textboxes to the list here
TbList.add(Textbox1)
...
dim ValList as new List(Of Integer)
for each elem in Tblist
dim value as integer
If integer.tryparse(elem.text,value)=True
ValList.add(Value)
else
'report error or do nothing
end if
next
dim Result as Integer
Dim MaxVal as Integer =0
for each elem in ValList
Maxval +=elem
next
Result = MaxVal / ValList.count
If you need support for point values, just choose double or single instead of Integer.
Also: regardless what you do -CHECK if the values in the textboxes are numbers or not. If you omit the tryparse, somebody will enter "A" and your app will crash and burn
Also: You OPTION STRICT ON!
You just have to check if the TextBox is blank on each one before using the value:
If TextBox7.TextLength <> 0 Then
'Use the value inside
End If
The way to do it depends a lot of your code. You should consider editing your question giving more information (and code) in order to us to help you better.