vbs: Elegant way to return array element? - vbscript

While I'm expecting a first and a last name as input for a vbscript I'm writing, sometimes the data will have both in a last name field, or it may contain a middle name as well. The separations between these could be commas or spaces. The data is pulled from an HL7 message.
The working method I'm using now is as follows:
Dim sLastName, sFirstName, sName, aName
sLastName = m.Element("PID-5-1").AsString
sFirstName = m.Element("PID-5-2").AsString
if sFirstName = "" then
sName = fixName(sLastName)
aName = split(sName, "*")
sLastName = aName(0)
sFirstName = aName(1)
end if
m.Element("PID-5-1").AsString = sLastName
m.Element("PID-5-1").AsString = sFirstName
'...rest of script, then fixName function...
Function fixName(sName)
sName = LTrim(sName)
sName = RTrim(sName)
sName = replace(sName, ",", "*")
sName = replace(sName, " ", "*")
sName = replace(sName, "**", "*")
fixName = sName
End Function
So this works, but it seems a bit inelegant. The script is already on the long side, and I have to perform this clean up in many places. I'm wondering if there is a way for me to perform the split in fixName() and return each part more directly? I tried sending a position variable to the function and then sending the appropriate array element based on that position, but I get an "subscript out of range" error when I do the split in fixName().
Ideally, I'd like to be able to write something in the if statement like:
sFirstName = fixName(sLastName,1)
sLastName = fixName(sLastName,0)
How would you do it, or is what I have the best I can hope for?

To show that such a function 'works':
>> Function getNamePart(s, i) : getNamePart = Split(s)(i) : End Function
>> s = "Alpha Beta Gamma"
>> WScript.Echo getNamePart(s, 0)
>> WScript.Echo getNamePart(s, 1)
>> WScript.Echo getNamePart(s, 2)
>>
Alpha
Beta
Gamma
and to demonstrate that you shouldn't use it - your CPU will hate you, if you force her to do the Split() (and the cleaning I left off) three times for one person.

Related

Issue to SaveAs a word document in UFT using VB

Made a function to save a word document previously created and modified in another function, but it is sending me an error: This is not a valid file name.
This is my code:
Set obj_Word = CreateObject("Word.Application")
obj_Word.Visible = True
Set doc = obj_Word.Documents.Open("C:\Evidencias3.docx")
NombreDocumento = DataTable.Value("Preguntas","Global")
Sub SaveEvidences()
obj_Word.Visible = True
doc.SaveAs("C:\Evidencias_"& NombreDocumento &".docx")
obj_Word.Quit
Set obj_Word = Nothing
End Sub
I appreciated any help or recommended
You can try to clean out the file name before saving:
Public Function CleanFileName(ByVal sIn As String) As String
Dim sOut As String, sIllegalChars As String
sIllegalChars = "\/:*|?<>" + Chr(34)
sOut = sIn
For q = 1 To Len(sIllegalChars)
sOut = Replace(sOut, Mid(sIllegalChars, q, 1), "_")
Next
CleanFileName = sOut
End Function
Usage:
doc.SaveAs(CleanFileName("C:\Evidencias_"& NombreDocumento &".docx"))
Reference: MSDN - Naming Files, Paths, and Namespaces
Perhaps the problem is in the line:
NombreDocumento = DataTable.Value("Preguntas","Global")
Not familiar with the code, is it possible that it is returning a null value? If so, you could try to append an empty string to it:
NombreDocumento = DataTable.Value("Preguntas","Global") & ""
Either way, I would debug the code and see what the constructed filename actually is. Perhaps then it will become obvious.

How capitalize fullname in vb6

