Me again everyone. I am trying to pull various strings and place a string in a separate field. I cannot seem to get my code to work and I am hoping someone can shine some light in my flawed attempts. Thank you very much.
I have column "B" which includes multiple names and is in the following format:
B C D
Other Team teamOne teamTwo
/jdoe/smithjr/
/someguy/testuser/
/obiwan/luke/darth
/vader/
/hp/dell/lenova/mint/
I only need to take the first two names and place one name in one field and one name in another field.
Expected results
B C D
Other Team teamOne teamTwo
/jdoe/smithjr/ jdoe smithjr
/someguy/testuser/ someguy testuser
/obiwan/luke/darth obiwan luke
/vader/ vader
/hp/dell/lenova/mint/ hp dell
The code I have come up with so far is below and does not work. I receive errors that there is no data to replace.
For Q = 2 To 10
If UCase(Cells(Q, "B").Value) Like "*Other Team*" Then
Name = Cells(Q, "B").Value
startingPosition = InStr(Name, "/")
Firstname = Left(Name, (startingPosition) - 1)
secondName = Right(Name, startingPosition - 2)
Cells(Q, "C").Value = Firstname
Cells(Q, "D").Value = secondName
End If
Next Q
I am pretty new to VBA (on 3rd day) and cannot seem to figure out how to parse this data. Perhaps someone can explain what I am doing wrong and assist me? Thank you.
Since you have a delimited string, I'd personally use the Split function. Note also that your If UCase(Cells(Q, "B").Value) Like "*Other Team*" Then test fails on every input in your sample data - it is only true for the column header that you skip, assuming that you change the test to uppercase like you do the input. If you're trying to determine if you're on the correct worksheet, it needs to go outside of the loop.
Something like this:
If UCase$(Cells(1, "B").Value) Like "*OTHER TEAM*" Then
Dim tokens() As String
For Q = 2 To 10
Name = Cells(Q, "B").Value
tokens = Split(Name, "/")
If UBound(tokens) > 0 Then Cells(Q, "C").Value = tokens(1)
If UBound(tokens) > 1 Then Cells(Q, "D").Value = tokens(2)
Next Q
End If
just to put in a "formula" approach
Sub main()
If UCase$(Cells(1, "B").Value) Like "*OTHER TEAM*" Then
Range("c2:c10").FormulaR1C1 = "=MID(RC2,2,SEARCH(""/"",RC2,2)-2)"
Range("d2:d10").FormulaR1C1 = "=IF(ISNUMBER(SEARCH(""/"",RC2,SEARCH(""/"",RC2,2)+1)),MID(RC2,SEARCH(""/"",RC2,2)+1,SEARCH(""/"",RC2,SEARCH(""/"",RC2,2)+1)-SEARCH(""/"",RC2,2)-1),"""")"
End If
a more "clear" format of which could be
Dim str1 As String, str2 As String, formula1 As String, formula2 As String
str1 = "SEARCH(""/"",RC2,2)"
str2 = "SEARCH(""/"",RC2," & str1 & "+1)"
formula1 = "=MID(RC2,2," & str1 & "-2)"
formula2 = "=IF(ISNUMBER(" & str2 & "),MID(RC2," & str1 & "+1," & str2 & "-" & str1 & "-1),"""")"
If UCase$(Cells(1, "B").Value) Like "*OTHER TEAM*" Then
Range("c2:c10").FormulaR1C1 = formula1
Range("d2:d10").FormulaR1C1 = formula2
End If
Related
I am trying to make a full function report file which connects to old version access data base. I need to build a Userform where user can enter deal (order) number just like we can add pages in print dialog box.
So far I have found below question which has given me partial answer:
How to Parsing Full String and split into several String in Excel VBA?
I can use Split(string) method to get various deal numbers when separated by ",".
However, I also need From to TO deal number option as well.
so, if user enters on String1 = "10001 - 10050, 20111 , 20115"
then I need output as
Deal_Line.Deal_Number >= 10001 and Deal_Line.Deal_Number <= 10050
and Deal_Line.Deal_Number = 20111 and Deal_Line.Deal_Number = 20115.
I can refine SQL String for my requirement, I would like to know if there is a way to use two deliminator.
Expanding on #user3598756 answer, (which does exactly what you asked for) and interpreting your requirements I come up with the following:
Function ProcessString(strng1 As String, fieldname As String) As String
Dim sqlStrng As String
Dim strng As Variant, limits As Variant
For Each strng In Split(strng1, ",")
limits = Split(strng, "-")
If UBound(limits) = 0 Then
sqlStrng = sqlStrng & "[FIELD] = " & limits(0) & "|"
Else
sqlStrng = sqlStrng & "([FIELD] >= " & Trim(limits(0)) & " And [FIELD] <= " & Trim(limits(1)) & ")|"
End If
Next
ProcessString = Replace(WorksheetFunction.Trim(Join(Split(Left(sqlStrng, Len(sqlStrng) - 1), "|"), " Or ")), "[FIELD]", fieldname)
End Function
The test line would be:
MsgBox ProcessString("10001 - 10050, 20111 , 20115","Deal_Line.Deal_Number")
This will produce an output that I think is more likely to be what you actually want - using OR instead of AND for starters, adding in parentheses needed for the OR to work properly and allowing for multiple table/field names.
Then again, maybe I've misinterpreted your requirement - I just can't see what use having all AND would be one one field.
you could use this helper function:
Function ProcessString(strng1 As String) As String
Dim sqlStrng As String
Dim strng As Variant, limits As Variant
For Each strng In Split(strng1, ",")
limits = Split(strng, "-")
If UBound(limits) = 0 Then
sqlStrng = sqlStrng & "Deal_Line.Deal_Number = " & limits(0) & "|"
Else
sqlStrng = sqlStrng & "Deal_Line.Deal_Number >= " & limits(0) & " And Deal_Line.Deal_Number <= " & limits(1) & "|"
End If
Next
ProcessString = WorksheetFunction.Trim(Join(Split(Left(sqlStrng, Len(sqlStrng) - 1), "|"), " And "))
End Function
to be tested/expolited in your "main" code as:
Sub main()
MsgBox ProcessString("10001 - 10050, 20111 , 20115")
End Sub
What I need to do is to basically write lessons number. There are 3 colomns.
The second column is running by a custom formula called LessonsLeft done by someone from my second thread on stackoverflow and it is
Function LessonsLeft(rng As Range) As String
If rng.Count > 1 Then Exit Function
Dim spltStr() As String
Dim i As Long
spltStr = Split(rng.Value, ",")
LessonsLeft = ",1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,"
For i = LBound(spltStr) To UBound(spltStr)
LessonsLeft = Replace(LessonsLeft, "," & spltStr(i) & ",", ",")
Next i
LessonsLeft = Mid(LessonsLeft, 2, Len(LessonsLeft) - 2)
End Function
What I need to do is to add another, third colomn which is for lessons that my students did their first attempt but they couldnt pass exam.
How i want the data to be there, is to write for exemple a "-" or "+" near a number in first column so the number will move to third column.
How can it be done ?
use this function
Function LessonsAttemptedButNotDone(rng As Range) As String
If rng.Count > 1 Then Exit Function
Dim spltStr() As String, lessonDone As String
Dim i As Long
spltStr = Split(rng.Value, ",")
For i = LBound(spltStr) To UBound(spltStr)
lessonDone = spltStr(i)
If Right(lessonDone, 1) = "-" Then
lessonDone = Left(lessonDone, Len(lessonDone) - 1)
LessonsAttemptedButNotDone = LessonsAttemptedButNotDone & lessonDone & ","
End If
Next
If LessonsAttemptedButNotDone <> "" Then LessonsAttemptedButNotDone = Left(LessonsAttemptedButNotDone, Len(LessonsAttemptedButNotDone) - 1)
End Function
I am trying to delete part of the string. For example
mystring="site, site text, sales "
I want to remove 'site' from mystring. My required output is "site text, sales"
I use this line of code :
s1 = Replace(mystring, "site", "")
but i am getting "text, sales"
I am not sure how to do this and I'd really appreciate your help!
replace("site, site text, sales ","site, ","",1,1)
You can also send as a parameter the start position and then the number of times you want to replace... (the default is -1)
There are a lot of different options here :
Just by adding the coma in the search string to be replaced and use Trim to get rid of spaces :
s1 = Trim(Replace(mystring, "site,", ""))
Specify the number of time you want the string to be replaced (first "1" is the start, the second for the number of replacements)
s1 = Trim(Replace(mystring, "site,", "",1,1))
Or the hard/bad way, to decompose your string in two pieces after the first occurence and then recombine to get result...
TempStart = Left(mystring, InStr(1, mystring, "site") + Len(mystring) + 1)
TempEnd = Replace(mystring, TempStart, "")
TempStart = Replace(TempStart, "site", "")
mystring = CStr(TempStart & TempEnd)
You can also user VB's MID function like this:
Mystring=Mid(myString, 6)
output will be "site text, sales"
Just specify the number of characters you want to be removed in the number part.
In my case I wanted to remove the part of the strings that was between "[" and "]". And the following code worked great.
So With original string in column A (and solution in column B):
Sub remove_in_string()
Dim i, lrowA, remChar As Long
Dim mString As String
lrowA = ActiveSheet.Cells(Rows.Count, 1).End(xlUp).Row
For i = 2 To lrowA
mString = Cells(i, 1).Value
If InStr(mString, "[") > 0 Then
remChar = InStr(mString, "]") - InStr(mString, "[") + 1
Cells(i, 2).Value = Left(mString, Len(mString) - remChar)
ElseIf InStr(mString, "[") = 0 Then
Cells(i, 2).Value = Cells(i, 1).Value
End If
Next
End Sub
Hello I am trying to get part of my string out and was wondering if anyone can help so here is what I am working with
Dim tempName, NewName As String
'This is an example of what tempName will Equal
'What I need is the information in between the first -
'and the second one. In this case it would be 120
'I can not do it by number because the dashes are the only thing
'that stays the same.
tempName = "3-120-12-6"
NewName = tempName 'Do not know what String Manipulation to use.
Another few examples would be 6-56.5-12-12 I need the 56.5 or 2-89-12-4 I would need the 89
Thank you for the help.
You can do this too... You can break it up into pieces by detecting the first -. Then get the second...
Dim x as String = Mid(tempName, InStr(tempName, "-") + 1)
NewName = Mid(x, 1, InStr(x , "-") - 1)
Or make something like this to get it into 1 line of code...
NewName = Mid(Mid(tempName, InStr(tempName, "-") + 1), 1, InStr(Mid(tempName, InStr(tempName, "-") + 1), "-") - 1)
Or the quickest approach to this would be to use Split like the code below... This code equates the values between - into an array. Since you want the second value, you'd want the array with the index of 1 since an array starts with 0. If you're only starting, do try to create your own way to manipulate the string, this will help your mind think of new things and not just rely on built-in functions...
Dim tempName As String = "3-120-12-6"
Dim secondname() As String = Split(tempName, "-")
NewName = secondname(1)
I am trying to make a program that changes letters in a string and i keep running into the obvious issue of if it changes a value, say it changes A to M, when it gets to M it will then change that M to something else, so when i run the code to change it all back it converts it as if the letter was originally an M not an A.
Any ideas how to make it so the code doesnt change letters its already changed?
as for code ive just got about 40 lines of this (im sure theres a cleaner way to do it but im new to vba and when i tried select case it would only change one letter and not go through all of them)
Text1.value = Replace(Text1.value, "M", "E")
Try this:
Dim strToChange As String
strToChange = "This is my string that will be changed"
Dim arrReplacements As Variant
arrReplacements = Array(Array("a", "m"), _
Array("m", "z"), _
Array("s", "r"), _
Array("r", "q"), _
Array("t", "a"))
Dim strOutput As String
strOutput = ""
Dim i As Integer
Dim strCurrentLetter As String
For i = 1 To Len(strToChange)
strCurrentLetter = Mid(strToChange, i, 1)
Dim arrReplacement As Variant
For Each arrReplacement In arrReplacements
If (strCurrentLetter = arrReplacement(0)) Then
strCurrentLetter = Replace(strCurrentLetter, arrReplacement(0), arrReplacement(1))
Exit For
End If
Next
strOutput = strOutput & strCurrentLetter
Next
Here is the output:
Thir ir zy raqing ahma will be chmnged
Loop through it using the MID function. Something like:
MyVal = text1.value
For X = 1 to Len(MyVal)
MyVal = Replace(Mid(MyVal, X, 1), "M", "E")
X = X + 1
Next X
EDIT: OK upon further light, I'm gonna make one change. Store the pairs in a table. Then you can use DLookup to do the translation, using the same concept:
MyVal = text1.value
For X = 1 to Len(MyVal)
NewVal = DLookup("tblConvert", "fldNewVal", "fldOldVal = '" & Mid(MyVal, X, 1) & "")
MyVal = Replace(Mid(MyVal, X, 1), Mid(MyVal, X, 1), NewVal)
X = X + 1
Next X
Here's another way that uses less loops
Public Function Obfuscate(sInput As String) As String
Dim vaBefore As Variant
Dim vaAfter As Variant
Dim i As Long
Dim sReturn As String
sReturn = sInput
vaBefore = Split("a,m,s,r,t", ",")
vaAfter = Split("m,z,r,q,a", ",")
For i = LBound(vaBefore) To UBound(vaBefore)
sReturn = Replace$(sReturn, vaBefore(i), "&" & Asc(vaAfter(i)))
Next i
For i = LBound(vaAfter) To UBound(vaAfter)
sReturn = Replace$(sReturn, "&" & Asc(vaAfter(i)), vaAfter(i))
Next i
Obfuscate = sReturn
End Function
It turns every letter into an ampersand + the replacement letters ascii code. Then it turns every ascii code in the replacement letter.
It took about 5 milliseconds vs 20 milliseconds for the nested loops.