VB Script writing to MultiString reg key - arrays

I'm writing a script that looks at the current home page of IE. if it is something other than our intranet I grab that value and merge it in to the secondary pages reg key.
Now I have figured out how merge it in to an array(assuming that there are some secondary pages... if there are no big deal). What I am running in to is that there seems to be an extra line when I finally merge it. It's driving me nuts. Any thoughts? Here is the function. There is more tot he script but this is the part that is painful. Thanks
Function AppendSecondary(StrComputer)
objReg.GetstringValue HKEY_CURRENT_USER, strKeyPath, ValueName, strValueMain
objReg.SetStringValue HKEY_CURRENT_USER, strKeyPath, ValueName, strValueMyMTD
set ws = WScript.CreateObject("Wscript.Shell")
strKeyPath=WS.RegRead(strKeyPathPath & ValueNameSecondary)
if vartype(strKeyPath)= vbArray + vbVariant then
arStrings = strKeyPath
else
arStrings = split(strKeyPath,chr(0))
redim preserve arStrings(ubound(arStrings)-3)
end If
redim preserve arStrings(ubound(arStrings)+1)
arstrings(ubound(arStrings))= strvaluemain
arstrings1 = join(arStrings,VBCRLF)
arstringsnew = Array(arstrings1)
objReg.SetMultiStringValue HKEY_CURRENT_USER, strKeyPath, ValueNameSecondary, arstringsnew
End Function

Check the last element of each array to make sure it's not a null string ("") or a non-printing character like Chr(10) or Chr(13) or vbCR, vbLF or vbCRLF.

Interesting question.
Just out of curiosity, why do you merge an array, then rebuild it as an array later on?
arstrings1 = join(arStrings,VBCRLF) 'merge
arstringsnew = Array(arstrings1) 'reassemble
Regardless, I think your split on "chr(0)" is creating this issue and a simple revision too the join command will suffice.
arstrings1 = trim(join(arstrings,vbcrlf))
of if not the case, a quick loop'd'loop
dim nArray() : Redim nArray(0)
for each str in arstrings
if len(str)>0 then
nArray(ubound(nArray)) = str
redim preserve nArray(ubound(nArray)+1)
end if
next
arrstringsnew = nArray

Related

Less compact form