hi all i have this question as bellow
how capitalize full in one vb6 Vb6 string variable
‘example
‘my fullname
Dim fullname as string
Fullname = “abdirahman abdirisaq ali”
Msgbox capitalize(fullname)
it prints abdirahmanAbdirisaq ali that means it skips the middle name space even if I add more spaces its same .
this is my own code and efforts it takes me at least 2 hours and still .
I tired it tired tired please save me thanks more.
Please check my code and help me what is type of mistakes I wrote .
This is my code
Private Function capitalize(txt As String) As String
txt = LTrim(txt)
temp_str = ""
Start_From = 1
spacing = 0
For i = 1 To Len(txt)
If i = 1 Then
temp_str = UCase(Left(txt, i))
Else
Start_From = Start_From + 1
If Mid(txt, i, 1) = " " Then
Start_From = i
spacing = spacing + 1
temp_str = temp_str & UCase(Mid(txt, Start_From + 1, 1))
Start_From = Start_From + 1
Else
temp_str = temp_str & LCase(Mid(txt, Start_From, 1))
End If
End If
Next i
checkName = temp_str
End Function
It's far simpler than that. In VB6 you should use Option Explicit to properly type your variables. That also requires you to declare them.
Option Explicit
Private Function capitalize(txt As String) As String
Dim temp_str as String
Dim Names As Variant
Dim Index As Long
'Remove leading and trailing spaces
temp_str = Trim$(txt)
'Remove any duplicate spaces just to be sure.
Do While Instr(temp_str, " ") > 0
temp_str = Replace(temp_str, " ", " ")
Loop
'Create an array of the individual names, separating them by the space delimiter
Names = Split(temp_str, " ")
'Now put them, back together with capitalisation
temp_str = vbnullstring
For Index = 0 to Ubound(Names)
temp_str = temp_str + Ucase$(Left$(Names(Index),1)) + Mid$(Names(Index),2) + " "
Next
'Remove trailing space
capitalize = Left$(temp_str, Len(temp_str) - 1)
End Function
That's the fairly easy part. If you are only going to handle people's names it still needs more work to handle names like MacFarland, O'Connor, etc.
Business names get more complicated with since they can have a name like "Village on the Lake Apartments" where some words are not capitalized. It's a legal business name so the capitalization is important.
Professional and business suffixes can also be problematic if everything is in lower case - like phd should be PhD, llc should be LLC, and iii, as in John Smith III, would come out Iii.
There is also a VB6 function that will capitalize the first letter of each word. It is StrConv(string,vbProperCase) but it also sets everything that is not the first letter to lower case. So PhD becomes Phd and III becomes Iii. Where as the above code does not change the trailing portion to lower case so if it is entered correctly it remains correct.
Try this
Option Explicit
Private Sub Form_Load()
MsgBox capitalize("abdirahman abdirisaq ali")
MsgBox capitalize("abdirahman abdirisaq ali")
End Sub
Private Function capitalize(txt As String) As String
Dim Names() As String
Dim NewNames() As String
Dim i As Integer
Dim j As Integer
Names = Split(txt, " ")
j = 0
For i = 0 To UBound(Names)
If Names(i) <> "" Then
Mid(Names(i), 1, 1) = UCase(Left(Names(i), 1))
ReDim Preserve NewNames(j)
NewNames(j) = Names(i)
j = j + 1
End If
Next
capitalize = Join(NewNames, " ")
End Function
Use the VB6 statement
Names = StrConv(Names, vbProperCase)
it's all you need (use your own variable instead of Names)

VBScript: Resort String and group with new Split Item

