Splitting String into Array Errors - arrays

Trying to write a script that will be run in WinPE, that essentially gets the IP address of the localhost and chooses an action based on the IP range.
In Windows, the script runs flawlessly. However, in WinPE, I'm getting the following error:
script.vbs(1,1) Microsoft VBScript runtime error: Subscript out of range
Google-fu is telling me that has something to do with my array being outside of the range. Here I thought I had a decent understanding, but apparently not.
Code that works as is on Windows:
Option Explicit
Dim sIP, sHostname,sPingBat
Dim aIP
Dim iOct1, iOct2, iOct3, iOct4, iReturn
Dim oWMIService, oCmd, oAdapter
Dim cAdapters
iReturn = 999
sHostname = "."
Set oWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & sHostname & "\root\cimv2")
Set cAdapters = oWMIService.ExecQuery("Select IPAddress from Win32_NetworkAdapterConfiguration Where IPEnabled = True")
Set oCmd = CreateObject("Wscript.Shell")
For Each oAdapter in cAdapters
If Not IsNull(oAdapter.IPAddress) Then
sIP = Trim(oAdapter.IPAddress(0))
Else
iReturn = 404
WScript.Quit iReturn
End If
Next
sIP = CStr(sIP)
aIP = Split(sIP, ".")
iOct1 = CInt(aIP(0))
iOct2 = CInt(aIP(1))
iOct3 = CInt(aIP(2))
iOct4 = CInt(aIP(3))
Now, if I change the declaration of the aIP array to either of the following:
aIP()
aIP(4)
and run
aIP = Split(sIP, ".")
I get
script.vbs(26, 1) Microsoft VBScript runtime error: Type mismatch
Changing the array assignment / split line to
aIP() = Split(sIP,".")
results in
script.vbs(26, 1) Microsoft VBScript runtime error: Subscript out of range
So I'm obviously doing something wrong.
It's also entirely possible that my original error message is completely unrelated to my array range, and WinPE just doesn't like my script (in which case, if anybody has any pointers, it'd be appreciated)
At the moment, I'm mounting my wim to get the install packages to make sure the WMI and Scripting packages are installed from the ADK.

There is nothing wrong with the code except the assumption being made about what Win32_NetworkAdapterConfiguration returns.
From MSDN - Win32_NetworkAdapterConfiguration class
Array of all of the IP addresses associated with the current network adapter. This property can contain either IPv6 addresses or IPv4 addresses. For more information, see IPv6 and IPv4 Support in WMI.
Because sIP could contain an IPv6 address the Split() will not work as expected. IPv6 addresses don't contain . as a separator so Split() will return a Array containing the original string as the first index only. Hence attempting to read anything other then aIP(0) will cause an
Microsoft VBScript runtime error:
Subscript out of range
error.
To avoid this use InStr() to check for the existence of . in the sIP variable first, you will also need to iterate through the oAdapter.IPAddress array to check each address to get the correct one, you can't assume IPAddress(0) will always be the right one.
Try this
Dim ips, ip
For Each oAdapter in cAdapters
ips = oAdapter.IPAddress
If IsArray(ips) Then
For Each ip In ips
If InStr(1, ip, ".") > 0 Then
sIP = Trim(ip)
Exit For
End If
Next
If Len(sIP) > 0 Then Exit For
Else
iReturn = 404
WScript.Quit iReturn
End If
Next
Untested on iPad sorry

I guess sIP variable contains some string which can not be splitted wity delimiter "."(ex: "somestringwithNoDOT")
So in the 1st case
aIP = Split(sIP,".") ' Split("somestringwithNoDOT",".")
statement returned only 1 string, which can not be coverted to Integer. So i returned Type mismatch error in below line
iOct1 = CInt(aIP(0)) ' returns Type mismatch error
In the 2nd case
aIP() = Split(sIP,".") ' Split("somestringwithNoDOT",".")
above statement will return 1 element, but aIP is array with NO elements. So this statement rturned "Subscript out of range" error
Resolution for this issue is to check whether correct value is passing to sIP

Related

How can I use a table in LUA for pinging multiple devices and detecting change in variable status

I am trying to ping a number of IP address on a local network at defined intervals and then send a message only when a device connects. I have managed to get it to work for a single device, but when I add additional devices to the table the code fails.
Many thanks in advance.
An earlier version without the table and just a single IP address works perfectly. But adding the table and the "for key,value loop" only works if a single entry is in the table.
local tble = {
["device name"] = "192.168.1.204"
}
for key,value in pairs(tble) do
statuscheckIP=os.execute("arping -f -w 3 " .. value)
if statuscheckIP ~= lastcheckIP then
if statuscheckIP == 0 and lastcheckIP == 256 then
subject ="" ..key.. " , ( IP Address " ..value.. ") Connected"
message = "Connection Alert\nThe device named " ..key.. ", with the IP address " ..value.. " has just connected to the WiFi network"
--send email notification
luup.call_action("urn:upnp-org:serviceId:SmtpNotification1", "SendEmail", { Recipient_Name="SomeOne", Recipient_eMail="someone#somewhere.com", Subject= subject, Message=message }, 24)luup.call_action("urn:upnporg:serviceId:SmtpNotification1","ResetCount",{}, 24)
else
end
end
end
lastcheckIP = statuscheckIP
The code you posted is valid. There are not many reasons why this would fail due to more entries in your table.
os.execute Execute an operating system shell command. This is like the C system() function. The system dependent status code is returned.
Running os.execute will start a arping and return an exitcode. Then you are comparing that statuscheckIP == 0 a lastcheckIP == 256. The if before is redundant. If true you are sending your message and continuing.
After worked though all entries you are setting lastcheckIP to statusCheckIP and this is propably your error. It should be before the last if and inside your loop. But even then does not make sense if 0 is the only correct return code. If lastcheckIP is set to any other value your both if's will never go true again.
Either your last line lastcheckIP = statuscheckIP is wrongly placed, lastcheckIP was never initialized to 256 or you should rethink your whole program.
EDIT:
After understanding the intention of the provided program, I've created a probably working example. This should show you, how to easily use tables in Lua as a structures. I was not able to test the following code.
local WAIT_TIME = 10
local STATUS_CODE_CONNECTED = 0
local STATUS_CODE_NOT_CONNECT = 256 -- not sure about this (return code from arping for failure)
local device_table =
{
["device_name1"] =
{
ip = "<ip address>",
status_code = STATUS_CODE_NOT_CONNECT
},
["device_name1"] =
{
ip = "<ip address>",
status_code = STATUS_CODE_NOT_CONNECT
}
-- , ...
}
while true do
-- check for changed return codes
for device_name, device in pairs(device_table) do
local temp_status_code = os.execute("arping -f -w 3 " .. device.ip)
-- status code changed
if temp_status_code ~= device.status_code then
-- device connected
if temp_status_code == STATUS_CODE_CONNECTED then
local subject = "" .. device_name .. " , ( IP Address " .. device.ip .. ") Connected"
local message = "Connection Alert\nThe device named " .. device_name .. ", with the IP address " .. device.ip .. " has just connected to the WiFi network"
--send email notification
luup.call_action(
"urn:upnp-org:serviceId:SmtpNotification1",
"SendEmail",
{
Recipient_Name = "SomeOne",
Recipient_eMail = "someone#somewhere.com",
Subject = subject,
Message = message
}, 24)
luup.call_action(
"urn:upnporg:serviceId:SmtpNotification1",
"ResetCount",
{ }, 24)
end
-- update last device status_code if changed
device.status_code = temp_status_code
end
end
os.execute("sleep " .. tonumber(WAIT_TIME)) -- wait some time for next check
end
If I've understand you wrongly and you either do not want to have this program run all the time or do not want to have all addresses in a table then you should ask again or somewhere else because that would be out off topic.

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
...

Creating an array of strings

I'm having a few problems with the following:
Dim design(6) As String
design(0) = "DES1"
design(1) = "DES1_slot"
design(2) = "DES2"
design(3) = "DES2_slot"
design(4) = "DES3"
design(5) = "DES3_slot"
I get the error "Expected end of statement"
Similarly:
Dim design(0 To 5) As String
design(0) = "DES1"
design(1) = "DES1_slot"
design(2) = "DES2"
design(3) = "DES2_slot"
design(4) = "DES3"
design(5) = "DES3_slot"
says "Expecting ')' "
I don't often use VBA, but from the quick googling I did at least one of these should work?
Thats perfectly valid VBA however you will get those exact errors in VBScript which is what I presume your using.
As VBScript is typeless change the first line to just:
Dim design(5)

dbWriteTable in RMySQL error in name pasting

i have many data.frames() that i am trying to send to MySQL database via RMySQL().
# Sends data frame to database without a problem
dbWriteTable(con3, name="SPY", value=SPY , append=T)
# stock1 contains a character vector of stock names...
stock1 <- c("SPY.A")
But when I try to loop it:
i= 1
while(i <= length(stock1)){
# converts "SPY.A" into SPY
name <- print(paste0(str_sub(stock1, start = 1, end = -3))[i], quote=F)
# sends data.frame to database
dbWriteTable(con3,paste0(str_sub(stock1, start = 1, end = -3))[i], value=name, append=T)
i <- 1+i
}
The following warning is returned & nothing was sent to database
In addition: Warning message:
In file(fn, open = "r") :
cannot open file './SPY': No such file or directory
However, I believe that the problem is with pasting value onto dbWriteTable() since writing dbWriteTable(con3, "SPY", SPY, append=T) works but dbWriteTable(con3, "SPY", name, append=T) will not...
You are probably using a non-base package for str_sub and I'm guessing you get the same behavior with substr. Does this succeed?
dbWriteTable(con3, substr( stock1, 1,3) , get(stock1), append=T)

Resources