Trim Function doesn't remove any spaces from any side - trim

I try to trim spaces in Calc using a macro.
The Trim function doesn't seem to work
I tried using Trim, LTrim, RTrim but same result.
Anybody have an idea of where is wrong?
oCSL is "Arang and the Magistrate"
oCSR and z should also be like oCSL after Trim but still stays "Arang and the Magistrate   "
Code below:
Dim oAC As Object, oC As Object, oAS As Object, oCSL As String, oCSR As String
Dim oASn As Integer
Dim CellRangeAddress As New com.sun.star.table.CellRangeAddress
Dim CellAddress As New com.sun.star.table.CellAddress
oC = ThisComponent
oAS = oC.getcurrentcontroller.ActiveSheet
oASn = oC.getCurrentController().getActiveSheet().getRangeAddress().sheet
Dim Ll As Integer, Lc As Integer, r As Integer
Dim z As String, y As String
Ll = 400
Lc = 0
r = 400
' Read Each Left Side Line
Do
Do
' Locate Position For Right Side
Do
oCSL = Trim(UCase(oAS.getCellByPosition(Lc, Ll).String)) ' oSCL Value Returned "Arang and the Magistrate"
oCSR = Trim(UCase(oAS.getCellByPosition(7, r).String)) ' oCSR Value Returned "Arang and the Magistrate   "
z = RTrim(oAS.getCellByPosition(7, r).String) ' z Returns Also "Arang and the Magistrate   "
If strcomp(oCSL, oCSR) < 0 Then
ThisComponent.CurrentController.Select(oAS.getCellByPosition(7, r)) ' Reposition Selected Area
'ThisComponent.CurrentController.Select(oAS.getCellByPosition(Lc, Ll)) ' Reposition Selected Area
MsgBox ("At " & r & " Not Found " & Chr(13) & oCSL) ' Not Found
' Insert New Movie
Exit Do
else
If UCase(oCSL) = UCase(OcSR) Then
ThisComponent.CurrentController.Select(oAS.getCellByPosition(7, r)) ' Reposition Selected Area
'MsgBox ("At " & r & " Same Value " & oCSL) ' Same Value
r = r + 1
Exit Do
else
r = r + 1
End If
End If
Loop While Lc <= 4
Lc = Lc + 1
Loop While Lc <= 4
Ll = Ll + 1 ' Next Line
Lc = 0 ' Reset Column
Loop While oCSL <> "" ' getCellByPosition Starts From Col 0 Row 0

I found the reason.
After using Asc() in order to figuring out if it's spaces and it wasn't spaces but special characters.
Sorry for bothering everybody.

Related

What's the best way to parse an SQL fragment string into a List(of string) for a Listbox control?

