I would like to check a txt file for a string.
If the string doesn't exist, it takes a number from key.txt and write it in another file. That part works fine.
But when the string is found, I would like to read the first five characters into a variable and take this variable to creating xml. When I run my script and the string is found.... the xml element Key is empty...
Anyone can help me? Thanks
Dim FSSys, Reference, corp, Account, intCorp, strPK, FS
Set FSSys = Wscript.CreateObject("Scripting.FileSystemObject")
Set Reference = FSSys.OpenTextFile("C:\corpreferenz.txt")
intCorp = Reference.ReadAll
Reference.Close
intCorp = intCorp + 1
Set corp = FSSys.CreateTextFile("C:\corpreferenz.txt")
corp.Write intCorp
corp.Close
Const FORREADING = 1
Const FORWRITING = 2
Const FORAPPENDING = 8
Dim sToSearch: sToSearch = "Test"
Dim sFileName: sFileName = "C:\Account.txt"
Dim sContent, Found, TxtFile
If Not FSSys.FileExists(sFileName) Then
MsgBox "File Not Found"
WScript.Quit 0
End If
Set TxtFile = FSSys.OpenTextFile(sFileName,FORREADING)
sContent = TxtFile.ReadAll
If InStr(sContent,sToSearch) Then
Found = True
while not TxtFile.AtEndOfStream
sTemp = TxtFile.ReadLine
If Instr(1,sTemp,sToSearch)>0 then
strPK = strPK + sTemp
FS = Left(strPK, 5)
End If
Wend
End If
Set TxtFile = Nothing
If Not Found Then
Set PKNumber = FSSys.OpenTextFile("C:\Key.txt")
intPKNumber = PKNumber.ReadAll
PKNumber.Close
intPKNumber = intPKNumber + 1
Set PKNum = FSSys.CreateTextFile("C:\Key.txt")
PKNum.Write intPKNumber
PKNum.Close
FS = intPKNumber
Set TxtFile = FSSys.OpenTextFile(sFileName,FORAPPENDING)
TxtFile.WriteLine intPKNumber & " " & sToSearch
End If
'Create XML
set xml = CreateObject("Microsoft.XMLDOM")
set encoding = xml.createProcessingInstruction("xml", "version='1.0'")
xml.insertBefore encoding, xml.childNodes.Item(0)
set foo = xml.createElement("XML")
set bar = xml.createElement("Table")
set corp = xml.createElement("Corp")
set cdata = xml.createCDATASection(intCorp)
set konto = xml.createElement("Key")
set cdata1 = xml.createCDATASection(FS)
corp.appendChild cdata
bar.appendChild corp
konto.appendChild cdata1
bar.appendChild konto
foo.appendChild bar
xml.appendChild(foo)
xmlSave xml, "C:BUP.xml"
'Function for XML
function xmlSave(xml, filename)
set rdr = CreateObject("MSXML2.SAXXMLReader")
set wrt = CreateObject("MSXML2.MXXMLWriter")
Set oStream = CreateObject("ADODB.STREAM")
oStream.Open
oStream.Charset = "ISO-8859-1"
wrt.indent = True
wrt.encoding = "ISO-8859-1"
wrt.output = oStream
Set rdr.contentHandler = wrt
Set rdr.errorHandler = wrt
rdr.Parse xml
wrt.flush
oStream.SaveToFile filename, 2
end function
After
sContent = TxtFile.ReadAll
you (the read pointer) are at the end of the file; TxtFile.AtEndOfStream is True and TxtFile.ReadLine won't be called/would fail. Evidence:
>> Set f = CreateObject("Scripting.FileSystemObject").OpenTextFile(WScript.ScriptFullName)
>> WScript.Echo 0, CStr(f.AtEndOfStream)
>> s = f.ReadAll()
>> WScript.Echo 1, CStr(f.AtEndOfStream)
>>
0 Falsch (False)
1 Wahr (True)
You could loop over the lines of the file (Split() sContent on vbCrLf), or - better - use a RegExp on sContent to extract the data needed.
I need to sort a dictionary by its key, but the values are class items.
Here is the class:
CLASS Person
PUBLIC PersonID
PUBLIC PersonName
PUBLIC GenderID
PUBLIC PersonAdditional
PRIVATE SUB class_initialize()
PersonID = null
PersonName = null
GenderID = null
PersonAdditional = null
END SUB
END CLASS
And here is my dictionary, filled with data from an array:
Set dict = Server.CreateObject("Scripting.Dictionary")
FOR i = 0 TO UBOUND(arr_People)
key_person = arr_People(i).GenderID & arr_People(i).PersonName
dict.Add key_person, new Person
dict.Item(key_person).PersonName = arr_People(i).PersonName
dict.Item(key_person).GenderID = arr_People(i).GenderID
dict.Item(key_person).PersonID = arr_People(i).PersonID
dict.Item(key_person).PersonAdditional = arr_People(i).PersonAdditional
NEXT
I use this function for sorting, but it doesn't seem to work:
Function SortDictionary(objDict,intSort)
Dim strDict()
Dim objKey
Dim strKey,strItem
Dim X,Y,Z
Z = objDict.Count
If Z > 1 Then
ReDim strDict(Z,2)
X = 0
For Each objKey In objDict
strDict(X,dictKey) = CStr(objKey)
strDict(X,dictItem) = CStr(objDict(objKey))
X = X + 1
Next
For X = 0 to (Z - 2)
For Y = X to (Z - 1)
If StrComp(strDict(X,intSort),strDict(Y,intSort),vbTextCompare) > 0 Then
strKey = strDict(X,dictKey)
strItem = strDict(X,dictItem)
strDict(X,dictKey) = strDict(Y,dictKey)
strDict(X,dictItem) = strDict(Y,dictItem)
strDict(Y,dictKey) = strKey
strDict(Y,dictItem) = strItem
End If
Next
Next
objDict.RemoveAll
For X = 0 to (Z - 1)
objDict.Add strDict(X,dictKey), strDict(X,dictItem)
Next
End If
End Function
It gives me the following error:
Object doesn't support this property or method
on this row:
strDict(X,dictItem) = CStr(objDict(objKey)
I'm assuming that this happens because the values in the dictionary contains class instead of just a string or integer, but I don't know how to handle it.
There's a workaround that you can use:
Create another array containing only the keys of the dictonary
Sort the array
Read the dictionary values by iterating trough the array of keys
And here's the code:
Set dict = Server.CreateObject("Scripting.Dictionary")
Set arr_personKeys = CreateObject("System.Collections.ArrayList")
FOR i = 0 TO UBOUND(arr_People)
key_person = arr_People(i).GenderID & arr_People(i).PersonName
arr_personKeys.Add key_person
dict.Add key_person, new Person
dict.Item(key_person).PersonName = arr_People(i).PersonName
dict.Item(key_person).GenderID = arr_People(i).GenderID
dict.Item(key_person).PersonID = arr_People(i).PersonID
dict.Item(key_person).PersonAdditional = arr_People(i).PersonAdditional
NEXT
arrLength_personKeys = arr_personKeys.count - 2
SortArray arr_personKeys,arrLength_personKeys
And here is the sorting function:
Function SortArray(arrayForSorting, arraySize)
for a = arraySize To 0 Step -1
for j = 0 to a
if arrayForSorting(j)>arrayForSorting(j+1) then
temp=arrayForSorting(j+1)
arrayForSorting(j+1)=arrayForSorting(j)
arrayForSorting(j)=temp
end if
next
next
End Function
Now you can iterate trough your sorted dictionary like this:
For i = 0 To arrLength_personKeys + 1
key = arr_personKeys(i)
Response.write dict(key).PersonID
Response.write dict(key).PersonName
Response.write dict(key).GenderID
Response.write dict(key).PersonAdditional
Next
'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
why now return ....Syntax error
Can i put the Sub rutine in the function? Or better way for this?!
Function SumerizePlanArrays(f_String, f_Type)
Set dic = CreateObject("Scripting.Dictionary")
Sub Add(s)
weight = Split(s,"$")(0)
values = Split(s,"$")(1)
pipes = Split(values, "|")
For Each line In pipes
val = Split(line, ",")
if f_Type = 1 then
dic(val(1)) = (dic(val(1))*weight/100) + CInt(val(2))
elseif f_Type = 2 then
dic(val(1)) = dic(val(1)) + CInt(val(2))
end if
Next
End Sub
arrString = Split(f_String,"#")
For i = 0 to UBound(arrString)
'wei = Split(arrString(i),"$")(0)
Add arrString(i)
Next
Set a = CreateObject("System.Collections.ArrayList")
For Each key In dic.Keys
a.Add "0," & key & "," & dic(key)
Next
a.Sort
result = Join(a.ToArray, "|")
SumerizePlanArrays = result
End Function
Microsoft VBScript compilation error '800a03ea'
Syntax error
/inc_func_projects.asp, line 2592
Sub Add(s)
^
No - you can't put a sub within a function, except in JavaScript or in the server side version called JScript. VBScript and JScript are two completely different languages, however.
You should be doing this...
Function SumerizePlanArrays(f_String, f_Type)
Set dic = CreateObject("Scripting.Dictionary")
arrString = Split(f_String,"#")
For i = 0 to UBound(arrString)
'NOTE: Updated the call to reflect comment by sadrasjd...
Add arrString(i, f_Type, dic)
Next
Set a = CreateObject("System.Collections.ArrayList")
For Each key In dic.Keys
a.Add "0," & key & "," & dic(key)
Next
a.Sort
result = Join(a.ToArray, "|")
SumerizePlanArrays = result
End Function
Sub Add(s, type, dic)
'NOTE: ^Updated the parameters to reflect comment by sadrasjd^
weight = Split(s,"$")(0)
values = Split(s,"$")(1)
pipes = Split(values, "|")
For Each line In pipes
val = Split(line, ",")
if type = 1 then
dic(val(1)) = (dic(val(1))*weight/100) + CInt(val(2))
elseif type = 2 then
dic(val(1)) = dic(val(1)) + CInt(val(2))
end if
Next
End Sub
NOTE: Updated the call to reflect the suggestion made by sadrasjd.
Ok so I'm working on a program that parses input in the textbox and finds a delimiter such as a comma, space, or a line pressed using enter key and extracting each word before each delimiter and posting it in the listbox. I keep getting errors though.
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
Dim delimiter As String = ""
Dim oldIndex As Integer = 0
Dim newIndex As Integer = 0
Dim length As Integer = 0
Dim tempString As String = ""
Dim tempWord As String = ""
Dim advanceSize As Integer = 0
If RadioButton1.Checked = True Then
delimiter = ","
advanceSize = 1
tempString = TextBox1.Text
length = tempString.Length
Do While oldIndex < length
newIndex = tempString.IndexOf(delimiter)
tempWord = Mid(tempString, oldIndex, newIndex)
tempWord.Trim()
oldIndex = newIndex + advanceSize
ListBox1.Items.Add(tempWord)
Loop
ElseIf RadioButton2.Checked = True Then
delimiter = vbCrLf
advanceSize = 2
tempString = TextBox1.Text
length = tempString.Length
Do While oldIndex < length
newIndex = tempString.IndexOf(delimiter)
newIndex = tempString.IndexOf(delimiter)
tempWord = Mid(tempString, oldIndex, newIndex)
tempWord.Trim()
oldIndex = newIndex + advanceSize
ListBox1.Items.Add(tempWord)
Loop
ElseIf RadioButton3.Checked = True Then
delimiter = " "
advanceSize = 1
tempString = TextBox1.Text
length = tempString.Length
Do While oldIndex < length
newIndex = tempString.IndexOf(delimiter)
newIndex = tempString.IndexOf(delimiter)
tempWord = Mid(tempString, oldIndex, newIndex)
tempWord.Trim()
oldIndex = newIndex + advanceSize
ListBox1.Items.Add(tempWord)
Loop
Else
Exit Sub
In the first line read, the value of oldindex is zero. The Mid function requires a number greater than zero for the second parameter because, unlike the string.substring method, it is one-based rather than zero-based. The error will be resolved if you initialize oldindex to 1.
Incidentally, the third parameter of mid (and .substring) is length, not an ending index.
May I suggest an alternative which achieves the goal of your question? There is a String.Split function which you can use. It's a bit fiddly, as to split on a string you need to use an array of strings (there can be just one in the array, which is all we need) and you have to specify a StringSplitOptions value, but apart from that it is easy to use:
Private Sub bnSplitData_Click(sender As Object, e As EventArgs) Handles bnSplitData.Click
Dim txt = tbDataToSplit.Text
Dim delimiter As String() = Nothing
' select case true is an easy way of looking at several options:
Select Case True
Case rbCommas.Checked
delimiter = {","}
Case rbNewLines.Checked
delimiter = {vbCrLf}
Case rbSpaces.Checked
delimiter = {" "}
Case Else ' default value
delimiter = {","}
End Select
Dim parts = txt.Split(delimiter, StringSplitOptions.RemoveEmptyEntries)
' get rid of the old entries
ListBox1.Items.Clear()
' add the new entries all in one go
ListBox1.Items.AddRange(parts)
End Sub
Please note how I gave the controls (except ListBox1) meaningful names - it makes referring to the correct one much easier.