Lotusscript array randomize - lotus-notes

If it is the following variables, how to use MyVar to randomly select three out of four, the number may increase, and the number to be taken is also according to the needs
My Code
Dim MyVar() As Variant
Redim MyVar(2)
MyVar(0) = Name
MyVar(1) = NameType
AllQuestion = MyVar
Name
"Car"
"Dog"
"Man"
"Cow"
NameType
"One"
"Four"
"TWO"
"Five"

Related

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.

Selecting Characters In String

I can grab every 2 chars from sum2.text in order (102030) i get 10,20,30
but my issue is, selecting exactly those numbers 10,20,30 in order
my current code below outputs: msgbox(10) msgbox(20) msgbox(30) but wont select and replace those exact numbers in order one by one
My code:
For i = 0 To sum2.Text.Length - 1 Step 2 'grabs every 2 chars
Dim result = (sum2.Text.Substring(i, 2)) 'this holds the 2 chars
MsgBox(result) 'this shows the 2 chars
sum2.SelectionStart = i 'this starts the selection at i
sum2.SelectionLength = 2 'this sets the length of selection (i)
If sum2.SelectedText.Contains("10") Then
sum2.SelectedText = sum2.SelectedText.Replace("10", "a")
End If
If sum2.SelectedText.Contains("20") Then
sum2.SelectedText = sum2.SelectedText.Replace("20", "b")
End If
If sum2.SelectedText.Contains("30") Then
sum2.SelectedText = sum2.SelectedText.Replace("30", "c")
End If
my probolem is that it will show the numbers in sum2 one by one correctly, but it would select and replace at all or one by one. I believe the issue is with the selection length
OK, here's my attempt from what I'm understanding you are wanting to do. The problem is, you are trying to alter the string that the loop is using when you replace "10" with "a" so you need to create a variable to hold your newly built string.
Dim part As String = ""
Dim fixed As String = ""
For i = 0 To Sum2.SelectedText.Length - 1 Step 2
part = Sum2.SelectedText.Substring(i, 2)
Select Case part
Case "10"
part = part.Replace("10", "a")
Case "20"
part = part.Replace("20", "b")
Case "30"
part = part.Replace("30", "c")
End Select
fixed &= part
Next
Sum2.SelectedText = fixed
Of course, this is only to show the workings of moving through the string and changing it. You would need to replace your selected text with the newly formatted result (fixed in this case)
Result: ab3077328732
Also, just so you know, if this format was such that no 2 digits would interfere, you could simply do a
sub2.selectedtext.replace("10", "a").Replace("20", "b").Replace...
However if you had 2 digits like 11 next to 05 it would fail to give desired results because if would change 1105 to 1a5. Just something to think about.
Here's some code to get you started:
For i = 0 To sum2.SelectedText.Length - 1 Step 2
MessageBox.Show(sum2.SelectedText.Substring(i, 2))
Next

Can a logic test for an `if` statement be a variable in excel vba?

I have the following function:
Function get_equal_array_subset(column_label As String, _
loop_array() As Variant, _
values_array() As Variant)
' this function outputs an array of value from the values_array, based on a loop through the loop_array
' column_label is the first item in the array of the ouput array; i.e. the column lable of a new range
' loop_array is array being looped through and testing each value
' valus_array is the array from which values are taken with the test is met in the first array
' *** arrays have to be of equal lenght ***
Dim subset_array() As Variant
subset_array = Array(column_label)
Dim rows_dim As Long
Dim cols_dim As Integer
Dim agent_subset_counter As Long
agent_subset_counter = 0 ' counter to set the key for the new array
For rows_dim = 2 To UBound(loop_array, 1)
For cols_dim = 1 To UBound(loop_array, 2)
If loop_array(rows_dim, cols_dim) > 2 Then
agent_subset_counter = agent_subset_counter + 1 ' increase the subset counter by 1
ReDim Preserve subset_array(agent_subset_counter) ' resize the array account for the next id
subset_array(agent_subset_counter) = values_array(rows_dim, cols_dim) ' add the new id to the agent subset
End If
Next cols_dim
Next rows_dim
get_equal_array_subset = subset_array
End Function
Is there a way for me to make the If loop_array(rows_dim, cols_dim) > 2 Then a variable? Let's say I wanted the test to be > 3 or = 5 or non blank...etc.
I would go for the magic Application.Evaluate() method of the Application class. An example might be to define a series of tests into an array, let's say:
Dim myTests(4)
myTests(1) = "> 3"
myTests(2) = "= 5"
myTests(3) = "+3 < 5"
myTests(4) = "- 4 + sum(1,2) < 5"
Hence, using the simple statement:
If Application.Evaluate(loop_array(rows_dim, cols_dim) & myTests(j)) Then
Clearly, the variable j should be defined depending on the test you want to use and this kind of method would allow you to define several arrays of operators (one array for operators like +, - etc., another one for values like 3, 5 etc.)
NOTE If you don't know it yet, the Application.Evaluate() method will evaluate the expression and returning the result as Excel would do. It's basically using the same code that Excel uses to evaluate what you write in a cell:
Application.Evaluate("2+3") --> 5
Application.Evaluate("2 < 3") --> True
Application.Evaluate("IF(2=3,1,2)") --> 2
'etc.
If you wanted to make the "magic number" 2 into a variable, then you would use an array item in place of the 2.If, however, you wanted separate logic, then you use use a Select Case structure.

