I'm currently creating a program that will take user input.
If the user input contains _, then a variable substring will then equal the first 4 characters (0,4) of that input.
From there, a loop is run that loops through an array, and within that loop is an If statement that determines if the array contains the substring. And if so, the position of the array element that contains the substring is then equal to the same position of a different element array. And if any element from that array doesn't contain the substring, a MsgBox displays saying error.
Currently, if the user inputs text that in fact is a substring of that input is contained within the array, it is still prompting the error message, as well as displaying the correct outcome. How would I correctly set this up to where if the substring is not found within the array, the MsgBox will prompt the error, and if it is, only the correct outcome will be executed. Here's what I currently have:
And yes I know that both arrays don't contain the same amount of elements, I'm just testing the first three values.
Dim i As Integer
Dim subString As String
Dim IdValues = New String() {"ADC_123", "AAA_123", "AAB_123", "EFGH_Company", "ABB_456", "ABC_456"}
Dim ValueValues = New String() {"Happy", "Sad", "Mad", "Excited", "Joyful"}
Dim charText As Char
charText = "_"
If txtDataEntry.Text.Contains(charText) Then ' if statement to determine if text contains a "_"
subString = txtDataEntry.Text.Substring(0, 4) 'sets variable subString to a substring of text data
For i = 0 To IdValues.Length - 1 'looping through array
If IdValues(i).Contains(subString) And txtDataEntry.Text.Contains(IdValues(i)) Then
MsgBox("Success, the position is at position " & i)
IdValues(i) = ValueValues(i) 'new array position now equals the IdValue array where the substring is found
lblValueResult.Text = IdValues(i) 'prints outcome to label
Else
MsgBox("Error")
End If
Next i
Else
MsgBox("Sorry, no value was found.")
End If
So if the user enters AAA_123 it will create a substring AAA_ and determine if the IdValues array contains that substring. It is prompting the correct execution, but it is also prompting the Error message. How should I correctly set this up.
Any help is appreciated!
Using a Boolean for these types of iteration process is always better than playing around with if else .Please try the below answer
Dim isValueFound As Boolean = False
Dim i As Integer
Dim subString As String
Dim IdValues = New String() {"ADC_123", "AAA_123", "AAB_123", "EFGH_Company", "ABB_456", "ABC_456"}
Dim ValueValues = New String() {"Happy", "Sad", "Mad", "Excited", "Joyful"}
Dim charText As Char
charText = "_"
If txtDataEntry.Text.Contains(charText) Then ' if statement to determine if text contains a "_"
subString = txtDataEntry.Text.Substring(0, 4) 'sets variable subString to a substring of text data
For i = 0 To IdValues.Length - 1 'looping through array
If IdValues(i).Contains(subString) And txtDataEntry.Text.Contains(IdValues(i)) Then
MsgBox("Success, the position is at position " & i)
IdValues(i) = ValueValues(i) 'new array position now equals the IdValue array where the substring is found
lblValueResult.Text = IdValues(i) 'prints outcome to label
isValueFound = True
Exit For
End If
Next i
If isValueFound = False Then
MsgBox("Error : Not Found")
End If
Else
MsgBox("Sorry, no value was found.")
End If
Related
I am hoping to find help with this current VBA problem. I have looked throughout Stack Overflow and other Google searches, but can't seem to find what I'm looking for.
Essentially, I have a user pasted value on my page which I am delimiting on a comma, and then storing that into an array. What I am aiming to do is then loop through that array and eliminate any extra spaces, and then also delete any values that AREN'T a number.
Copy user values
Store into an array
Erase whitespace
So far, I have not been able to:
Copy items that ARE a number to new array
Currently, my code looks like:
Sub grabText()
' This macro was written as a test macro to grab and filter data entered in a textbox
Application.ScreenUpdating = False
Dim enteredValue As String ' Value taken from page
Dim vals() As String ' Array once it is split
Dim goodvals() As String 'Formatted array
Dim i As Integer 'Index
enteredValue = ActiveSheet.myTxt.Text
' MsgBox enteredValue
vals() = Split(enteredValue, ",")
lastitem = UBound(vals)
' MsgBox lastitem
'Formats array
For i = LBound(vals) To UBound(vals)
i = TRIM(vals(i))
'
' If (ISNUMBER(vals(i)) == TRUE) Then
' enter i into goodvals()
'
Next i
Application.ScreenUpdating = True
Any help or advice would be greatly appreciated. I was thinking about ways to do this in other languages (Java, Python) and I was thinking about Linked-Lists.
Thanks in advance!
Some issues:
Don't assign the result of Split to vals(), but to vals
Don't re-use the variable i for the result of the Trim. It is better to use a separate variable for that, which you can then type as a String
You can capture the desired result if you
First reserve enough room for your target array: it can never be longer than the Split result, so use that as the initial size
Use a separate index variable for referencing the target array index, and only increment it when you have stored a number in it
Finally reduce the size of the target array to the size that was actually used
Code:
Dim enteredValue As String ' Value taken from page
Dim vals() As String ' Array once it is split
Dim goodvals() As String 'Formatted array
Dim i As Long 'Index in vals
Dim j As Long 'Index in goodvals
Dim s As String 'Individual string
enteredValue = ActiveSheet.myTxt.Text
vals = Split(enteredValue, ",")
' Reserve as many entries in the target array
ReDim goodvals(UBound(vals))
j = LBound(goodvals)
For i = LBound(vals) To UBound(vals)
s = Trim(vals(i))
If IsNumeric(s) Then
goodvals(j) = CDbl(s)
MsgBox goodvals(j)
j = j + 1
End If
Next
' Shorten the array size to the part that is used
If j Then
ReDim Preserve goodvals(j - 1)
Else ' There were no numericals at all, so erase the array:
Erase goodvals
End If
I am trying to create a deciphering program which takes the entire English alphabet and shifts the letters' positioning to the left at one increment at a time. I have created a character array for this and I have got the shifting part to work. So, the index of each character in the array changes each time a shift is made. I also created an identical character array which does not shift so it has something to compare to.
Once the shift is made, I have textbox1 output into textbox2 which replaces the letters to their now corresponding letters based on the index of the first character array. For instance, "ABC" is now "DEF". The problem I am having is upon replacing the characters, it will replace them again because their state was changed previously. For example, I changed "A" to "B". Then I move on to changing "B" to "C". But since the "A" was changed to a "B", it is changed again to a "C". I realize doing a For Each Loop caused this to happen so I took it out of a loop and it still does it. I even tried putting a break in the code such as GOTO but that just stops the loop after changing the first letter.
Here is my code:
Private Sub cryptshift()
'SHIFTING ALL CHARACTERS IN ARRAY ONE SPACE TO THE LEFT
Dim temporaryStorageA As [String] = charArray(0)
Dim temporaryStorageB As [String]() = New [String](charArray.Length - 1) {}
For i As Integer = 1 To charArray.Length - 1
temporaryStorageB(i - 1) = charArray(i)
charArray(i - 1) = temporaryStorageB(i - 1)
Next
charArray(charArray.Length - 1) = temporaryStorageA
'CLEARING LABEL54 AND REALIGNING ARRAY TO LABEL53
Label54.Text = Nothing
For Each c In charArray
Label54.Text = Label54.Text & c & "-"
Next
'DECIPHERING
Dim mess As String = TextBox1.Text
Dim result As String = ""
For i As Integer = 0 To mess.Length - 1
Dim c As Char = mess(i)
Dim itemindex As Integer = Array.IndexOf(charArray2, c)
'**This IF Statement allows letters to be deciphered but also allows other characters such as punctuation, numbers and spaces to go through without any altering.**
If charArray2.Contains(c) Then
result &= charArray(itemindex)
Else
result &= c
End If
Next
TextBox2.Text = result
End Sub
Your problem is the .Replace. You should change only the current character. Here, I'm creating a new string with the result.
Dim mess As String = TextBox1.Text
Dim result As String = ""
For i As Integer = 0 To mess.length-1
Dim c As Char = mess(I)
Dim itemindex As Integer = Array.IndexOf(charArray2, c)
result &= charArray(itemindex)
Next
You could then use a string building.
How do I use an Excel Macro to determine true/false whether ALL of the words of a substring are included, in any order, in a mainstring? For example, I want to check whether the words in this substring "ford F150" are included in the mainstring "like new f150 ford black", which should return true.
I tried the code examples above, but they didn't work.
I'm guessing the way to do this is to split the substring into an array and then check whether each element of the array is in the mainstring. If ALL of the elements of the substring are in the mainstring then true.
I'm using VBA 7.1. Right now my macro runs, but it always returns TRUE no matter what text I search. Maybe it's an issue with InStr comparing method? Maybe it's an issue storing strings elements inside an array? Here's my macro:
Sub Macro 1()
Dim MainString As String
Dim SubString As String
Dim SubStringArray() As String
Dim bFound As Boolean
MainString = Cells(1, 1).Text
SubString = Cells(2, 1).Text
SubStringArray() = Split(SubString, " ")
bFound = False
For Each element In SubStringArray
If InStr(MainString, element) <> 0 Then
bFound = True
Exit For
End If
Next
Cells(1, 7) = bFound
End Sub
I also want to make sure I do not get partial matches such as "ford" should not be found in "fording". I only want to check on complete words.
Assuming you are saying a non-partial match is anything where there is a space on both sides of the searched text (i.e. you don't want to say that "ford" should match with " ford.") then the following should work:
'Macro names cannot contain spaces
'Sub Macro 1()
Sub Macro1()
Dim MainString As String
Dim SubString As String
Dim SubStringArray() As String
Dim bFound As Boolean
MainString = UCase(Cells(1, 1).Text) ' use a consistent case so that "F150"
SubString = UCase(Cells(2, 1).Text) ' will match "f150"
SubStringArray() = Split(SubString, " ")
bFound = True ' Start by assuming that everything will match
For Each element In SubStringArray
If InStr(" " & MainString & " ", " " & element & " ") = 0 Then
'Exit if we have found something that doesn't match
bFound = False
Exit For
End If
Next
Cells(1, 7) = bFound
End Sub
Short disclaimer: This is my very first question, so please be understanding.
I'm trying to code a function in Excel VBA that takes a binary number (formatted as a string) that counts the spaces, the 0s, and outputs the consecutive amount of 0s (and adds one to it) until the next "1" in that string appears, with "," in between. At the very end of the string, if there's the a "1", the output should look like: "..., 1". I'll try to make a little easier to understand with an example:
Strings of length twelve:
101011010101 --> 2, 2, 1, 2, 2, 2, 1
110000101101 --> 1, 5, 2, 1, 2, 1
100010001000 --> 4, 4, 4
So far I've managed to make a one-dimensional boolean array that takes the string and splits it into parts of length 1, so to say a "binary array". But I couldn't test it, since I only have half of the function.
Function ABSTAND(str As String, size As Integer) As String
Dim i As Integer
Dim arrays(size) As Boolean
For i = 1 To Len(str)
If Mid(str, i, 1) = "1" Then
arrays(i) = True
Else
arrays(i) = False
End If
'Maybe all of this works in a loop?
'Count consecutive 0s, add one
'Output the value with ", " (Concatenate numbers with strings, or make the number a string)
'Count consecutive 0s again
'and so on...
'Add conditions for the last value: Don't add a ", " and check if a one is the last character
End Function
I know, it looks like I have already figured out the problem and only need to implement it, but I'm new to VBA and don't know that well how it works and how to fix syntax and other problems.
Also, I would like to have a generalized form of my problem, that works with every string length, if that's possible.
Unfortunately, VBA isn't the best language for dealing with arrays. I've written the function as described but it sounds like, from your description, you might want to remove the check for If Len(arrZeroes(i)) > 0 Then etc. because it looks like you want to return '1' values in those cases.
Have a play around with the 'Split' function to try get a better feel for it and how it relates to your problem.
Function ABSTAND(str As String) As String
Dim arrZeroes() As String
Dim arrResult() As String
Dim i As Integer
'Initialise arrResult dimensions
ReDim arrResult(1 To 1)
'Splits your binary number into an array with each element being zero or more 0's
'(if there are several 1's in a row or a 1 at the start or finish it returns 0-length element for that position)
arrZeroes = Split(str, "1")
'Loop through each element in this new array
For i = LBound(arrZeroes) To UBound(arrZeroes)
'Sets the top element of the result array to this length + 1 then increments the size (like appending to array)
arrResult(UBound(arrResult)) = Len(arrZeroes(i)) + 1
ReDim Preserve arrResult(1 To UBound(arrResult) + 1)
Next i
'The last step on the result array incremented its ubound which is still empty so we remove that
ReDim Preserve arrResult(1 To UBound(arrResult) - 1)
'then return the array joined!
ABSTAND = Join(arrResult, ", ")
End Function
Let me know if anything doesn't make sense!
Edit:
An array is basically like an indexed list of elements of a specified data type. The line Dim arrZeroes() as String is dimming a dynamic array of string elements. The benefit of using a dynamic array is that you can dynamically change the amount of elements in it using Redim. To get around the lack of an 'append' function, what you have to do is redim the array to make it one element bigger then set this new biggest element to your new value.
arrResult(UBound(arrResult)) = Len(arrZeroes(i)) + 1
ReDim Preserve arrResult(1 To UBound(arrResult) + 1)
That's what these lines are doing. What the Split function does is, given a string and a delimiter, cut the string into a load of slices at each occurrence of the delimiter and return the array. For example, Split("11101101", "0") returns {"111", "11", "1"}. Where there are more than one occurrence of the delimiter in sequence, or the delimiter appears at the beginning or end of the string, it outputs a zero-length element, such as Split("101101", "1") returns {, "0", , "0",}. What the function is doing is looking at the length of each of these slices (i.e. consecutive digits that are not the delimiter) and outputting them to a new array.
Remove the # in your code.
It is used for preprocessing directive, and you do not need it.
More about Preprocessing directives:
https://msdn.microsoft.com/VBA/Language-Reference-VBA/articles/ifthenelse-directive
In general, try the following code:
Option Explicit
Public Sub TestMe()
Debug.Print ABSTAND("101011010101", 12)
End Sub
Function ABSTAND(str As String, size As Long) As String
Dim i As Long
Dim arrays() As Variant
Dim strResult As String
ReDim arrays(size)
For i = 1 To Len(str)
If Mid(str, i, 1) = "1" Then
arrays(i) = True
Else
arrays(i) = False
End If
strResult = strResult & arrays(i)
Next i
ABSTAND = strResult
End Function
It would print something like TrueFalseTrueFalseTrueTrue... Then try to build up your solution further.
Just some points:
Pay attention how the Array is created.
Use Long instead of Integer.
You can shorten the ABSTAND function, to the following:
Function ABSTAND(str As String, size As Long) As String
Dim i As Long
Dim arrays() As Variant
Dim strResult As String
ReDim arrays(size)
For i = 1 To Len(str)
arrays(i) = Mid(str, i, 1) = "1"
strResult = strResult & arrays(i)
Next i
ABSTAND = strResult
End Function
I have a directory with .txt files in it. I am writing each file's line to an array and need to know if any lines in a file match any lines in another file.
Example:
If any item in Array1 = any item in Array2 then...
Code thus far:
For Each foundBaseFile As String In My.Computer.FileSystem.GetFiles _
(DataDir, _
FileIO.SearchOption.SearchTopLevelOnly, "*.vpk.txt")
Dim BaseTextArray = IO.File.ReadAllLines(foundBaseFile)
For Each foundCheckFile As String In My.Computer.FileSystem.GetFiles _
(DataDir, _
FileIO.SearchOption.SearchTopLevelOnly, "*.vpk.txt")
If Not foundBaseFile = foundCheckFile Then
Dim CheckTextArray = IO.File.ReadAllLines(foundCheckFile)
'If any item in CheckTextArray = any item in BaseTextArray then
' Do X
'End If
End If
Next
Next
Thanks!
This should do the trick.
If BaseTextArray.Any(Function(o) CheckTextArray.Contains(o)) Then
' Do X
Declare two array variable
dim arr1() as string
dim arr2() as string
Read values from .txt file line b line and add to each arrarlevel. You can also split lines by vbnewline
then use
Array.Indexof()
method to find whether values in first array string exist in other.
If indx >1 then
True
Else
False
end if