I'm trying to take this string:
(("DISPLAY_NAME" like N'sadf%') And ("ID" = 2) And ("IsCRITERION" = null))
and parse it into a List(of string) so that it can be displayed like:
(
(
"DISPLAY_NAME" like N'sadf%'
)
And
(
"ID" = 2
)
Or
(
"IsCRITERION" = null
)
)
I'm close but don't quite have it. My code currently looks like:
Dim filterlist As New List(Of String)
Dim temp As String = String.Empty
Dim lvl As Integer = 0
Dim pad As String = String.Empty
For Each chr As Char In originalString '--- filter is the string i posted above
Select Case chr.ToString.ToLower()
Case "("
filterlist.Add(pad.PadLeft(lvl * 5) & chr)
lvl += 1
Case ")"
filterlist.Add(pad.PadLeft(lvl * 5) & temp)
If lvl > 0 Then lvl -= 1
filterlist.Add(pad.PadLeft(lvl * 5) & chr)
'If lvl > 0 Then lvl -= 1
temp = String.Empty
Case Else
temp &= chr
End Select
Next
'--- Removes the empty line produced by generating the List(of String)
filterlist = filterlist.Where(Function(s) Not String.IsNullOrWhiteSpace(s)).ToList()
listSelectedCriteria.DataSource = filterlist
listSelectedCriteria.DataBind()
Unfortunately, the above code produces something close to what I desire but the "And"s and "Or"s are not in the right places:
(
(
"DISPLAY_NAME" like N'sadf%'
)
(
And "ID" = 2
)
(
Or "IsCRITERION" = null
)
)
Would using regular expressions be better? Thanks for the help
Probably the "best" way (although that's getting into "primarily opinion-based" territory) would be to use a parser, but assuming that your input is limited to similar looking strings, here's what I came up with:
Dim originalString = "((""DISPLAY_NAME"" like N'sadf%') And (""ID"" = 2) And (""IsCRITERION"" = null))"
Dim filterlist = New List(Of String)()
Dim temp = New StringBuilder()
Dim lvl = 0
Dim addLine =
Sub(x As String)
filterlist.Add(New String(" ", lvl * 4) & x.Trim())
End Sub
For Each c In originalString
Select Case c
Case "("
If temp.Length > 0 Then
addLine(temp.ToString())
temp.Clear()
End If
addLine("(")
lvl += 1
Case ")"
If temp.Length > 0 Then
addLine(temp.ToString())
temp.Clear()
End If
lvl -= 1
addLine(")")
Case Else
temp.Append(c)
End Select
Next
If temp.Length > 0 Then
addLine(temp.ToString())
temp.Clear()
End If
filterlist.Dump() ' LINQPad ONLY
This results in:
(
(
"DISPLAY_NAME" like N'sadf%'
)
And
(
"ID" = 2
)
And
(
"IsCRITERION" = null
)
)
However, you will probably end up having to add code as you find different inputs that don't quite work how you want.
Instead of looking at each characters, I would start be doing a split. And then add/remove padding depending on what character is at the start.
Dim tempString As String = "((""DISPLAY_NAME"" like N'sadf%') And (""ID"" = 2) And (""IsCRITERION"" = null))"
Dim curPadding As String = ""
Const padding As String = " "
Dim result As New List(Of String)
For Each s As String In Text.RegularExpressions.Regex.Split(tempString, "(?=[\(\)])")
If s <> "" Then
If s.StartsWith("(") Then
result.Add(curPadding & "(")
curPadding &= padding
result.Add(curPadding & s.Substring(1).Trim())
ElseIf s.StartsWith(")") Then
curPadding = curPadding.Substring(padding.Length)
result.Add(curPadding & ")")
result.Add(curPadding & s.Substring(1).Trim())
Else
result.Add(curPadding & s)
End If
End If
Next

How to insert values of string builder to an Integer Stack? (VB.Net)

This code basically takes a mathematical expression and evaluates it.
The following code i have written in VB.net shamelessly taken from here : Expression Evaluation
which has been written in Java.
Public Function evaluate(expression As [String]) As Integer
Dim tokens As Char() = expression.ToCharArray()
' Stack for numbers: 'values'
Dim values As New Stack(Of UInteger)()
' Stack for Operators: 'ops'
Dim ops As New Stack(Of Char)()
For i As Integer = 0 To tokens.Length - 1
' Current token is a whitespace, skip it
If tokens(i) = " "c Then
Continue For
End If
' Current token is a number, push it to stack for numbers
If tokens(i) >= "0"c AndAlso tokens(i) <= "9"c Then
Dim sbuf As New StringBuilder(100)
'Dim sbuf As New String("", 128)
' There may be more than one digits in number
If i < tokens.Length AndAlso tokens(i) >= "0"c AndAlso tokens(i) <= "9"c Then
sbuf.Append(tokens(System.Math.Max(System.Threading.Interlocked.Increment(i), i - 1)))
End If
If sbuf Is Nothing AndAlso sbuf.ToString().Equals("") Then
Else
Dim intgr As Integer
Dim accpt As Boolean = Integer.TryParse(sbuf.ToString(), intgr)
If accpt = True Then
values.Push([Integer].Parse(sbuf.ToString()))
Else
Dim space As String = " "
values.Push(space)
End If
End If
' Current token is an opening brace, push it to 'ops'
ElseIf tokens(i) = "("c Then
ops.Push(tokens(i))
' Closing brace encountered, solve entire brace
ElseIf tokens(i) = ")"c Then
While ops.Peek() <> "("c
values.Push(applyOp(ops.Pop(), values.Pop(), values.Pop()))
End While
ops.Pop()
' Current token is an operator.
ElseIf tokens(i) = "+"c OrElse tokens(i) = "-"c OrElse tokens(i) = "*"c OrElse tokens(i) = "/"c Then
' While top of 'ops' has same or greater precedence to current
' token, which is an operator. Apply operator on top of 'ops'
' to top two elements in values stack
While Not ops.Count = 0 AndAlso hasPrecedence(tokens(i), ops.Peek())
values.Push(applyOp(ops.Pop(), values.Pop(), values.Pop()))
End While
' Push current token to 'ops'.
ops.Push(tokens(i))
End If
Next
' Entire expression has been parsed at this point, apply remaining
' ops to remaining values
While Not ops.Count = 0
values.Push(applyOp(ops.Pop(), values.Pop(), values.Pop()))
End While
' Top of 'values' contains result, return it
Return values.Pop()
End Function
Public Function hasPrecedence(op1 As Char, op2 As Char) As [Boolean]
If op2 = "("c OrElse op2 = ")"c Then
Return False
End If
If (op1 = "*"c OrElse op1 = "/"c) AndAlso (op2 = "+"c OrElse op2 = "-"c) Then
Return False
Else
Return True
End If
End Function
' A utility method to apply an operator 'op' on operands 'a'
' and 'b'. Return the result.
Public Function applyOp(op As Char, b As Integer, a As Integer) As Integer
Select Case op
Case "+"c
Return a + b
Case "-"c
Return a - b
Case "*"c
Return a * b
Case "/"c
If b = 0 Then
'Throw New UnsupportedOperationException("Cannot divide by zero")
End If
Return a \ b
End Select
Return 0
End Function
this is how im using the code :
formula = "10 + 2 * 6"
Dim result As Double = evaluate(formula)
and i keep getting this following error:
Unhandled exception at line 885, column 13 in http:**** DEDOM5KzzVKtsL1tWZwgsquruscgqkpS5bZnMu2kotJDD8R38OukKT4TyG0z97U1A8ZC8o0wLOdVNYqHqQLlZ9egcY6AKpKRjQWMa4aBQG1Hz8t_HRmdQ39BUIKoCWPik5bv4Ej6LauiiQptjuzBMLowwYrLGpq6dAhVvZcB-4b-mV24vCqXJ3jbeKi0&t=6119e399
0x800a139e - Microsoft JScript runtime error: Sys.WebForms.PageRequestManagerServerErrorException: Conversion from string " " to type 'UInteger' is not valid.
Im a beginner but i think that the error is occurring because its not able to covert space into integer.How to deal with the spaces??
Any help is much appreciated:).
VB.NET is strongly-typed, so you simply cannot push anything other than integers onto a Stack(Of Integer). Therefore this code:
Dim space As String = " "
values.Push(space)
will always fail at runtime. (By the way, you want to set Option Explicit On and Option Strict On at the top of every module. If you do that, the line above will already be marked as an error at build time).
I haven't tried executing your code, but why would you need to save the spaces if what you're building is an expression evaluator? It doesn't seem to add anything to the evaluation. Perhaps if you simply don't add the spaces to the stack it will work anyway.

