Pick random value from string array - vba

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)))

Related

Assign value to a range with a variable column refreence

The following code gives me a compile error:expected: separator or ).
Public Sub test1()
Dim first_column As String,a_tab as string
a_tab="Sheet1"
first_column = "A"
ThisWorkbook.Sheets(a_tab).Range(first_column&"10").value="hello"
End Sub
I know we can do it when the row reference is a variable, i.e.
Public Sub test1()
dim fist_row as integer, a_tab as string
a_tab="Sheet1"
first_row=10
ThisWorkbook.Sheets(a_tab).Range("A"&first_row).value="hello"
End Sub
Could someone help? Many thanks.
Get out of the habit of using a letter for the column designation.
Your first column is column 1:
Columns(1).Value = "Hello" will place "Hello" in every cell in column 1 - Range(A1:A1048576).
The second cell in column 1:
Cells(2, 1) = "Hello" will place "Hello" in row 2, column 1 - Range(A2).
A range of cells designated by a start and end cell:
Range(Cells(2, 1), Cells(4, 2)) = "Hello" will place "Hello" in every cell between row 2, column 1 and row 4, column 2 - Range("A2:B4")
The first, second, third & fourth columns:
Range(Cells(1,1),Cells(1,4)).EntireColumn - Range("A:D").
But, saying that the only thing that caused your code to fail was spacing. You'll notice with the row variable it keeps putting the spaces back in - doesn't seem to do that with the column variable:
ThisWorkbook.Sheets(a_tab).Range(first_column & "10").Value = "hello"
- add a space either side of the ampersand.
Edit:
Consider placing values in columns CB:CL using a loop. Using numbers you'd just write:
Sub Test()
Dim x As Long
For x = 80 To 90
Cells(1, x) = "Hello"
Next x
End Sub
Using letters you'd have to use something like:
Sub Test()
Dim col_Letter As String
col_Letter = "CB"
Do
Range(col_Letter & "10") = "Hello"
'Get the next column letter by finding the address, splitting it and extracting just the column letter.
col_Letter = Split(Range(col_Letter & "10").Offset(, 1).Address(True, False), "$")(0)
Loop While col_Letter <> "CL"
End Sub
Are you missing spaces when concatenating strings in your argument to Range? ThisWorkbook.Sheets(a_tab).Range(first_column & "10").value="hello" Works for me if I add the spaces.

If function giving me problems

My value keeps becoming false instead of the values i've added even when i enter Male. anyone has any idea?
If gender = "Male" Then
Sheet2.Range("A2").Value = "he" & Sheet2.Range("A3").Value = "him" & Sheet2.Range("A4").Value = "his"
Else
Sheet2.Range("A2").Value = "she" & Sheet2.Range("A3").Value = "her" & Sheet2.Range("A4").Value = "her"
End If
You can't assign a value two time in the same statement. Any = character after the first is treated as a logical operator (is equal to), not as an assignment.
So if you have:
a = b = c
VBA treats the statement as: Assign to A the results of "Is b equal to c".
It gets more complicated if you have three equal signs in a statement, but it won't be what you want in any rate.
Additionally, the & operator is for string concatenation. so
a = "top" & "hat"
will assign the string "tophat" to a.
You might want to use the : operator instead of &. That separates statements on a single line. So try this:
If gender = "Male" Then
Sheet2.Range("A2").Value = "he" : Sheet2.Range("A3").Value = "him" : Sheet2.Range("A4").Value = "his"
Else
Sheet2.Range("A2").Value = "she" : Sheet2.Range("A3").Value = "her" : Sheet2.Range("A4").Value = "her"
End If
However, I would urge you not to use : here. There's really no need, and I think it makes the code harder to read. I'd suggest:
If gender = "Male" Then
Sheet2.Range("A2").Value = "he"
Sheet2.Range("A3").Value = "him"
Sheet2.Range("A4").Value = "his"
Else
Sheet2.Range("A2").Value = "she"
Sheet2.Range("A3").Value = "her"
Sheet2.Range("A4").Value = "her"
End If
Rich Holton gave you the reason why your code didn't work
Here I propose you some different techniques
Option Explicit
Sub main()
Dim valsArray As Variant '<--| declare a Variant variable to hold an array
Dim gender As String
gender = "Male" '<--| gender initialization for testing purposes
If gender = "Male" Then
valsArray = Array("he", "him", "his") '<--| fill your Variant with values corresponding to the 'gende'r value
Else
valsArray = Array("she", "her", "her") '<--| fill your Variant with values corresponding to the 'gende'r value
End If
Sheet2.Range("A2:A4").Value = Application.Transpose(valsArray) '<--| write all values in one shot (you need 'Transpose()' to change the "horizontal" Variant array to a "vertical" one and fit the range you're fill values of
End Sub
you can also shorten it down even more by using IIf() function:
Option Explicit
Sub main()
Dim gender As String
gender = "Male" '<--| gender initialization for testing purposes
Sheet2.Range("A2:A4").Value = Application.Transpose(IIf(gender = "Male", Array("he", "him", "his"), Array("she", "her", "her")))
End Sub