def read_file(filename):
trolls = dict()
try:
with open(filename) as file:
for line in file:
city, data = line.split(':')
for i in data.split():
trolls[city] = [int(_) for _ in data.split()]
except OSError as error:
print(f"Yeuch!: {error}")
return trolls
How can I rewrite this line:
trolls[city] = [int(_) for _ in data.split()]
in a less compact way?
In these two lines in your code
for i in data.split():
trolls[city] = [int(_) for _ in data.split()]
the for loop is uselessly repeating the work on the second line however many elements are in the list times, but the result is the same.
(in your code, the second line isn't indented but it should be, otherwise you'll just get a SyntaxError, so I assume it just didn't paste correctly and you have it indented)
I think you meant to do this
if city not in trolls:
trolls[city] = []
for i in data.split():
trolls[city].append(int(i))
or simply delete the for i in data.split(): line in your original code.

Word VBA Array not behaving as expected

I'm iterating through a list of keywords to define terms in a document but only certain keywords will get picked up.
For instance, with Array("Agreement", "deed", "AGREEMENT", "letter agreement", "letter", "Undertaking"), "Agreement" and "letter" get picked up just fine, but letter agreement and Undertaking do not.
I've tried rearranging the order of the array but that does nothing.
I'm guessing there's something fundamental about arrays I'm misunderstanding. I'm more familiar with python and am going for list functionality.
Full code is below. Any pointers would be very much appreciated.
Function getagree() As String
Dim aggrlist As Variant
aggrlist = Array("Agreement", "NDA", "deed", "AGREEMENT", "letter
agreement", "letter", "Undertaking", "Confidentiality Undertaking",
"agreement")
Set myRange = ActiveDocument.Content
With myRange.Find
For Each aggr In aggrlist
.ClearFormatting
.Text = aggr
.MatchWholeWord = True
.MatchCase = True
.Execute Forward:=True
If .Found = True Then
getagree = aggr
End If
Next
End With
End Function
Try using an underscore (_) to break your string into multiple lines...
aggrlist = Array("Agreement", "NDA", "deed", "AGREEMENT", _
"letter agreement", "letter", "Undertaking", _
"Confidentiality Undertaking", "agreement")

How do I check if an object collides with every object in an array?(Picture boxes)

High school student here and I'm pretty rusty on my code. Okay, I have to have an image scroll along, and if it hits an object(in this case both are picture boxes), it resets.
The problem is when it gets to the If statement below, it won't work saying " 'bounds' is not a member of 'system.array' "
If PtbIcon.Bounds.IntersectsWith(objects.Bounds) Then
The error is the Objects.bounds
If PtbIcon.Bounds.IntersectsWith(objects.Bounds) Then
t = t + 1
PtbIcon.Location = New Point(29, 236)
'resets when you die, sets the score
End If
lblScore.Text = "Your Score Equals" & t
End
Why doesn't this work? Why? Is there a simpler way of checking all of this, such as calling a function which checks the bounds individually?
Use Linq.
Dim t As Integer = 0
PtbIcon.All(Function(pb As PictureBox) As Boolean
' Checking goes here with pb
' Return True if you want to go through all of them
End Function)
lblScore.Text = "Your Score Equals" & t

Convert.ChangeType() Returns incorrect value

I've got a class that parses a CNC file, but I'm having difficulties with trailing "words" on each line of the file.
My code parses all leading "words" until it reaches the final word. It's most noticeable when parsing "Z" values or other Double type values. I've debugged it enough to notice that it successfully parses the numerical value just as it does with "X" and "Y" values, but it doesn't seem to successfully convert it to double. Is there an issue with a character I'm missing or something?
Here's my code:
If IO.File.Exists("Some GCode File.eia") Then
Dim sr As New IO.StreamReader("Some GCode File.eia")
Dim i As Integer = 0
'Read text file
Do While Not sr.EndOfStream
'Get the words in the line
Dim words() As String = sr.ReadLine.Split(" ")
'iterate through each word
For i = 0 To words.Length - 1 Step 1
'iterate through each "registered" keyword. Handled earlier in program
For Each cmd As String In _registeredCmds.Keys
'if current word resembles keyword then process
If words(i) Like cmd & "*" Then
_commands.Add(i, _registeredCmds(cmd))
'Double check availability of a Type to convert to
If Not IsNothing(_commands(i).DataType) Then
'Verify enum ScopeType exists
If Not IsNothing(_commands(i).Scope) Then
'If ScopeType is modal then just set it to True. I'll fix later
If _commands(i).Scope = ScopeType.Modal Then
_commands(i).DataValue = True
Else
'Catch errors in conversion
Try
'Get the value of the gcode command by removing the "registered" keyword from the string
Dim strTemp As String = words(i).Remove(0, words(i).IndexOf(_commands(i).Key) + _commands(i).Key.Length)
'Save the parsed value into an Object type in another class
_commands(i).DataValue = Convert.ChangeType(strTemp, _commands(i).DataType)
Catch ex As Exception
'Log(vbTab & "Error:" & ex.Message)
End Try
End If
Else
'Log(vbTab & "Command scope is null")
End If
Else
'Log(vbTab & "Command datatype is null")
End If
Continue For
End If
Next
Next
i += 1
Loop
Else
Throw New ApplicationException("FilePath provided does not exist! FilePath Provided:'Some GCode File.eia'")
End If
Here's an example of the GCode:
N2930 X-.2187 Y-1.2378 Z-.0135
N2940 X-.2195 Y-1.2434 Z-.0121
N2950 X-.2187 Y-1.249 Z-.0108
N2960 X-.2164 Y-1.2542 Z-.0096
N2970 X-.2125 Y-1.2585 Z-.0086
N2980 X-.207 Y-1.2613 Z-.0079
N2990 X-.2 Y-1.2624 Z-.0076
N3000 X0.
N3010 X12.
N3020 X24.
N3030 X24.2
N3040 X24.2072 Y-1.2635 Z-.0075
N3050 X24.2127 Y-1.2665 Z-.0071
N3060 X24.2167 Y-1.2709 Z-.0064
N3070 X24.2191 Y-1.2763 Z-.0057
N3080 X24.2199 Y-1.2821 Z-.0048
N3090 X24.2191 Y-1.2879 Z-.004
N3100 X24.2167 Y-1.2933 Z-.0032
N3110 X24.2127 Y-1.2977 Z-.0026
N3120 X24.2072 Y-1.3007 Z-.0021
N3130 X24.2 Y-1.3018 Z-.002
N3140 X24.
N3150 X12.
N3160 X0.
N3170 X-.2
N3180 X-.2074 Y-1.3029 Z-.0019
N3190 X-.2131 Y-1.306 Z-.0018
N3200 X-.2172 Y-1.3106 Z-.0016
N3210 X-.2196 Y-1.3161 Z-.0013
N3220 X-.2204 Y-1.3222 Z-.001
N3230 X-.2196 Y-1.3282 Z-.0007
N3240 X-.2172 Y-1.3338 Z-.0004
N3250 X-.2131 Y-1.3384 Z-.0002
N3260 X-.2074 Y-1.3415 Z-.0001
N3270 X-.2 Y-1.3426 Z0.
N3280 X0.
N3290 X12.
N3300 X24.
N3310 X24.2
N3320 G0 Z.1
N3330 Z1.0
N3340 G91 G28 Z0.0
N3350 G90
With regard to the sample CNC code above, you'll notice that X and Y commands with a trailing Z command parse correctly.
EDIT
Per comment, here is a breakdown of _commands()
_commands = SortedList(Of Integer, Command)
Command is a class with the following properties:
Scope as Enum ScopeType
Name as String
Key as String
DataType as Type
DataValue as Object
EDIT: Solution!
Figured out what was wrong. The arrays that make up the construction of the classes were essentially being passed a reference to the "registered" array of objects from the Command class. Therefore every time I parsed the value out of the "word" each line, I was overwriting the DataValue in the Command object.
The solution was to declare a new 'Command' object with every parse and append it to the proper array.
Here's my short hand:
...
For I = 0 To words.Length - 1 Step 1
'iterate through each "registered" keyword. Handled earlier in program
For Each cmd as String in _registeredCmds.Keys
'if current word resembles keyword then process
If words(I) Like cmd & "*" Then
'NEW!!! Declare unassigned Command object
Dim com As Command
' ****** New elongated logic double checking existence of values.....
If _registeredCmds.Keys.Scope = ScopeType.Modal Then
'assign Command object to previously declared variable com
com = New Command()'There's technically passing arguments now to ensure items are transferred
Else
'Parse and pass DataValue from this word
com = New Command()'There's technically passing arguments now to ensure items are transferred
End If
'New sub to add Command object to local array
Add(com)
Continue For
End If
Next
Next
...

Recursively search files for information contained in excel cell and return path

Okedoke... I have an Excel spreadsheet with a filename in column A. The filenames listed in column A appear in one or more text files in one or more source directories.
I need Excel to search the text files recursively and return the path(s) of the file(s) that contain the filename specified in column A into column B. If more than one file go to column C etc.
The Excel sheet would be
__________________________________
__|______A___________|______B_____|
1 | filename.avi | |
2 | another_file.flv | |
The text files to search would be in multiple directories under C:\WebDocs\ and are DokuWiki pages some are quite short, such as this page that would need to be returned
===== Problem Description =====
Reopen a closed bank reconciliation.
===== Solution =====
Demonstration of the tool box routine that allows reposting of the bank rec.
{{videos:bank_rec_reopen1006031511.flv|}}
===== Additional Information -cm =====
You may have noticed that in the video there is a number to the right of the bank account number. In this case it was a 0. That indicates department 0 which is all departments. You get the department 0 if you have all departments combined using the option in the bank set up called "One Bank for All Departments". If this setting is not checked then when you create your starting bank rec for each department you will get a 1 to the right of the bank rec for department 1 and so on. You should normally only have a 0, or have numbers 1 or greater. If you have both, then the method was changed after the initial bank rec was made. You just have to be aware of this as you move forward. As always backup before you make any changes.
There are some other pages though that are quite long that do not contain videos but would be in the directories being searched. Format is the same, plain text, ==== are place holders for headings may contain links to other pages/sites.
I did find an existing VBA script that sort of does what I need it to. It does not recurse and returns too much information, date/time stamp for instance, where all I need is the path.
Private Sub CommandButton1_Click()
Dim sh As Worksheet, rng As Range, lr As Long, fPath As String
Set sh = Sheets(1) 'Change to actual
lstRw = sh.Cells.Find(What:="*", After:=sh.Range("A1"), LookAt:=xlPart, LookIn:=xlFormulas, SearchOrder:=xlByRows, SearchDirection:=xlPrevious, MatchCase:=False).Row
Set rng = sh.Range("A2:A" & lstRw)
With Application.FileDialog(msoFileDialogFolderPicker)
.Show
fPath = .SelectedItems(1)
End With
If Right(fPath, 1) <> "\" Then
fPath = fPath & "\"
End If
fwb = Dir(fPath & "*.*")
x = 2
Do While fwb <> ""
For Each c In rng
If InStr(LCase(fwb), LCase(c.Value)) > 0 Then
Worksheets("Sheet2").Range("C" & x) = fwb
Set fs = CreateObject("Scripting.FileSystemObject")
Set f = fs.GetFile(fwb)
Worksheets("Sheet2").Range("D" & x) = f.DateLastModified
Worksheets("Sheet2").Range("B" & x) = f.Path
Worksheets("sheet2").Range("A" & x) = c.Value
Columns("A:D").AutoFit
Set fs = Nothing
Set f = Nothing
x = x + 1
End If
Next
fwb = Dir
Loop
Set sh = Nothing
Set rng = Nothing
Sheets(2).Activate
End Sub
My attempts at moification so far have generally resulted in a broken script and have thus led me here asking for help.
Thanks,
Simon
Downlaoded the win32 port of the GNU tool grep from http://gnuwin32.sourceforge.net/
Saved the list of video files into a plain text file instead of using a spreadsheet.
grep --file=C:\file_containing video_file_names.txt -R --include=*.txt C:\Path\To\Files >grep_output.txt
The information written to the grep_output.txt file looked like
C:\wiki_files\wiki\pages/my_bank_rec_page.txt:{{videos:bank_rec_reopen1006031511.flv|}}
So there was the path to the file containing the video name and the video name on one line.
Imported the grep_output.txt file into a new Excel workbook.
Used regular formulae to do the following
Split Column A at the "/" to give the path in Column A and the page and video information in Column B
Split the data in in Column B at the ":{{" characters leaving page name in Column B and video information in Column C
Stripped the :{{ and |}} from the front and rear of the string in Column C
From my limited experience, it seems you'd want to perform 4 tasks.
1) Loop through Directories
2) Loop through files per directory (Good idea to keep the filename in a variable)
3) Test the text file for values. Would suggest clear a "scribble sheet", import the file, run a check. e.g.
Sheets("YourScratchPatch").Select
Application.CutCopyMode = False
With ActiveSheet.QueryTables.Add(Connection:="TEXT;" & yourpath & yourfile.txt, Destination:=Range("A1"))
.FieldNames = True
.RowNumbers = False
.FillAdjacentFormulas = False
.PreserveFormatting = True
.RefreshOnFileOpen = False
.RefreshStyle = xlInsertDeleteCells
.SavePassword = False
.SaveData = True
.RefreshPeriod = 0
.TextFilePromptOnRefresh = False
.TextFilePlatform = 850
.TextFileStartRow = 2
.TextFileParseType = xlDelimited
.TextFileTextQualifier = xlTextQualifierDoubleQuote
.TextFileConsecutiveDelimiter = False
.TextFileTabDelimiter = True
.TextFileSemicolonDelimiter = False
.TextFileCommaDelimiter = True
.TextFileSpaceDelimiter = False
.TextFileColumnDataTypes = Array(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1)
.TextFileTrailingMinusNumbers = True
.Refresh BackgroundQuery:=False
End With
4) if values are found, write the file name variable to the index sheet.
I'm sure there should be better (arrays?) ways to do the comparison check as well, but it depends on what's inside the text file (i.e. just one file name?)
More info on the text file structure would be useful. Hope this helps.

Resources