I am trying to write a LotusScript to control a motor. The script I have for reading the bits seem to work fine, but I wish to add a stop button. I have all the commands for making the device stop, but the trouble I'm having is that whenever LotusScript is running through a loop, I cannot click on any of the other buttons.
Does anyone know a way around this???
The scripts I am using are below.
Thank-you kindly.
Andy Barlow
Sub readpositionsub
Dim send_string As String
Dim readString As String
Dim tempString As String
readString = ""
REM Sets the "movement" cell to 6 (the movement int)
[b1].contents = "6"
Do While [b1].contents <> "7"
readString = ""
statusBitString = ""
REM READ STATUS ===!!!===
REM Open the handle to the motor
handle = init_RS232(19200)
REM #1$ reads the status from the controller.
send_string = "#1$"+Chr$(13)
REM Ask the controller to store the results in bits
resultStatus=write_RS232 (handle,send_string)
REM Read Status by looping through all of the bits
For n=0 To 8
tempString = "*1234567"
sendReadCommand = read_RS232(handle,tempString)
If Mid(tempString,1,1) = Chr$(13) Then
Exit For
Else
statusBitString = statusBitString + Mid(tempString,1,1)
End If
Next
[b1].contents = Mid(statusBitString,7, 1)
close_RS232(handle)
REM End Read Status
REM READ POSITION ===!!!===
REM Open the handle to the motor
handle = init_RS232(19200)
send_string = "#1C"+Chr$(13)
t=write_RS232 (handle,send_string)
REM Reading Position
For n=0 To 20
tempString = "*1234567"
r = read_RS232(handle,tempString)
If Mid(tempString,1,1) = Chr$(13) Then
Exit For
Else
readString = readString + Mid(tempString,1,1)
End If
Next
REM End Read Position
[a1].contents=Mid(readString, 4)
close_RS232(handle)
Loop
End Sub
And the stop button that should work should be...
Object btnStop
Sub Click(Source As Buttoncontrol)
REM initialise
handle = init_RS232(19200)
REM Create the string for starting the motor
send_string = "#1S"+Chr$(13)
REM Send the string for starting the motor
resultStartMotor=write_RS232 (handle,send_string)
REM Close the spin handle
close_RS232(handle)
End Sub
You're not running your Lotusscript in a threaded environment, so how do you expect the code on a button to stop the code already running?
If you want to be able to cancel a loop you need to play with the timer object. Basically you start a time that executes one iteration of your loop. At the beginning you look for a changed field value or an ini variable to cancel the timer if set. Now you can use your button to set that variable.
The loop will run much slower than without a timer (after all it has a wait interval you set)
Related
I have a script that has a GUI and I have been running with a start button using the below code:
Case $StartButton
I would also like to try scheduling this using Windows TaskScheduler to run every morning at 8 AM EST. What would be the best way to add a condition to either start with the start button OR when TaskScheduler runs at 8 AM EST (or any specific time)? I am hesitant to just do 8 AM condition as it may increase processing a lot always looking at the time.
Essentially what I am looking to have happen is for my computer to auto-unlock (login?) using task scheduler and run this AutoIt script which has been compiled to exe.
FilePath is: C:\Users\robert\OneDrive\Desktop\TempFile.exe
Block of relevant code is below:
While 1
$nMsg = GUIGetMsg()
Switch $nMsg
Case $GUI_EVENT_CLOSE
Exit
Case $Save
SaveOptions()
Case $StartButton
;TAB1 of GUI
If WinExists("[CLASS: QT373947473845]") Then
$oBlah = WinGetHandle("[CLASS: QT373947473845]")
$BSLoc = WinGetPos ("[CLASS: QT373947473845]")
If $BSLoc[0] <> 0 or $BSLoc[1] <> 0 or $BSLoc[2] <> 800 or $BSLoc[3] <> 600 Then
WinSetState ( $oBlah, "", #SW_MINIMIZE )
sleep(500)
WinActivate($oBlah)
WinWaitActive($oBlah)
WinMove($oBlah, "", 0, 0, 800, 600)
sleep(2000)
Else
WinActivate($oBlah)
WinWaitActive($oBlah)
sleep(2000)
EndIf
Endif
EndSwitch
WEnd
I have thousands of lines of other code within the case but I tried to limit it as that portion is irrelevant
The Case $StartButton is the line where I am trying to do an OR if run by TaskManager. I have read you cannot do an OR function within a switch case but if you do 2 cases without a break it is the same thing?
I read some documentation and saw I can add a “/prim1=value” to the end of the command line and it will pass the prim1 argument to $CmdLine[0] but I can’t seem to get it working properly.
Review the documentation.
Particularly this part:
So if you were to use the compiled executable by passing commandline
parameters:
myProg.exe param1 "This is a string parameter" 99
$CmdLine[0] ; this equals 3 (because there are 3 command line parameters)
$CmdLine[1] ; This contains "param1".
$CmdLine[2] ; This contains "This is a string parameter".
$CmdLine[3] ; This contains 99.
So then just modify the code so that it behaves differently if $CmdLine[1] = something.
As for the switch case: that is inside of a message loop for the GUI and the code in the Case $StartButton part of the switch block is run when the start button is pressed and $nMsg is equal to the control ID of the start button ($StartButton).
If you want to run this code at some other time what I would do it just move all of that code into its own function:
Func onStartClick()
; start button code here
Endfunc
And then just call onStartClick() in the switch block:
$nMsg = GUIGetMsg()
Switch $nMsg
Case $StartButton
onStartClick()
Case $someOtherButton
; someOtherButton code...etc
EndSwitch
And then you can also call this function if there is a particular command line param (place this code before the Switch...EndSwitch block, not inside it):
If $CmdLine[0] >= 1 And $CmdLine[1] = "param1" then
; other code to run when started with "program.exe param1"
onStartClick()
EndIf
So the entire thing would look like this:
Func onStartClick()
; start button code here
Endfunc
If $CmdLine[0] >= 1 And $CmdLine[1] = "param1" then
; other code to run when started with "param1"
onStartClick()
EndIf
$nMsg = GUIGetMsg()
Switch $nMsg
Case $StartButton
onStartClick()
Case $someOtherButton
; someOtherButton code...etc
EndSwitch
I'm getting a error message in a VB6 .exe file running on Windows XP.
I compile and "make it" on Windows 7/8, but always get an Overflow error message when it executes this two lines on XP:
sUrl = "C:\Arquivos de Programas\Internet Explorer\IEXPLORE.EXE http://example.com/WebForms/send.aspx?id=" & intCodID & "&type=500&usr=" & intCodUser
openWeb = Shell(sUrl, vbMaximizedFocus)
sUrl is a String and OpenWeb is actually a Integer, but I already declared it as Double and as nothing (just Dim OpenWeb) and still get the overflow error.
UPDATE
Didn't managed to find out what was happening there, but another solution for calling IE:
Dim IE
sUrl = "http://www.google.com/"
Set IE = CreateObject("InternetExplorer.Application")
IE.Visible = True
IE.Navigate sUrl
While the VB6 documentation says Shell() returns a Variant Double... that appears to be obsolete information left over from manuals for earler versions of VB. Instead if you check the typelib info (i.e. look in the IDE's Object Browser) it actually returns a Double type result value.
As far as I can tell Shell() is a wrapper around a call to the WinExec() function.
The returned values are:
0 The system is out of memory or resources.
ERROR_BAD_FORMAT = 11 The .exe file is invalid.
ERROR_FILE_NOT_FOUND = 2 The specified file was not found.
ERROR_PATH_NOT_FOUND = 3 The specified path was not found.
or a Process ID
Also contrary to the documentation, Shell() turns those error values into exceptions ("File not found", "Invalid procedure call or argument," etc.). So if the call succeeds you always get back a PID value.
In all cases this is a DWORD. So it always fits in a Double without the possibility of an overflow. If you are seeing an overflow there is something else going wrong in your code.
Sadly a Double isn't particularly useful here, though it can at least hold the entire range of values. But you'd normally want to carefully convert it to a Long value:
Option Explicit
Function DDoubleToDLong(ByVal DDouble As Double) As Long
'Some functions like the intrinsic Shell() return a Double
'to get around the lack of a UI4 type (DWORD, i.e. unsigned
'Long) in VB. Of course this isn't clean to pass to API
'calls, making it sort of worthless so we need to do a type
'conversion such as this:
If DDouble > 2147483647# Then
DDoubleToDLong = CLng(DDouble - 2147483648#) Or &H80000000
Else
DDoubleToDLong = CLng(DDouble)
End If
End Function
Private Sub Form_Load()
Dim DD As Double
Dim DL As Long
AutoRedraw = True
Font.Name = "Courier New" 'Or other handy monospaced font.
Font.Size = 12#
DD = 0#: DL = DDoubleToDLong(DD): Print DD, DL, Hex$(DL)
DD = 1#: DL = DDoubleToDLong(DD): Print DD, DL, Hex$(DL)
DD = 2147483647#: DL = DDoubleToDLong(DD): Print DD, DL, Hex$(DL)
DD = 2147483648#: DL = DDoubleToDLong(DD): Print DD, DL, Hex$(DL)
DD = 4294967295#: DL = DDoubleToDLong(DD): Print DD, DL, Hex$(DL)
End Sub
Integer is worthless since overflows will be common. Long without the conversion could cause overflows now and then. String is just silly.
You also need to quote the values for the EXE and its arguments property, as in:
Option Explicit
Function DDoubleToDLong(ByVal DDouble As Double) As Long
If DDouble > 2147483647# Then
DDoubleToDLong = CLng(DDouble - 2147483648#) Or &H80000000
Else
DDoubleToDLong = CLng(DDouble)
End If
End Function
Private Sub Form_Load()
Dim sUrl As String
Dim PID As Long
sUrl = """C:\Arquivos de Programas\Internet Explorer\IEXPLORE.EXE"" " _
& """http://example.com/WebForms/send.aspx?id=" _
& intCodID _
& "&type=500&usr=" _
& intCodUser _
& """"
PID = DDoubleToDLong(Shell(sUrl, vbMaximizedFocus))
End Sub
Even this isn't quite "right" since exception handling should be added. And both intCodID and intCodUser may require "cleansing" (UrlEncoding) depending on what types they are and what values they really have. These might be Integers based on the names, with you relying on implicit String coercion? If so they might be Ok.
BTW, as we see above special folder names get localized. For that matter the system drive might not even be C:\ at all! So such paths should never be hard-coded but instead be built up based on values returned from calls to Shell32 to look up the special folder.
An integer can only be a whole number. No decimals.
You say it's declared as an integer therefore you cannot assign 1. anything, and you certainly can't assign anything like that to a number variable as it's not a valid number anyway as it has two decimal points.
You need to declare it as string.
I've been making a script for school, but I've encountered a few problems...
This if my script ">" shows the error.
Complete error:
Line: 26
Char: 14
Error: Syntax Error
' Macro starter script -- basically for any teachers or students to understand and or improve my script.
'oShell.AppActivate("Paint"); // Set focus to a program
'WScript.Sleep(500); // Delay for 1/2 second
'oShell.Run("notepad c:\\temp\\somefile.txt", 1, false); // launch a program
'----------------------------- can add ,2 to run minimized, true=wait for exit
'oShell.SendKeys("%F"); // Alt+F ----- SendKeys strings to jog my memory
'oShell.SendKeys("^C"); // Ctrl+C
'oShell.SendKeys("{ENTER}"); // Send Enter key (also tilde {~} )
'oShell.SendKeys("{{TAB} 2"); // Send Tab key twice )
'oShell.SendKeys(" "); // Send a space
'var nResult= oShell.Popup("Do you want to continue?", 0, "My Macro", 4+32 );
'if ( nResult==6 ) { // 6=Yes, 7=No,
' WScript.Echo( "you said 'Yes!'" );
'}
'WScript.Echo( "done!" );
'Script Starts Here
var oShell = WScript.CreateObject("WScript.Shell")
WScript.Echo( "Script made by Joshua Hughes" )
var sResult = oShell.Popup("Do you want to save all work and shut down?", 0, "Shutdown", 4+32)
>if ( sResult==6 ) {
WScript.Echo( "Starting, do not press any buttons or click!" )
oShell.AppActivate("Word");
WScript.Sleep(500);
oShell.SendKeys("^S");
oShell.SendKeys("{ENTER}");
WScript.Sleep(500);
oShell.SendKeys("%F4")
oShell.AppActivate("Notepad");
WScript.Sleep(500)
oShell.SendKeys("^S");
oShell.SendKeys("{ENTER}");
WScript.Sleep(500);
oShell.SendKeys("%F4")
oShell.AppActivate("Powerpoint");
WScript.Sleep(500)
oShell.SendKeys("^S");
oShell.SendKeys("{ENTER}");
WScript.Sleep(500);
oShell.SendKeys("%F4")
oShell.AppActivate("Paint");
WScript.Sleep(500)
oShell.SendKeys("^S");
oShell.SendKeys("{ENTER}");
WScript.Sleep(500);
oShell.SendKeys("%F4")
end
]
WScript.Echo( "Program Complete! Shutting Down..." )
'Script Ends Here
The story:
I had finished my assessment, an E-Zine, for grade eight at my high school, and I've been fiddling with code, I managed to make a visual basic script save all files, close it, then shutdown, the script only worked for notepad though.Since I've gotten home today, I've been expanding the script, and adding in a bit more, such as the classic 'Are you sure' prompt. But my computer is disagreeing...
I added that because it said:
'It looks like your post is mostly code; please add some more details.'
>if ( sResult==6 ) {
'...
end
]
is not VBScript. Proper syntax is
If sResult = 6 Then
'...
End If
I am using the functions below.In the first one i have parsed the node of xml and its value using MSXML. similar func fr other xml.i want to use two nodevalues and highlight it.i tried something.but i am getting error in the line highlighted(**) as 'Object Required'.your quick reply will help me more.
Public Sub DisplayNode1(ByRef Nodes1 As MSXML2.IXMLDOMNodeList, _
ByVal Indent1 As Integer)
some lines
RichTextBox2.Text = Space$(Indent) & xNode1.ParentNode.nodeName & _
":" & xNode1.NodeValue
difference
some lines
Public Sub difference()
Dim a As IXMLDOMText
Dim b As IXMLDOMText
a.NodeValue = xNode.innertext 'i get erroe in line
b.NodeValue = xNode1.innertext
If StrComp(a, b) > 0 Then
a = vbRed
b = vbRed
End If
please help me soon.
There is a lot that is potentially wrong with this.
xnode isn't declared anywhere in your code sample
Neither a, b, or xnode are explicitly set anywhere in your code sample
Unless xnode is a form/module/global level variable then it will be out of scope in the Difference procedure
It's not shown but I'm guessing that you don't have Option Explicit set in your code or by default
You'll need to address these points first before you can get anywhere with this code.
I have added the following fine function to my status bar to show which function is currently being edited in C-derived languages:
set statusline+=%{WhatFunctionAreWeIn()}
fun WhatFunctionAreWeIn()
let strList = ["while", "foreach", "ifelse", "if else", "for", "if", "else", "try", "catch", "case"]
let foundcontrol = 1
let pos=getpos(".") " This saves the cursor position
let view=winsaveview() " This saves the window view
while (foundcontrol)
let foundcontrol = 0
" Go to the character before the last open {
normal [{
call search('\S','bW')
" If the character is a ) then go to the character
" preceding the () section
let tempchar = getline(".")[col(".") - 1]
if (match(tempchar, ")") >=0 )
normal %
call search('\S','bW')
endif
let tempstring = getline(".")
for item in strList
if( match(tempstring,item) >= 0 )
let foundcontrol = 1
break
endif
endfor
if(foundcontrol == 0)
call cursor(pos)
call winrestview(view)
return tempstring
endif
endwhile
call cursor(pos)
call winrestview(view)
return tempstring
endfun
However, after a few minutes VIM hangs. Disabling the function prevents the hang, so I feel confident that this function is to blame. Is there anything in there that might hang VIM? Is there a better way to accomplish the task of showing the currently-edited function in the status bar?
Thanks.
The issue is that your strategy for determining whether to keep moving to surrounding braces is too aggressive:
Suppose your cursor is on the f in a preprocessor directive #endif between two functions.
Since you're between two functions, there is no unmatched { for [{ to jump to, so the cursor doesn't move.
Your match() against strList hits the if in #endif, causing the loop to continue.
The loop never exits.
I suspect a ctags-based approach, like #Gowtham suggests, will work better, even if it requires some customization.