How to search for specific words in column and return it to its same row but another cell?

I've returned a G3 and H3 value to M3 and N3 cell as result.
What I want is to find only 1 specific word from cell(J3) like "chocolate" and return it to Cell(M3)
Is there a way to write an Excel macro to find those specific words listed in Column(G) in Column(J) and if Column(J) contains those specific words the macro returns only the specific word to Column(M) to the same row it was found. (but another cell, like M3 on the screenshot)
Private Sub CommandButton1_Click()
Dim score1 As String, score2 As Integer, result1 As String, result2 As String
score1 = Range("G3").Value
score2 = Range("H3").Value
If score1 = "chocolate" Then
result1 = "chocolate"
result2 = "4"
Else
result1 = "" And result2 = ""
End If
Range("M3").Value = result1
Range("N3").Value = result2
End Sub
It's working with Range(Only One Cell).
But how can I search for the specific words listed in Columns("G3:G7") to be found in Column("J:J") and when it is found return the specific word to Column("M") to the same row it was found.
So I can press OK! CommandButton and if Column("J:J") contains any words in Column("G:G") the "found" exact word from Column("G:G") will be inserted to Column("M:M") to the same row where it was found.
I've tried with simple functions as:
=IF(ISNUMBER(SEARCH($G$3;"*"&A:A&"*"));"chocolate";IF(ISNUMBER(SEARCH($G$4;"*"&A:A&"*"));"muffin";IF(ISNUMBER(SEARCH($G$5;"*"&A:A&"*"));"lemon";IF(ISNUMBER(SEARCH($G$6;"*"&A:A&"*"));"monkey";IF(ISNUMBER(SEARCH($G$7;"*"&A:A&"*"));"baby")))))
and:
=IF(ISERROR(SEARCH(D3;"*"&A3&"*";A3));B3;"")
It's working as you can see below but macro would be easier.
edited after OP's clarifications
Option Explicit
Private Sub CommandButton1_Click()
Dim cell As Range
Dim words As Variant
Dim word As String, number As Long
words = Range("H3", Cells(Rows.Count, "G").End(xlUp)).value
For Each cell In Range("J3", Cells(Rows.Count, "J").End(xlUp)).SpecialCells(xlCellTypeConstants, xlTextValues)
If FindWord(cell.value, words, word, number) Then
cell.Offset(, 3).Resize(, 2).value = Array(word, number)
End If
Next
End Sub
Function FindWord(sentence As String, words As Variant, returnedWord As String, returnedNumber As Long) As Boolean
Dim iWord As Long
Dim word As String
For iWord = LBound(words, 1) To UBound(words, 1)
word = CStr(words(iWord, 1))
If InStr(sentence, word) Then
FindWord = True
returnedWord = word
returnedNumber = CLng(words(iWord, 2))
Exit Function
End If
Next
End Function

short way of cheeking multiple string in VBA

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 ...

Comparing character strings in separate cells in Excel spreadsheets?

I have a large Excel spreadsheet with alpha-numeric data. I want to be able to compare two cells in different row side by side and return the difference in another cell.
e.g. I have in cell B2, "tom, rick, mike, I" and in cell C2, "mike, rick". I need to
compare the cell C2 to cell B2 and return the difference in cell D2 which in this case would be the characters " tom, I". They are separated with "," and they can be in different order as you can see in the example.
Split each string into a list of items. Compare each item in the first list with the second list, adding those items that are not in the second list to a third. You might need to expand it to work with your list which contains spaces and commas.
Public Function ListDiff(names1 As String, names2 As String) As String
Dim list1() As String
Dim list2() As String
list1 = Split(names1, ",")
list2 = Split(names2, ",")
list3 = ""
For i = LBound(list1) To UBound(list1)
If Not existsInList(list2, list1(i)) Then
list3 = list3 & "," & list1(i)
End If
Next i
'remove leading comma
ListDiff = Right(list3, Len(list3) - 1)
End Function
Public Function existsInList(list() As String, item As String) As Boolean
exists = False
i = LBound(list)
bFound = False
While i <= UBound(list) And Not bFound
If list(i) = item Then
bFound = True
End If
i = i + 1
Wend
existsInList = bFound
End Function