VBA Excel - Replacing exact word in a String Phrase

I have an array with some words that i want to replace with other words, in fact, i have some problem:
Eg:
Var1 -> wksArray
Var2 -> wksArrayBigger
string : Dim wksArray, wksArrayBigger as Variant
When i try to replace wksArray with "test1", it will cause:
var1 -> teste1
var2 -> test1Bigger
string : Dim teste1, teste1Bigger as Variant
How can i solve that?
Function FindAndReplace(VBProjToClean, varArray)
Dim i, b As Integer
Dim str, replace_str As String
Dim VBC As VBComponent
For Each VBC In VBProjToClean.VBComponents
i = 1
With VBC.CodeModule
Do Until i > .CountOfLines
If Not .ProcOfLine(i, vbext_pk_Proc) = "VBE_Remove_Comments" Then
str = .Lines(i, 1)
End If
For b = 1 To UBound(varArray)
If InStr(1, str, varArray(b), vbTextCompare) > 0 Then
replace_str = Replace(str, varArray(b), varArray(b) & "banana")
.ReplaceLine i, replace_str
str = .Lines(i, 1)
End If
Next b
i = i + 1
Loop
End With
Next
End Function
While not a proper fix to your problem, you could sort your search list and possibly add some intermediary replacements should there be conflicts you cant resolve.
arrReplaceBigger -> arIM01
arrReplace -> aR
arIM01 -> aRB '
If your just replacing variable names, you could create a function to replace Replace that would do a number of extra replacements, appending however many possibilities for the next character there are.
white-space, comma, period, left bracket, right bracket, new line, plus, ...., etc
Or instead of doing many extra replacements you could do the same thing using Regular Expressions as David suggests.
Write a function to find out if something is a valid character for a VBA variable
Then for each pear of strings,
Look for the occurences of the string to be replaced, verify that preceding and succeding positoins do not contain valid characters, and if so, replace the string.

Comparing Strings in VBA

I have a basic programming background and have been self sufficient for many years but this problem I can't seem to solve. I have a program in VBA and I need to compare two strings. I have tried using the following methods to compare my strings below but to no avail:
//Assume Cells(1, 1).Value = "Cat"
Dim A As String, B As String
A="Cat"
B=Cell(1, 1).Value
If A=B Then...
If A Like B Then...
If StrCmp(A=B, 1)=0 Then...
I've even tried inputting the Strings straight into the code to see if it would work:
If "Cat" = "Cat" Then...
If "Cat" Like "Cat" Then...
If StrCmp("Cat" = "Cat", 1) Then...
VBA for some reason does not recognize these strings as equals. When going through Debugger it shows that StrComp returns 1. Do my strings have different Char lengths? Thanks for any help.
Posting as answer because it doesn't fit in the comments:
I find it hard to believe that something like:
MsgBox "Cat" = "Cat"
Would not display True on your machine. Please verify.
However, I do observe that you are most certainly using StrComp function incorrectly.
The proper use is StrComp(string, anotherstring, [comparison type optional])
When you do StrComp(A=B, 1) you are essentially asking it to compare whether a boolean (A=B will either evaluate to True or False) is equivalent to the integer 1. It is not, nor will it ever be.
When I run the following code, all four message boxes confirm that each statement evaluates to True.
Sub CompareStrings()
Dim A As String, B As String
A = "Cat"
B = Cells(1, 1).Value
MsgBox A = B
MsgBox A Like B
MsgBox StrComp(A, B) = 0
MsgBox "Cat" = "Cat"
End Sub
Update from comments
I don't see anything odd happening if I use an array, just FYI. Example data used in the array:
Modified routine to use an array:
Sub CompareStrings()
Dim A As String, B() As Variant
A = "Cat"
B = Application.Transpose(Range("A1:A8").Value)
For i = 1 To 8
MsgBox A = B(i)
MsgBox A Like B(i)
MsgBox StrComp(A, B(i)) = 0
MsgBox "Cat" = B(i)
Next
End Sub
What I would check is how you're instantiating the array. Range arrays (as per my example) are base 1. If it assigned some other way, it is most likely base 0, so check to make sure that you're comparing the correct array index.

Resources