Call function recursively without additional parameter

I wrote vbscript function which search the list of free ports on Unix. So my code looks like this:
Function FindFreePorts(ByVal intPortToStart, ByVal intCountOfPortToSearch, ByVal arrFreePorts)
Dim i, arrCommand, arrTmp, blnFindAllPort, j, strCommand
Dim blnFree, intCountOfFreePorts
strCommand = "lsof -i | awk '{print $8}' | sed -n '/"
For i = intPortToStart To intPortToStart+intCountOfPortToSearch - 1
If i = intPortToStart+intCountOfPortToSearch - 1 Then
strCommand = strCommand & ".*"& i & "$/s/.*://p'"
Else
strCommand = strCommand & ".*:" & i &"\|"
End If
Next
Push arrCommand, strCommand
arrTmp = Array()
arrTmp = ExecuteCommandOnUnix(arrCommand, Null, _
Environment.Value("UNIXHOST_NAME"), _
Environment.Value("UNIXHOST_USER"), _
Environment.Value("UNIXHOST_PWD"))
' Count of busy port is UBound(arrTmp) - the other ports are free
' Find free ports
intCountOfFreePorts = intCountOfPortToSearch
For i = intPortToStart To intPortToStart+intCountOfPortToSearch - 1
blnFree = True
For j = 0 To UBound(arrTmp)
If arrTmp(j) = CStr(i) Then
blnFree = False
j = UBound(arrTmp)
End If
Next
If blnFree Then
Push arrFreePorts, i
intCountOfFreePorts = intCountOfFreePorts - 1
End If
Next
'
If intCountOfFreePorts = 0 Then
blnFindAllPort = True
Else
blnFindAllPort = False
End If
If Not blnFindAllPort Then
' We found UBound(arrFreePorts), we need to find intCountOfPortToSearch - UBound(arrFreePorts)
Do While intCountOfPortToSearch - UBound(arrFreePorts) - 1 <> 0
arrFreePorts = FindFreePorts(intPortToStart + intCountOfPortToSearch + 1, intCountOfPortToSearch - UBound(arrFreePorts) - 1, arrFreePorts)
If intCountOfPortToSearch - UBound(arrFreePorts) - 1 = 0 Then
Exit Do
End If
Loop
End If
FindFreePorts = arrFreePorts
End Function
As you can see I call this function recursively in Do While cycle. Everything works ok but I don't like arrFreePorts parameter here. So I should write this code to execute my function:
arrPort = FindFreePorts(intStartFromPort, intCountToSearch, arrPort)
But I have no idea how to rewrite this function without this parameter. Then I could call it in more simple way:
arrPort = FindFreePorts(intStartFromPort, intCountToSearch)
Thanks in advance.
To keep things (experiments, illustration of #Bond's contribution) simple, let's consider the task of putting the chars of a string into an array.
A function that shall return an array (without getting it via parameter or global) needs to create the array:
Function f1(s) ' default ByRef is ok, because Left and Mid return new (sub)strings
If "" = s Then
f1 = Array() ' return empty array for empty string
Else
Dim t : t = f1(Mid(s, 2)) ' recurse for tail - sorry no tail recursion
f1 = cons(Left(s, 1), t) ' copy! result of cons to f1/function's return value
End If
End Function
The growing of the array could be done inline, but for clarity I use a helper function cons():
Function cons(e, a) ' default ByRef is ok; neither e nor a are changed
ReDim aTmp(UBound(a) + 1) ' create larger array
Dim i : i = 0
aTmp(i) = e ' 'new' head
For i = 1 To UBound(aTmp)
aTmp(i) = a(i - 1) ' copy 'old' elms
Next
cons = aTmp ' copy! aTmp to cons/function's return value
End Function
Calling the function is nice:
WScript.Echo 3, "[" & Join(f1("12456789"), ",") & "]"
The price to pay for avoiding the passing of 'the' array:
a lot of copies (array assingment copies in VBScript)
no tail recursion (I doubt, however, that VBScript exploits it)
about factor 10 slower than the Sub approach ((c) Bond) below
As in this case the recursive calls can/should work on the 'same' array, a Sub does the task more efficiently (and is less complex):
Sub s1(s, a) ' default ByRef is ok; a should be modified, s isn't touched
If "" <> s Then
ReDim Preserve a(UBound(a) + 1) ' grow! a
a(UBound(a)) = Left(s, 1)
s1 Mid(s, 2), a ' tail recursion for tail
End If
End Sub
Calling it looks nasty:
ReDim a(-1) : s1 "123456789", a : WScript.Echo 3, "[" & Join(a, ",") & "]"
But that can be avoided by a wrapper:
Function f2(s)
ReDim aTmp(-1)
s1 s, aTmp
f2 = aTmp
End Function

Creating SQL query in VB.net from a Checkboxlist

I have a checkboxlist and I populate it dynamically from a database. For example after i populate the checkboxlist is like that:
Los Angeles
New York
London
Berlin
Amsterdam
I want to create a SQL query according to the checkboxes are checked. If i want to choose only one city (e.g. only New York) i want the result to be:
(City = 2)
Thats works properly but when i have multiple cities (e.g. New York, London and Amsterdam) i want the result to be for example:
(City = 2) OR (City = 3) OR (City = 5)
Or if i choose Los Angeles and Berlin I want the result to be like this:
(City = 1) OR (City = 4)
How can i achieve this? That's my code below but I am stacked. Any ideas?
Protected Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim var As String = ""
Dim counter As Integer = 0
Dim myList As New List(Of String)()
For i As Integer = 0 To CheckBoxList1.Items.Count - 1
If CheckBoxList1.Items(i).Selected Then
myList.Add(i + 1)
counter = counter + 1
If counter = 1 Then
var = "(City =" & i + 1 & ")"
Else
Console.WriteLine(myList(1))
Dim myArray As String() = myList.ToArray()
For j As Integer = 1 To myArray.Length
Dim var2 As String = " OR (City =" & counter & ")"
var = "(City =" & myArray(0) & ")" & var2
Next
End If
End If
Next
SQL = "SELECT * FROM Data1 WHERE (" & var & ") ORDER BY [ID]"
Session("Search") = SQL
Server.Transfer("Data_Form.aspx")
End Sub
What I recommend most strongly is to look into Table-value Parameters:
http://msdn.microsoft.com/en-us/library/bb675163(v=vs.110).aspx
This will fix your issue and help you avoid sql injection vulnerabilities.
But if you really insist on using string concatenation, try using an IN() condition, where you end up with something more like CITY IN (1,2) instead of (City = 1 OR City = 2). You can make this a bit easier to write by leading with an unused ID, like so:
Dim cityClause As String = " CITY IN (-1{0})" 'start with a valid clause
Dim cityIDs As String = ""
For Each box As ListItem In CheckBoxList1.Items.Where(Function(b) b.Selected)
'Try storing the ID for each city in the value part of each listitem,
' rather than using the index order
cityIDs = cityIDs & "," & box.Value
Next box
cityClause = string.Format(cityClause, cityIDs)
You can use City IN(2,3,5) instead of (City = 2) OR (City = 3) OR (City = 5):
Protected Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim condition As String = ""
For i As Integer = 0 To CheckBoxList1.Items.Count - 1
If CheckBoxList1.Items(i).Selected Then
condition = condition & "," & (i + 1)
End If
Next
SQL = "SELECT * FROM Data1 WHERE (" & condition.SubString(1) & ") ORDER BY [ID]"
Session("Search") = SQL
Server.Transfer("Data_Form.aspx")
End Sub

ASP.Net get columns with values, add them and then divide

I've got some code which is working as it should but it just seems like a bit of a round about way in doing it and wondered if anyone had any ideas of how to tidy it up
Here's my code
Dim TotalNumber As Double
Dim NumberFilled As String
NumberFilled = Nothing
For x = 0 To drCode2a.Tables(0).Columns.Count - 1
If Not drCode2a.Tables(0).Rows(0)(x).ToString() = "0" Then
NumberFilled += drCode2a.Tables(0).Rows(0)(x).ToString() & "-"
TotalNumber = TotalNumber + drCode2a.Tables(0).Rows(0)(x).ToString()
End If
Next
Dim delimiters As Char() = New Char() {"-"c}
Dim TotalNumberFilled As String() = NumberFilled.Split(delimiters, StringSplitOptions.RemoveEmptyEntries)
Dim AverageRating As Double = TotalNumber / TotalNumberFilled.Length
Response.Write(NumberFilled & "<br/>" & TotalNumber & "<br/>" & AverageRating)
Basically for my example NumberFilled = "1-2-" and TotalNumber = 3 and AverageRating = 1.5
It shows that 2 columns were filled out and the total they equal is 3 so the average = 1.5
As I said it works like it should but I'd like to tidy up if possible
Thanks
Dim totalNumber as Double = 0
Dim count as Integer = 0
For x = 0 To drCode2a.Tables(0).Columns.Count - 1
Dim current as Double = 0
If Double.TryParse(drCode2a.Tables(0).Rows(0)(x).ToString(), current) AndAlso current <> 0 Then
count += 1
totalNumber += current
End If
Next
Dim averageRating as Double = totalNumber / count
Here is an alternative. I don't know that it's necessarily better, but it does make use of the StringBuilder object which is a little faster than strings and it keeps the total values as doubles rather than performing double to string to double conversions.
Dim NumberFilled As New StringBuilder("")
Dim TotalNumber as Double
Dim ColumnsFilled as Integer = 0
For each column as DataColumn in drCode2a.Tables(0).Columns
Dim value = drCode2a.Tables(0).Rows(0)(column.ColumnName).ToString()
If Not "0".Equals(value, StringComparison.OrdinalIgnoreCase) Then
If NumberFilled.Length > 0 Then NumberFilled.Append("-")
NumberFilled.Append(value)
TotalNumber = Convert.ToDouble(value)
ColumnsFilled += 1
End If
Next

Resources