I want to take a name in First Last format and change it to Last, First. I know I could to this with a formula but I want to be complicated.
Please let me know if you see any red flags in my code, or suggestions for improvements.
Function LastFirst(Name_FL As String)
'This only works if there is a single space in the cell - Will Error If Spaces <> 1
Length = Len(Name_FL) 'Establishes Length of String
Spaces = Length - Len(Application.WorksheetFunction.Substitute(Name_FL, " ", "")) 'Number of spaces
If Spaces <> 1 Then
LastFirst = "#SPACES!#" 'Error Message
Else
SpaceLocation = Application.WorksheetFunction.Find(" ", Name_FL, 1) 'Location of space
Last = Right(Name_FL, Length - SpaceLocation) 'Establishes Last Name String
First = Left(Name_FL, SpaceLocation) 'Establishes First Name String
LastFirst = Application.WorksheetFunction.Proper(Last & ", " & First) 'Puts it together
End If
End Function 'Ta-da
You could simplify it to:
Function LastFirst(Name_FL As String) As String
If (Len(Name_FL) - Len(Replace(Name_FL, " ", ""))) > 1 Then
LastFirst = "#SPACES#"
Else
LastFirst = StrConv(Split(Name_FL, " ")(1) & ", " & Split(Name_FL, " ")(0), vbProperCase)
End If
End Function
The logic here is:
If there is more than 1 space, return the error string #SPACES#
If there is 1 space, the split the string using " " as a delimiter.
Use the second index of the Split array, add ", " and use the first index of the split array.
Use StrConv() to convert it all to proper case.
You might also want to add another check for no spaces:
If InStr(Name_FL, " ") > 0 Then
'// There is a space in the string
Else
'// There is no space in the string
End If
Which can also be tested for by slightly changing the logic of the above example:
Function LastFirst(Name_FL As String) As String
If (Len(Name_FL) - Len(Replace(Name_FL, " ", ""))) = 1 Then
LastFirst = StrConv(Split(Name_FL, " ")(1) & ", " & Split(Name_FL, " ")(0), vbProperCase)
Else
LastFirst = "#SPACES#"
End If
End Function
Further elaboration on functions:
You can see I've used some VBA functions here in place of your WorksheetFunction methods.
Len() returns the Length of a string.
Replace() does what it says on the tin - replaces a given string with another.
StrConv() Converts a String to a respective case (e.g. vbProperCase).
Split() Creates a zero-based single dimension array from a string, by Splitting it on a given delimiter.
Finally - Don't forget to specify a return value in your function header:
Function LastFirst(Name_FL As String)As String<~~ return type
Related
I have a variable with a string...and I want to know if it contains any value other than single quote, comma and a space ("', ") I'm using vba in excel.
for example, i have a varible strA = "'test', 'player'"
I want to check to see if strA has any characters other than "', " (single quote, comma and space).
Thanks
Here is a strategy based on Count occurrences of a character in a string
I don't have vba handy, but this should work. The idea is to remove all these characters and see if anything is left. text represents your string that is being tested.
Dim TempS As String
TempS = Replace(text, " " , "")
TempS = Replace(TempS, "," , "")
TempS = Replace(TempS, "'" , "")
and your result is Len(TempS>0)
Another approach is to use recursion by having a base case of false if the string is empty, if the first character is one of the three call ourselves on the rest of the string, or if not the value is true. Here is the code
function hasOtherChars(s As String) As Boolean
hasOtherChars=false
if (len(s)=0) then
exit function
end if
Dim asciiSpace As Integer
asciiSpace = Asc(" ")
Dim asciiComma As Integer
asciiComma= Asc(",")
Dim asciiApostrophe As Integer
asciiApostrophe = Asc("'")
Dim c as Integer
c = Asc(Mid$(s, 1, 1))
if ((c=asciiSpace) or (c=asciiComma) or (c=asciiApostrophe)) then
hasOtherChars = hasOtherChars(Mid$(s,2))
else
hasOtherChars=true
end if
End function
Again I am borrowing from the other thread.
I need to check a string to see if there are any references of a number that is more than or less than 4 characters long.
So here are some examples of numbers that may be within the string:
0123
3443
9320
So it is not as easy as selecting the number and checking if it is more than 999 and less than or equal to 9999 as numbers can start with a 0.
Here is an example of the data which may be stored in a string
Profile ID: 3243, 9432, 0232, 3423
Profile ID: 3243/3454/0213/3253
Test 2434 2342 4325 2132
Here are some examples of what would return valid and invalid
0324 TRUE
39234 FALSE
2393 TRUE
192 FALSE
As there is no fixed dilemma for separating the data I am not sure how I would go about separating the numbers from the string.
My original idea was to only extract numbers and replace all others with a space. Then use the space as a dilema. If the string was blank then skip that for the check but if it contained a value then check if the length of the string was 4 characters.
All solutions or ideas are welcome
Assuming the string is selected, you could use code like:
Sub Demo()
Dim StrData As String, StrTmp As String, i As Long
With Selection
If InStr(.Text, vbCr) Then
.Collapse wdCollapseStart
.MoveEndUntil vbCr, wdForward
End If
StrTmp = Replace(Replace(Replace(Replace(Split(.Text, vbLf)(0), vbTab, " "), "/", " "), ",", " "), " ", " ")
For i = 1 To UBound(Split(StrTmp, " "))
StrData = Split(StrTmp, " ")(i)
If IsNumeric(StrData) Then
If Len(Split(StrTmp, " ")(i)) <> 4 Then
.InsertAfter " Invalid": Exit For
End If
End If
Next
End With
End Sub
As coded, the macro inserts ' Invalid' after the string if it contains an out-of-range number.
Function CheckNumbers(ByVal s As String) As Boolean
s = " " & s & " "
CheckNumbers = Not s Like "*#####*" _
And Not s Like "*[!0-9]###[!0-9]*" _
And Not s Like "*[!0-9]##[!0-9]*" _
And Not s Like "*[!0-9]#[!0-9]*"
End Function
https://msdn.microsoft.com/en-us/vba/language-reference-vba/articles/like-operator
Issue, where the character I am removing does not exist I get a blank string
Aim: To look for three characters in order and only get the characters to the left of the character I am looking for. However if the character does not exist then to do nothing.
Code:
Dim vleftString As String = File.Name
vleftString = Left(vleftString, InStr(vleftString, "-"))
vleftString = Left(vleftString, InStr(vleftString, "_"))
vleftString = Left(vleftString, InStr(vleftString, " "))
As a 'fix' I have done
Dim vleftString As String = File.Name
vleftString = Replace(vleftString, "-", " ")
vleftString = Replace(vleftString, "_", " ")
vleftString = Left(vleftString, InStr(vleftString, " "))
vleftString = Trim(vleftString)
Based on Left of a character in a string in vb.net
If File.Name is say 1_2.pdf it passes "-" and then works on line removing anything before "" (though not "" though I want it to)
When it hits the line for looking for anything left of space it then makes vleftString blank.
Since i'm not familiar (and avoid) the old VB functions here a .NET approach. I assume you want to remove the parts behind the separators "-", "_" and " ", then you can use this loop:
Dim fileName = "1_2.pdf".Trim() ' Trim used to show you the method, here nonsense
Dim name = Path.GetFileNameWithoutExtension(fileName).Trim()
For Each separator In {"-", "_", " "}
Dim index = name.IndexOf(separator)
If index >= 0 Then
name = name.Substring(0, index)
End If
Next
fileName = String.Format("{0}{1}", name, Path.GetExtension(fileName))
Result: "1.pdf"
I'm trying to convert a string that contains someones name as "Last, First" to "First Last".
This is how I am doing it now:
name = name.Trim
name = name.Substring(name.IndexOf(",") + 1, name.Length) & " " & name.Substring(0, name.IndexOf(",") - 1)
When I do this I get the following error:
ArgumentOutOfRangeException was unhandled
Index and length must refer to a location within the string
Parameter name: length
Can someone explain why I am getting this error and how I should be doing this?
You are getting error on this:
name.Substring(name.IndexOf(",") + 1, name.Length)
name.Length should have subtracted with the length of the string before the comma.
The best way for that is to split the string.
Dim oFullname as string = "Last, First"
Dim oStr() as string = oFullname.split(","c)
oFullname = oStr(1).trim & " " & oStr(0).trim
MsgBox (oFullname)
The second parameter for String.Substring is the length of the substring, not the end position. For this reason, you're always going to go out of bounds if you do str.Substring(n, str.Length) with n > 0 (which would be the whole point of a substring).
You need to subtract name.IndexOf(",") + 1 from name.Length in your first substring. Or just split the string, as the others have suggested.
simply ,you only need to split the string
Dim originalName As String = "Last,First"
Dim parts = name.Split(","C)
Dim name As String = parts(1) & " " & parts(0)
If you're using the Unix command line--like the terminal on a Mac--you can do it like this:
Let's say that you have a file containing your last-comma-space-first type names like this:
Last1, First1
Last2, First2
Last3, First3
OK, now let's save it as last_comma_space_first.txt. At this point you can use this command I came up with for your particular problem:
sed -E 's/([A-Za-z0-9]+), ([A-Za-z0-9]+)/\2 \1/g' last_comma_space_first.txt > first_space_last.txt
--->>> Scroll --->>>
You're done! Now, go check that first_space_last.txt file! ^_^ You should get the following:
First1 Last1
First2 Last2
First3 Last3
Tell your friends... Or don't...
This would work keeping to the posters format.
Name = "Doe,John"
Name = Replace(Name.Substring(Name.IndexOf(","), Name.Length - Name.IndexOf(",")) & " " & Name.Substring(0, Name.IndexOf(",")), ",", "")
Result Name = "John Doe"
This is my code:
With ad.Tables(2)
For i As Integer = 0 To .Rows.Count - 1
If .Rows(i)("name") & "" <> "" Then
temp &= .Rows(i)("name") & ", "
End If
Next
End With
temp = temp.Trim(",")
testing &= "&Name=" & temp & vbCrLf
With this is get a comma in the end of the string. But if I do
temp = temp.Trim.Trim(",")
all commas are deleted.
How do I keep all commas and only delete the last one?
temp = temp.TrimEnd(CChar(","))
That will do it and I think it is the easiest way.
temp = temp.Trim().Substring(0, temp.Length - 1)
or
temp = temp.Trim().Remove(temp.Length - 1)
You can avoid the Trim/extra character if you set a delimiter within the loop
Dim delimiter as string = ""
For i As Integer = 0 To .Rows.Count - 1
If .Rows(i)("name") & "" <> "" Then
temp &= delimiter & .Rows(i)("name")
delimiter = ","
End If
Next
The Trim() function has a Char() (static array of characters) parameter on it, you don't need to pass a Char explicitly.
' VB.Net Version
", Hello ^_^ ^_^ ,,, , ,, ,, ,".Trim({" "c, ","c})
//C# version
", Hello ^_^ ^_^ ,,, , ,, ,, ,".Trim({' ', ','})
Would produce the output
"Hello ^_^ ^_^"
The multi-parameter .Trim() removes the specified characters from both the beginning and the end of the string. If you want to only trim out the beginning or the end, use .TrimStart() or .TrimEnd() respectively.
This works:
dim AlarmStr as string="aaa , bbb , ccc , "
AlarmStr = AlarmStr.Remove(AlarmStr.LastIndexOf(","))
Check to see if the loop is done before adding the last comma. #cleaner
While dr.Read
For c As Integer = 0 To dr.FieldCount - 1
s.Append(dr(c).ToString.Trim)
'This line checks if the loop is ending before adding a comma
If (c < dr.FieldCount - 1) Then s.Append(",")
Next
s.Append(vbCrLf)
End While
I wonder, that based on the OP's code sample, nobody suggested to use String.Join or build an output with StringBuilder
Dim names As New List(Of String)
With ad.Tables(2)
For i As Integer = 0 To .Rows.Count - 1
' DataRow("columnName").ToString() returns value or empty string if value is DbNull
If .Rows(i)("name").ToString() <> "" Then
names.Add(.Rows(i)("name"))
End If
Next
End With
Dim temp As String = String.Join(", ", names)
testing &= "&Name=" & temp & vbCrLf
With LINQ and DataRow extension method .Field(Of T) code will look simpler
Dim names = ad.Tables(2).
AsEnumerable().
Select(row => row.Field<String>("name")).
Where(name => String.IsNullOrEmpty(name) = False)
Dim temp As String = String.Join(", ", names)
testing &= "&Name=" & temp & vbCrLf
If you go further you can(should) use StringBuilder for building a string and use Aggregate method to build string from the collection
I know that a little bit odd, but I found this works for me:
Visual Basic:
Every time: mystring = "today, I love go out , , , ," (less than five commas and spaces)
mystring.Trim.TrimEnd(",").Trim.TrimEnd(",").Trim.TrimEnd(",").Trim.TrimEnd(",").Trim.TrimEnd(",")
temp = temp.TrimEnd()
this trims the trailing spaces from a string.