'I Have the below String.. that splited with "#"
myStr = "78,6$25,01|25,02|25,03|25,04#74,5$15,01|15,02|15,03|15,04#70,1$25,06|25,07|25,08|25,09#77,3$25,07|25,08|25,09|25,10#78,2$10,05|10,06|10,07|10,08"
'And I want resort to this New String with New Grouping...
'i should group splited string with first value after dollar($) chrachter
But i dont know how should I Sorting and Grouping to new desired result:
myStrDesired = "78,2$10,05|10,06|10,07|10,08#74,5$15,01|15,02|15,03|15,04#78,6$25,01|25,02|25,03|25,04#70,1$25,06|25,07|25,08|25,09#77,3$25,07|25,08|25,09|25,10"
My Script:
Function GroupArrays()
myStr = "78,6$25,01|25,02|25,03|25,04#74,5$15,01|15,02|15,03|15,04#70,1$25,06|25,07|25,08|25,09#77,3$25,07|25,08|25,09|25,10#78,2$10,05|10,06|10,07|10,08"
'And I want resort to this New String with New Grouping...
'i should group splited string with first value after dollar($) chrachter
myStrDesired = "78,2$10,05|10,06|10,07|10,08#74,5$15,01|15,02|15,03|15,04#78,6$25,01|25,02|25,03|25,04#70,1$25,06|25,07|25,08|25,09#77,3$25,07|25,08|25,09|25,10"
arrMyStr = Split(myStr,"#")
arrMyStrDesired = ""
for i = 0 to UBound(arrMyStr)
' find group id from each string
groupVal = Split(Split(arrMyStr(i),"$")(1),",")(0)
' put the same groups together and split them by "#" And finally the isolation of other disciplines with "#"
arrMyStrDesired = arrMyStrDesired & arrMyStr(i)
next
GroupArrays = arrMyStrDesired
End Function
New Description:*
Split the main String by "#".
In the each parts splited... see the first value after "$" and name to "groupId". (it is Important parameter for Grouping and sorting)
All of each parts has same groupId should be placed side by side and Joined by "#".
After above Steps... we should Join All New strings with other groupId by "#".... same as ... (00$01,05#01,06#...#02,07#03,4.....)
The following should work on any Windows machine with the Dot Net runtime. If for some reason you don't have that -- would need a custom sort:
myStr = "78,6$25,01|25,02|25,03|25,04#74,5$15,01|15,02|15,03|15,04#70,1$25,06|25,07|25,08|25,09#77,3$25,07|25,08|25,09|25,10#78,2$10,05|10,06|10,07|10,08"
myDesiredStr = "78,2$10,05|10,06|10,07|10,08#74,5$15,01|15,02|15,03|15,04#78,6$25,01|25,02|25,03|25,04#70,1$25,06|25,07|25,08|25,09#77,3$25,07|25,08|25,09|25,10"
Function GroupVal(group)
A = Split(group,"$")
B = Split(A(1),",")
GroupVal = CInt(B(0))
End Function
Function ReSort(str)
Set D = CreateObject("Scripting.Dictionary")
Set keyList = CreateObject("System.Collections.ArrayList")
groups = Split(str,"#")
For i = 0 to UBound(groups)
group = groups(i)
v = GroupVal(group)
If D.Exists(v) Then
D.Item(v) = D.Item(v) & "#" & group
Else
D.Add v,group
keyList.Add v
End If
Next
keyList.Sort()
newGroups = Array()
ReDim newGroups(Ubound(groups))
i = -1
For Each v In keyList
i = i + 1
newGroups(i) = D.item(v)
Next
ReDim Preserve newGroups(i)
Resort = Join(newGroups,"#")
End Function
MsgBox myDesiredStr = Resort(myStr)
The msgbox pops up True

compare wscript.arguments and string

I want to compare an wscript.argument that I got to the vbs to a string, so depending in that comparation one action or another is performed. I have tried this, but I get an error. How can I solve it? How can I make the type comparation?
Set args = Wscript.Arguments
Set accessPath = args.Item(5)
If accessPath = "-" Then
objExcel.Cells(15, 3).Value = " "
Else
objExcel.Cells(15, 3).Value = accessPath
End If
Use this instead:
Dim accessPath : accessPath = Wscript.Arguments(5)
If accessPath = "-" Then
objExcel.Cells(15, 3).Value = " "
Else
objExcel.Cells(15, 3).Value = accessPath
End If
Bear in mind that arguments start at 0, so by looking at Wscript.Arguments(5) you're actually looking at the sixth entry on the command line.
Finally you may want to also check the value of Wscript.Arguments.Count to ensure you have had enough arguments passed, otherwise an error will be thrown.

Visual Basic split function

Ok so now I'm not getting an error but instead of everything being posted in the listbox it only contains the first line of text from the .txt file. This is the code I changed it too:
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim inFile As IO.StreamReader
If IO.File.Exists("StudentList.txt") = True Then
inFile = IO.File.OpenText("StudentList.txt")
For index As Integer = 0 To inFile.Peek = -1
Dim splits = inFile.ReadLine.Split(","c)
Member(index).ID = splits(0)
Member(index).lastName = splits(1)
Member(index).firstName = splits(2)
Member(index).middleName = splits(3)
Member(index).grade = splits(4)
Member(index).period = splits(5)
ListBox1.Items.Add(Member(index).ID.PadLeft(10) & " " & Member(index).lastName & " " & Member(index).firstName)
Next
inFile.Close()
Else
MessageBox.Show("error", "error", MessageBoxButtons.OK)
End If
End Sub
The problem is that you're trying to assign a string array to a Member. That is, you have:
Member(index) = infile.ReadLine.Split(",", c);
You need to assign each field:
Dim splits = infile.ReadLine.Split(",", c);
Member(index).ID = splits(0);
Member(index).lastName = splits(1);
... etc.
Update after OP edit
I suspect the problem now is that your For loop is executing only once, or index isn't being incremented. I don't know where you came up with that wonky infile.Peek = -1 thing, but I suspect it doesn't work the way you think it does. Use something more conventional, like this.
Dim index As Integer = 0
For Each line As String In File.ReadLines("StudentList.txt")
Dim splits = line.Split(",", c)
Member(index).ID = splits(0)
' etc.
ListBox1.Add(...)
Index = Index + 1
Next

Resources