Search for characters in a string using blueprism - blueprism

str1 ="HEADINGLEY";
str2 ="HDNGLY";
how can i search string 1 to see if it contains all the characters from string 2 in the order they exist in string 2 and return a true or false value using blueprism.
I tried using contains and Filter in Utility- Collection Manipulation

I can't see a way of using the provided utilities to perform this exact action.
It’s easily done in a custom VBO however.
If you create a new page in Utility - Strings, give it inputs of the TARGET and LETTERS strings and a Flag output (I've called mine ORDERMATCH), you can use some vb in a Code stage such as the below to return a True/False value.
Dim CurPosition as Integer
Dim LastPosition as Integer
ORDERMATCH = False
CurPosition = 0
LastPosition = 0
For Each c As Char in LETTERS
CurPosition = TARGET.IndexOf(c)
If CurPosition > LastPosition Then
ORDERMATCH = True
Else
ORDERMATCH = False
Exit For
End If
LastPosition = CurPosition
CurPosition = 0
Next
It is also possible to perform this task with an object or process that follows the same basic steps:

Related

Put a space in front of every capital letter in a string

I want to put spaces before each capital letter in a string.
So turn this: TheQuickBrownFox
into this: The Quick Brown Fox
This is the code I have so far: it finds uppercase chars in the string and shows each upper letter in a Message Box.
I can't figure out where to go from here:
Dim input As String = "TheQuickBrownFox"
For i As Integer = 0 To input.Length - 1
Dim c As Char = input(i)
If Char.IsUpper(c) Then
MsgBox(c)
End If
Next
I've googled around but I wasn't able to find a solution for visual basic.
A couple of example using LINQ:
Imports System.Linq
Imports System.Text
Dim input As String = "TheQuickBrownFox"
In case you don't know it, a String is a collection of Chars, so you can iterate the string content using a ForEach loop (e.g., For Each c As Char In input).
▶ Generate a string from an collection of chars (Enumerable(Of Char)), excluding the first uppercase char if it's the first in the string.
The second parameter of a Select() method, when specified (in Select(Function(c, i) ...)), represents the index of the element currently processed.
String.Concat() rebuilds a string from the Enumerable(Of Char) that the Select() method generates:
Dim result = String.Concat(input.Select(Function(c, i) If(i > 0 AndAlso Char.IsUpper(c), ChrW(32) + c, c)))
The same, not considering the position of the first uppercase char:
Dim result = String.Concat(input.Select(Function(c) If(Char.IsUpper(c), ChrW(32) + c, c)))
▶ With an aggregation function that uses a StringBuilder as accumulator (still considering the position of the first uppercase char).
When processing strings, a StringBuilder used as storage can make the code more efficient (creates way less garbage) and more performant.
See, e.g., here: How come for loops in C# are so slow when concatenating strings?
➨ Note that I'm adding an Array of chars to the StringBuilder:
Dim result = input.Aggregate(New StringBuilder(),
Function(sb, c) sb.Append(If(sb.Length > 0 AndAlso Char.IsUpper(c), {ChrW(32), c}, {c})))
➨ result is a StringBuilder object: extract the string with result.ToString().
Or, as before, without considering the position:
Dim result = input.Aggregate(New StringBuilder(),
Function(sb, c) sb.Append(If(Char.IsUpper(c), {ChrW(32), c}, {c})))
▶ The two example above are somewhat equivalent to a simple loop that iterates all chars in the string and either creates a new string or uses a StringBuilder as storage:
Dim sb As New StringBuilder()
For Each c As Char In input
sb.Append(If(sb.Length > 0 AndAlso Char.IsUpper(c), {ChrW(32), c}, {c}))
Next
Change the code as described before if you want to add a space to the first uppercase Char without considering its position.
Yet another option is a language extension method.
Imports System.Text.RegularExpressions
Module Module1
Sub Main()
Demo()
Console.ReadLine()
End Sub
Private Sub Demo()
Dim data = New List(Of String) From
{
"ThisIsASentence",
"TheQuickBrownFox",
"ApplesOrangesGrapes"}
data.ForEach(Sub(item) Console.WriteLine($"{item,-25}[{item.SplitCamelCase}]"))
End Sub
End Module
Public Module StringExtensions
<Runtime.CompilerServices.Extension>
Public Function SplitCamelCase(sender As String) As String
Return Regex.Replace(Regex.Replace(sender,
"(\P{Ll})(\P{Ll}\p{Ll})", "$1 $2"),
"(\p{Ll})(\P{Ll})",
"$1 $2")
End Function
End Module
You can use a regular expression:
Dim input = "TheQuickBrownFox"
Dim withSpaces = Regex.Replace(a, "(?<!^)([A-Z])", " $1")
The regex finds any uppercase A-Z that are not preceded by the start of the string and captures it into a group. The replacement takes the group content and prefixes a space
If you don't want to use the negative lookbehind, you can trim the result:
Dim withSpaces = Regex.Replace(a, "([A-Z])", " $1").TrimStart()
Or don't trim if you don't care that the string starts with a space
To expand on your code:
Dim input As String = "TheQuickBrownFox"
Dim outputSB as new StringBuilder
For i As Integer = 0 To input.Length - 1
Dim c As Char = input(i)
If Char.IsUpper(c) Then
outputSB.Append(" ")
'MsgBox(c)
End If
outputSB.Append(c)
Next
Console.Writeline(outputSB.ToString())

Comparing two strings with wildcard conditions

Working on a VBA macro that compares string values, and have hit a wall at a point.
Here is some context on what I'm trying to accomplish:
Compare two strings, If String 2 is CONTAINED anywhere in String 1, I return a match. For the most part, I've used the builtin "instr" function in instances where the String 2 is contained in String 1 without any wildcards involved.
The trouble I'm having is that I must treat spaces or " " in String 2 as a wildcard.
Ex:
String 1 = Red Green Blue
String 2 = Red Blue
This should still return a valid match, since the " " in String 2 is being treated as a wildcard, and any number of characters can be between "Red" and "Blue"
What I did was use the "split" function with " " as a delimiter to split String 2 in instances where a space(" ") is involved, and run an instr function on the resulting array to check if each element of the array is contained in String 1. In the example above:
String 2 would be split into a String array(let's call with splitString) with the following elements:
splitString = (Red, Blue)
Using the logic above:
splitString(0) is contained in String 1
splitString(1) is contained in String 1
Therefore, String 2 is contained in String 1, and a match is returned. The match condition I am using is utilizing the UBounds value of splitString (details in the code snippet below)
The issue I am having is that I need to only return a match where the initial string order of String 2 is maintained. Ex:
If:
String 1 = Red Green Blue
String 2 = Blue Red
This is not a valid match since even though when we split String 2, we find the resulting array elements are "contained" in String 1, the order of String 2 is not being respected.
Here is a rough draft of the logic I've coded:
splitString = Split(String2," ")
x = -1
For y = LBound(splitString) To UBound(splitString)
splitStringCompare = InStr(1, String1, splitString(y), vbTextCompare)
If splitStringCompare > 0 Then
x = x + 1
If x = UBound(splitString) Then
"Match"
Else
"No Match"
End If
Next y
Any help or nudge in the right direction would be much appreciated. Thanks!!
You can use Regular Expressions object to test this and verify match. For demonstration purpose, I have created a UDF as below.
Public Function MatchWildCard(strMatchWith As String, strMatchString As String) As Boolean
strMatchString = Replace(Trim(strMatchString), " ", ".+")
With CreateObject("VBScript.RegExp")
.Global = True
.MultiLine = False
.IgnoreCase = True '\\ Change to False if match is case sensitive
.Pattern = strMatchString
If .Test(strMatchWith) Then
MatchWildCard = True
Else
MatchWildCard = False
End If
End With
End Function
It can then be used in Excel sheet like below snapshot =MatchWildCard(A1,B1):
Note: I am a basic user of RegExp so there may be a better manner of handling this so you should test this on large sample to validate.

Excel formula: If cell contains substring "this" AND does not contain substring "that"

I'm trying to write a function in which a column contains one substring and does not contain another substring.
In the example bellow I would like my function to return 1 if my row contains "some project" AND DOES NOT CONTAIN "overhead".
row| example strings | desired return value
0 |some project,other project | 1
1 |some project | 1
2 |overhead | 0
3 |some project, overhead | 0
4 |some project, other, boo | 1
I was trying to formulate it first with exact strings such as:
=IF(AND((E3="some project"),NOT(E3="overhead")),1,0)
But this only gives correct results for row 1 and 2 because it only does exact mach for the string instead of matching on the substring.
What you need is some kind of Substring function. I think FIND might work. Check out this page: https://exceljet.net/excel-functions/excel-find-function
Your function would be like:
=IF(AND(ISERROR(FIND("some project", E3))=FALSE,ISERROR(FIND("overhead",E3))),1,0)
EDIT: Above function works after testing
Tricky part here is that FIND returns the starting position of the string, and if it fails it returns #VALUE, which I believe you can catch with the ISERROR() function. This is in no way a beautiful solution. I would try to utilize the code behind and write this is VBA, as I am certain there is a proper substring function in VBA.
If you can insert a little VBA code, then you can use a custom function like so:
=StrContains(E3, "some project", "overhead")
And this will return True if the value in E3 contains both of those substrings. This function relies mainly on VBA's Instr function, which
Function code:
Public Function StrContains(ByRef cl As Excel.Range, ParamArray strings() As Variant)
'Function returns TRUE if the range contains ALL of the passed substring items
' uses ParamArray to allow varying number of substring items
' Ex:
' =StrContains(A1, "something", "else", "foo")
'
Dim val$
Dim s
Dim i As Integer
Dim ret As Boolean
Dim length As Integer
length = UBound(strings) + 1
val = cl.Value2
For Each s In strings
If InStr(1,val, s) <> 0 Then
i = i + 1
End If
Next
ret = (i = length)
StrContains = ret
End Function
You could modify this relatively easily to be case-insensitive, or to accept partial matches optionally, etc. Here is what it looks like extended for both of those concepts:
=StrContains(E3, False, True, "some project", "overhead")
Function Code:
Public Function StrContains(ByRef cl As Excel.Range, MatchCase As Boolean, MatchAll as Boolean, ParamArray strings() As Variant)
'MatchAll is matching switch, use True to require ALL matching items, or False to allow for fewer.
'MatchCase is the Case-sensitive switch, use False to ignore case.
' uses ParamArray to allow varying number of substring items
' Ex:
' =StrContains(A1, "something", "else", "foo")
'
Dim val$
Dim s
Dim i As Integer
Dim ret As Boolean
Dim length As Integer
length = UBound(strings) + 1
val = cl.Value2
If Not MatchCase Then
val = LCase(val)
For i = lBound(strings) to UBound(strings)
strings(i) = lcase(strings(i))
Next
Next
For Each s In strings
If InStr(val, s) <> 0 Then
i = i + 1
End If
Next
ret = (i = IIF(MatchAll, length, 1))
StrContains = ret
End Function
You can actually use the SEARCH function, like this:
=IF(ISNUMBER(SEARCH("some project",B2)),NOT(ISNUMBER(SEARCH("overhead",B2)))*1,0)
Considerations:
SEARCH function: returns either a number or error (that's why I used ISNUMBER, you could actually have used ISERROR too). This function is case insensitive. For case sensitiveness you might just use FIND, in the previous formula woud be =IF(ISNUMBER(FIND("some project",B2)),NOT(ISNUMBER(FIND("overhead",B2)))*1,0)
ISNUMBER function: returns either FALSE or TRUE. I converted the result to 1 or 0 simply by multiplying TRUE or FALSE by 1.
Hope helps

Check an array for non-numeric characters

I am trying to create a function that will check an array for non-numeric characters. I'm sure there is a way with existing functions, but I was hoping to make a clean function.
This is what I have:
Public Function ContainsAllNumbers(Text() As Variant) As Boolean
For Each element In Text
If Not IsNumeric(element) Then
ContainsAllNumbers = False
End If
Next
End Function
The arguments I want it to take would be something like 11013688 or K03778 or 9005110-4400. I need to know if these strings contain something that is not a number.
Here is a (debugged) function which takes a string input and returns True if and only if all of the characters in the string are digits. This is (perhaps) what you are trying to do:
Function AllDigits(s As String) As Boolean
Dim i As Long
For i = 1 To Len(s)
If Not IsNumeric(Mid(s, i, 1)) Then
AllDigits = False
Exit Function
End If
Next i
AllDigits = True
End Function
I assume you want a function that takes an array of strings and checks them for nun-numeric values. Then your question would be, why your function always returns False.
The default value of a Boolean is false so you need to set ContainsAllNumbers = True at the beginning of the function.
I also recommend using Option Explicit so you don't forget to Dim your variables.
Convert the characters to their ascii code and check each of them. You can Look up an ascii table to find out the specific values for certain characters.
As an example I just copied this from one of my macros. It checks for non-alphanumeric values in the input string str:
invalidCharacter = false
For pos = 1 To Len(str)
Select Case Asc(Mid(str, pos, 1)) 'ascii value of character at str(pos)
Case 48 To 57, 65 To 90, 97 To 122 '0-9,a-z,A-Z
'nothing
Case Else
invalidCharacter = True
End Select
Next pos
If invalidCharacter Then
MsgBox "only numbers or letters may be used"
End If

Phone number format

I have a table field 'Phone number', the data in table is imported through a excel file link in database. The data type of the field is text since we are not sure how user enters his phone number(sometime with country code and sometime without country code).
I want to format the 'phone number' field once the table is updated everytime or data is imported into table. Format [countrycode]-[localcode]-[phone num].
I am not sure how to go about it, whether to create an update query or VBA code to update this field. Will appriciate any help in this regards.
It is generally recommended that in database fields, the phone number is maintained in numerical format only (meaning no parenthesis, dashes, or whatnot) because it provides more stability for the data and allows for better/easier future formatting when outputting. The most recommended method is to take the number given to you and strip it of all non-numeric characters and then store that value.
If you are working with an excel sheet containing this information before it is put into the database, then you can simply format the column that contains the phone numbers to convert everything into a single numerical value so 800-555-1212 or (888) 222-1515 would just become 8005551212 and 8882221515. This can be done using the existing cell formatting option built into Excel or if you want it done on the fly a simple VBA code that triggers when the field has a value would do the trick too.
EDIT #1 (super simple function)
Public Function numOnly(sToClean As String) As String
Const NUM_CHARS = "0123456789"
Dim lChar As Long
Dim sResult As String
For lChar = 1 To Len(sToClean)
If InStr(1, NUM_CHARS, Mid$(sToClean, lChar, 1)) > 0 Then
'Found a numeric character
sResult = sResult + Mid$(sToClean, lChar, 1)
End If
Next
'Return the result
numOnly = sResult
End Function
EDIT #2 (more feature advanced version)
Option Explicit
Public Function stripChars(CheckStr As String, Optional KillNums As Boolean = False, Optional AllowedChars As String, Optional NotAllowed As String)
' CheckStr = the string being evaluated
' KillNums [True/False] = remove numbers/remove non-numeric
' AllowedChars = what to allow even if you are removing non-numeric (aka KillNums=False) [ex. "$,."] or removing numbers (aka KillNums=True) [ex. "6,9"]
' NotAllowed = override characters never allowed and processed before any other option (meaning if you have it in both allow/not allow - not allow takes precedence
' NOTE: AllowedChars and NotAllowed arguments are *not* case-sensitive
Dim Counter As Long
Dim TestChar As String
Dim TestAsc As Long
' Loop through characters
For Counter = 1 To Len(CheckStr)
' Get current character and its ANSI number
TestChar = Mid(CheckStr, Counter, 1)
TestAsc = Asc(TestChar)
' Test first to see if current character is never allowed
If InStr(1, NotAllowed, TestChar, vbTextCompare) > 0 Then
' do nothing
' If current character is in AllowedChars, keep it
ElseIf InStr(1, AllowedChars, TestChar, vbTextCompare) > 0 Then
stripChars = stripChars & TestChar
' If KillNums=True, test for not being in numeric range for ANSI
ElseIf KillNums Then 'only allow non-numbers
If TestAsc < 48 Or TestAsc > 57 Then
stripChars = stripChars & TestChar
End If
' If KillNums=False, test for being in numeric ANSI range
Else 'only allow numbers
If TestAsc >= 48 And TestAsc <= 57 Then
stripChars = stripChars & TestChar
End If
End If
Next
End Function
You can drop either of these in your Excel's module (Alt+F11) or in your Access forms or what not, good luck.

Resources