What is shortcut of checking string value like this.
If midtxt = "a" Then
midtxt = "apple"
ElseIf midtxt = "b" Then
midtxt = "ball"
ElseIf midtxt = "c" Then
midtxt = "cat"
.....
ElseIf midtxt = "z" Then
midtxt = "zebra"
End If
MsgBox midtxt
Is there any way I can do this using two arrays.
[a, b, c....z] and [apple, ball, cat.....zebra]
Edit
I need reproducible function for my task.
I think a for apple is not right example for me.
This is updated array for me.
[ap, bl, ca,... zr] [apple, ball, cat... zebra]
means the two letter code is derived from the corresponding string but it is not uniformly derived.
A dictionary may be worthwhile here, as long as the [a, b, ...z] set is unique.
In the VBA IDE, go to Tools, References, and select Windows Scripting Runtime.
Public gdctAnimals As Dictionary
Public Sub SetUpAnimalDictionary()
Set gdctAnimals = new Scripting.Dictionary
gdctAnimals.Add "a", "apple"
gdctAnimals.Add "b", "ball"
gdctAnimals.Add "c", "cat"
gdctAnimals.Add "z", "zebra"
End Sub
Public Sub YourProc(midtxt As String)
If gdctAnimals Is Nothing Then
SetUpAnimalDictionary
End If
If gdctAnimals.Exists(midtxt) Then
MsgBox gdctAnimals(midtxt)
Else
MsgBox "Item not found in dictionary", vbExclamation
End if
End Sub
Use the Select Case or Switch function
Function SwapString(strInput As String)
SwapString= Switch(strInput = "a", "Apple", strInput = "b", "Banana", strInput = "c", "Cherry")
End Function
In your case, if you can only have 26 combinations (a-z) the easiest way is to do this:
Public Function ReturnString(strIn As String) As String
Select Case strIn
Case "a"
ReturnString = "apple"
Case "b"
ReturnString = "ball"
Case "c"
ReturnString = "cat"
' .............
Case Else
ReturnString = "UNKNOWN"
End Select
End Function
and you call your fonction like this
MyLongString = ReturnString "a"
But there are many more possibililities that I won't detail because you have not detailed enough your question:
You can use 2 arrays or a 2D array
you can use an array of private types
you can use a dictionary as specified in another answer
No need for an external component or tedious population, you are looking for something based on an ordinal value; a=>z is the character code range 97=>122 so you can use a simple efficient array lookup by converting the character code to a value within the bounds of the array:
'//populate (once)
Dim map() As String: map = Split("apple,ball,cat,...,zebra", ",")
'//lookup
midtxt = "a"
midtxt = map(Asc(Left$(midtxt, 1)) - 97)
'=>apple
midtxt = "c"
midtxt = map(Asc(Left$(midtxt, 1)) - 97)
'=>cat
If needed check the value starts with a character first with if midtxt like "[a-z]*" then ...
Related
How do I make the following code input either "Jack" or "John" randomly in cell A1? Currently, the result is always "2":
Sub RandomNames ()
Dim UserNames(1 To 2) As String
UserNames(1) = "Jack"
UserNames(2) = "John"
Range("A1").Value = Application.WorksheetFunction.RandBetween(LBound(UserNames), UBound(UserNames))
End Sub
Try using randbetween on the array.
Range("A1").Value = UserNames(Application.RandBetween(LBound(UserNames), UBound(UserNames)))
so I am making a decryption software that allows the user to input some text and then they can swap out letters in the program. For example, there is a drop down box that allows you to swap all the "O"'s in a user input to "W". So in the input "Stack overflow" the output would be "Stack wverflww".
However, my problem is is that when the user chooses a second letter to change, that has already been swapped, it causes a problem. For example, after the first above example has occurred, if the user then wanted to then change all the "W"'s in their input to "A"'s the output would be "stack averflaa". However, what I'm looking for the code to do is give an output of "Stack wverflwa". So only the original "W"'s of the user input are changed to the letter "A".
I hope the above makes sense.
Someone suggested using a two dimensional array to reassign the letters new letters and I am able to do this, but I have no idea how to then put this into my code and get it working. Below is my code and thank you to anyone who can help me.
Dim chooseLetter, replaceLetter, words2
chooseLetter = selectLetterCombo.Text
replaceLetter = replaceLetterCombo.Text
words2 = UCase(textInputBox.Text)
Dim replaceList As New List(Of String)
For Each z In words2
If z = chooseLetter Then
replaceList.Add(replaceLetter)
Else
replaceList.Add(z)
End If
Next
letterReplaceBox.Text = ""
For Each f In replaceList
letterReplaceBox.Text = letterReplaceBox.Text & f
Next
note: selectLetterCombo.Text is the letter chosen by the user that they want to replace and replaceLetterCombo.Text is the letter chosen by the user that they want to swap the first chosen letter with. Also, textInputBox.text is the text the user has inputted.
Thank you!
You should be able to keep a list of the index of the character that changed and check that before making another change.
'List to keep track of changed character index
Dim replacedCharsList As New List(Of Integer)'member variable
Dim chooseLetter, replaceLetter, words2
chooseLetter = selectLetterCombo.Text
replaceLetter = replaceLetterCombo.Text
words2 = UCase(textInputBox.Text)
Dim replaceList As New List(Of String)
Dim i As Integer
For i = 1 To Len(words2)
'remove the for each and go with a straight for loop to keep track if the index
If Mid(words2, i, 1) = chooseLetter Then
'check to see if we have already replaced this character via the index position
If replacedCharsList.Contains(i) = False Then
'we have not changed this so add the replacement letter and update our index list
replaceList.Add(replaceLetter)
replacedCharsList.Add(i)
Else
'we have already changed this character so just add it as is
replaceList.Add(Mid(words2, i, 1))
End If
Else
replaceList.Add(Mid(words2, i, 1))
End If
Next
letterReplaceBox.Text = ""
For Each f In replaceList
letterReplaceBox.Text = letterReplaceBox.Text & f
Next
I have an answer, but you're really not going to like it:
Option Infer On
Option Strict On
Imports System.Text.RegularExpressions
Module Module1
Dim swaps As New Dictionary(Of Char, Char)
Function DoSwaps(originalText As String, swapLetters As Dictionary(Of Char, Char)) As String
Dim newText As String = ""
For Each c In originalText
If swapLetters.ContainsKey(c) Then
newText &= swapLetters(c)
Else
newText &= c
End If
Next
Return newText
End Function
Sub Main()
Console.Write("Enter the text to be altered: ")
Dim t = Console.ReadLine()
Dim exitNow = False
Do
Console.Write("Enter the letter to swap from and the letter to swap to, or a blank line to quit: ")
Dim s = Console.ReadLine()
If s.Trim().Length = 0 Then
exitNow = True
Else
Dim parts = Regex.Matches(s, "([A-Za-z])")
If parts.Count >= 2 Then
Dim letter1 = CChar(parts.Item(0).Value)
Dim letter2 = CChar(parts.Item(1).Value)
If swaps.ContainsKey(letter1) Then
swaps.Item(letter1) = letter2
Else
swaps.Add(letter1, letter2)
End If
Console.WriteLine(DoSwaps(t, swaps))
End If
End If
Loop Until exitNow
End Sub
End Module
... unless you'd like to learn about the Dictionary class to understand how it works. I used a simple regular expression to parse the user input, but if you're using dropdowns to select the letters then that would just be bonus learning if you explore it.
The essential feature is that you keep the original string (t in the above code) and apply the transformation (I named it DoSwaps) to that each time, not to the previously transformed string.
These two functions will do the job, although there is no allowance for punctuation, just spaces.
Private Function EncryptText(str As String) As String
Dim swapletters() As String = {"l", "s", "d", "f", "g", "h", "j", "k", "a", "q", "w", "e", "r", "t", "y", "u", "i", "o", "p", "z", "x", "c", "v", "b", "n", "m"}
Dim encryptedText As String = ""
For Each letter As Char In str
If letter = " "c Then
encryptedText = encryptedText & " "
Else
Dim charactercode As Integer = Asc(letter) - 97
encryptedText = encryptedText & swapletters(charactercode)
End If
Next
Return encryptedText
End Function
Private Function DecryptText(str As String) As String
Dim swapletters As New List(Of String) From {"l", "s", "d", "f", "g", "h", "j", "k", "a", "q", "w", "e", "r", "t", "y", "u", "i", "o", "p", "z", "x", "c", "v", "b", "n", "m"}
Dim decryptedText As String = ""
For Each letter As Char In str
If letter = " "c Then
decryptedText = decryptedText & " "
Else
Dim character As String = Chr(swapletters.IndexOf(letter) + 97)
decryptedText = decryptedText & character
End If
Next
Return decryptedText
End Function
To use them, declare a string to hold the return value of each function
Dim etext As String
etext = EncryptText("disambiguation is the root of all evil")
results in etext being "faplrsajxlzayt ap zkg oyyz yh lee gcae"
and
Dim dtext As String
dtext = DecryptText("faplrsajxlzayt ap zkg oyyz yh lee gcae")
results in "disambiguation is the root of all evil"
MY question would best be understood be the following example, my goal is to classify the following string into category if the string matches any one of the strings defined in those categories. For example,
dim test_str as string
test_str = "tomato"
If the test string tomato matches any one of the keywords (1) potato, (2) tomato and (3) spaghetti, then tomato will be classified as food.
I have a very inefficient way of doing this now, which involves using multiple strcomp, i.e.
if(strcomp(test_str, "potato", vbtextcompare) = 0 or _
strcomp(test_str, "tomato", vbtextcompare) =0 or _
strcomp(test_str, "spaghetti", vbtextcompare)=0 ) then
'label test str as "food"
However, if I have 10 keywords defined within "food", I would then need 10 strcomp statements, which would be tedious. Is there a better way to do this ?
I would simply store all the combinations in a string and check that the value is present with InStr:
Const food = "|potato|tomato|spaghetti|"
Dim test_str As String
test_str = "tomato"
If InStr(1, food, "|" & test_str & "|", vbTextCompare) Then
Debug.Print "food"
Else
Debug.Print "not food"
End If
Write a function that helps you
Function ArrayWordNotInText(textValue, arrayKeyword)
Dim i
ArrayWordNotInText = -1
For i = LBound(arrayKeyword) To UBound(arrayKeyword)
If Not StrComp(textValue, arrayKeyword(i), vbTextCompare) Then ArrayWordNotInText = i
Next i
End Function
If the return value = -1 ... no Match, >0 the index of the word
This is my first time posting; excuse my formatting. Have not been using VBA for too long but was able to piece this together.
Sub vinden4()
Dim EXCEPT() As String, a As Integer
EM = "no.replynoreply#ziggo.nl"
Exceptions = "no-Reply,noreply,nO.reply,"
EXCEPT = Split(Exceptions, ",")
For i = LBound(EXCEPT) To UBound(EXCEPT)
NOREPLY = InStr(1, EM, EXCEPT(i), vbTextCompare)
If NOREPLY > 0 Then
'CbEM.Value = True '~food~
EM = InputBox("NOREPLY E-MAILADRES", "Geef E-mailadres aan", EM)
'else
'CbEM.Value = False ~not food~
End If
Next i
MsgBox EM
End Sub
Hope this can help someone.
This one's really got me confused. I'm trying to do a visual basic console application that if the user enters 'A' or 'a' then the program should do 'x', but that's not working. The error I get is:
Conversion from string "a" to type 'Boolean' is not valid.
Here's my code:
Module Module1
Sub Main()
Dim Selection As String
Console.WriteLine("Please select your function:")
Console.WriteLine("* To convert binary to decimal, press A,")
Console.WriteLine("* Or to convert decimal to binary, press B")
Selection = Console.ReadLine
If Selection = "A" Or "a" Then
Console.WriteLine("This will be A")
ElseIf Selection = "B" Or "b" Then
Console.WriteLine("This will be B")
ElseIf Selection = Not "A" Or "a" Or "B" Or "b" Then
Console.WriteLine("Please try again")
Do Until Selection = "A" Or "a" Or "B" Or "b"
Loop
End If
End Sub
What should be the correct usage of the Or in this piece of code to make it function correctly?
Your If clauses should be like:
If Selection = "A" Or Selection = "a" Then
The clauses between the Or should each be boolean expressions, and "a" is simply a character, not a boolean expression.
I would suggest changing the string entered into upper case before the if statements. Also the last else if statement isn't needed and can be replaced with a single else.
Sub Main()
Dim Selection As String
Console.WriteLine("Please select your function:")
Console.WriteLine("* To convert binary to decimal, press A,")
Console.WriteLine("* Or to convert decimal to binary, press B")
Selection = Console.ReadLine.ToUpper() 'Not tested otherwise use the one below
'Selection=Selection.ToUpper()
If Selection = "A" Then
Console.WriteLine("This will be A")
ElseIf Selection = "B" Then
Console.WriteLine("This will be B")
Else
Do Until Selection = "A" Or Selection = "B"
'Loop Code goes here
Loop
End If
End Sub
Using Select Case is yet another alternative:
Sub Main()
Console.WriteLine("Please select your function:")
Console.WriteLine("* To convert binary to decimal, press A,")
Console.WriteLine("* Or to convert decimal to binary, press B")
Console.WriteLine("* To Quit, press Q")
Dim Selection As String = ValidateInput()
If Selection <> "Q" Then
'do something
End If
End Sub
Function ValidateInput() As String
Dim Selection As String
Selection = Console.ReadLine
Select Case Selection.ToUpper
Case "A"
Console.WriteLine("This will be A")
Case "B"
Console.WriteLine("This will be B")
Case "Q"
Return "Q"
Case Else
Console.WriteLine("Please try again")
ValidateInput()
End Select
Return Selection
End Function
Okay this one might be a little tougher. I'm using VB that looks like this:
string = Replace(string.ToLower, chr(63), "A")
But I also want chr(63) = "B" as well, like this:
string = Replace(string.ToLower, chr(63), "B")
My problem is that when chr(63) is at the end of a string I need it to be B, and when it's not the end I need it to be A. I suppose that I can use an if/then/else statement. Is there a way to do this?
Example:
XXXXXchr(63)XXXXX = A
but
XXXXXXXXXXchr(63) = B
Thanks!
pseudo:
if (string[string.Length] == chr(63))
{
string[string.Length] = B
}
string = Replace(string.ToLower, chr(63), "A")
string = Replace(string.ToLower, chr(63), "A", 1, Len(string) - 1)
If Right(string, 1) = chr(63) then
Mid$(string, Len(string), 1) = 'B'
End if
Update: in response to comment:
VB String Functions
VB String Array Functions - Split, Join, Filter (very useful)
I haven't used Visual Basic since version 6, but it should be something like this:
If Robert.EndsWith(chr(63)) Then
Robert = Left(Robert, Robert.Length - 1) + "B"
End If
Then do the usual replacement with A.
This ought to do it
Dim s As String
Dim char63 As String = Convert.ToChar(63).ToString
If s.EndsWith(char63) Then
s = s.Substring(0, s.Length - 1) & "B"
End If
s = s.Replace(char63, "A")