Is it possible to write a script that can also execute the commands which are already in the DigitalMicrograph application menu?
Yes, the command you are seeking is called ChooseMenuItem. It takes three string parameters as input, the full signature is
Boolean ChooseMenuItem( String menu_name, String sub_menu_name, String menu_item_name )
And example (assuming an image is open) would be
GetFrontImage().SelectImage()
ChooseMenuItem( "Analysis", "Statistics", "Sum" )
Note the use of SelectImage in the example because the menu command is only available if an image window is selected!
You may also want to use things below to catch if a given menu item is not accessible. The command ChooseMenuItem returns a Boolean true on success and a false on failure.
string menu = "Analysis"
string submenu = "Special"
string item = "Variance"
If ( !ChooseMenuItem( menu, submenu, item ) )
Throw( "The menu-command " + menu + " / "+ submenu + " / " + item + " was not found!" )
Related
I have a web form of pre populated data which i have to fill. I want to do this with javascript. I am not sure to write the code .
Public Sub ABC()
Dim document As HTMLDocument
Dim bot As New WebDriver
Dim cSCRIPT,m
m=58
bot.Start "chrome", ""
bot.Get "https://XYZ"
cSCRIPT = "document.getElementByXPath("//td[contains(text(),'XXXX')]/following-sibling::td[5]").value='" & m & "'"
bot.ExecuteScript cSCRIPT
But my code do not work. How can I code in selenium VBA with the help of XPath to fill data in Web table.
I can't test this in VBA but have translated from python which worked. I use evaluate to handle the xpath matching.
The function Document.evaluate() has the following definition:
var xpathResult = document.evaluate(
xpathExpression,
contextNode,
namespaceResolver,
resultType,
result
);
The first argument is the xpath expression. Then contextNode is basically the node to apply the xpath to i.e. document in this case. namespaceResolver is null as no namespace prefixes are used (it's an html document). I specify resultType as XPathResult.ANY_TYPE so as to get the natural type from the expression. For result argument I pass null so as to create a new XPathResult.
The return type is object. I use iterateNext to get to the input element and then assign the visual value with input.value = "abc"; and the actual with input.setAttribute('value', 'xyz');.
I am using a testable example but you would amend as per your html which means your xpath would be
//td[contains(text(),'XXXX')]/following-sibling::td[5]/input
VBA:
Dim s As String
s = "var td = document.evaluate(""//tr[contains(td/text(), 'Angelica Ramos')]/td[2]/input"", document, null, XPathResult.ANY_TYPE, null);" & _
"var input = td.iterateNext();" & _
"input.value = 'abc';" & _
"input.setAttribute('value', 'xyz');"
bot.Get 'https://datatables.net/examples/api/form.html'
bot.ExecuteScript s
Python original:
bot.get('https://datatables.net/examples/api/form.html')
s = '''var td = document.evaluate("//tr[contains(td/text(), 'Angelica Ramos')]/td[2]/input", document, null, XPathResult.ANY_TYPE, null);
var input = td.iterateNext();
input.value = 'abc';
input.setAttribute('value', 'xyz');
'''
bot.execute_script(s)
References:
https://developer.mozilla.org/en-US/docs/Web/API/Document/evaluate
https://developer.mozilla.org/en-US/docs/Web/API/Document/evaluate#Result_types
https://javascript.info/object
https://developer.mozilla.org/en-US/docs/Web/API/XPathResult/singleNodeValue
https://developer.mozilla.org/en-US/docs/Web/API/XPathResult/iterateNext
It's tough to debug the XPath without seeing the table and underlying HTML for the webpage, but typically if a table is tough to access, I just use a macro tool like AppRobotic to leverage screen X,Y coordinates of the table to click into it and fill in the necessary info, sometimes navigating using keyboard strokes while in the table works well also:
Set Waiter = CreateObject("Selenium.Waiter")
Set Assert = CreateObject("Selenium.Assert")
Set bot = CreateObject("Selenium.FirefoxDriver")
Set x = CreateObject("AppRobotic.API")
Sub ABC
' Open webpage
bot.Get "https://www.google.com"
' Wait a couple of seconds
x.Wait(2000)
' Type in the Search box
bot.FindElementByName("q").SendKeys "test"
bot.Keys.Return
' Or use coordinates if an element is difficult to find
' Use UI Item Explorer to get X,Y coordinates of Search box and move cursor
x.MoveCursor(438, 435)
' click inside Search box
x.MouseLeftClick
x.Type("test")
x.Type("{ENTER}")
While Waiter.Not(Instr(bot.Title, "test")): Wend
x.MessageBox("Click OK to quit the browser"):
bot.Quit
End Sub
I have over 40 combo controls in my application. I am working on developing a public function, to put in the not in list event of every combo. The goal is to have 1 continuous pop up form, which will open, if the user says they want to add a new value to the combo. The open form command will pass open args for the
record source
the control source for the 1 text box on the continuous form (generically the type)
the label for the control source.
I'm having some trouble getting it to pass the open args. I debug.print the parts of the args, I can split them, when they get passed (inconsistent results getting the open args to pass correctly, as I try to debug), and I cannot seem to set the record source for the pop up form correctly. I've tried doing 1 at a time, and still can't seem to get it.
This is the public function:
Option Explicit
Public Function TypeNotInList(ctl As Control, arg1 As String, arg2 As Variant, arg3 As String)
On Error GoTo Err_TypeNotInList
Dim Msg, Style, Title
'arg1 is the row source of the combo, to be passed as the recordsource for the frmAddTypeVal form
'arg2 is the control source of the combo, to be passed as the control source for the text box in the frmAddTypeVal form
'arg3 is the label of the combo, to be used for messages, and the label of the text box in the frmAddTypeVal form
Msg = "The " & arg3 & " you entered is not in the " & arg3 & " list, would you like to add it now?"
Style = vbYesNo
Title = "Type or listing must be maintained"
Response = MsgBox(Msg, Style, Title)
If Response = vbYes Then
ctl.Undo
DoCmd.OpenForm "frmAddTypeVal", acNormal, , , , acDialog, arg1 & "|" & arg2 & "|" & arg3
ctl.Requery
End If
Exit_TypeNotInList:
Exit Function
Err_TypeNotInList:
MsgBox Err.Description
Resume Exit_TypeNotInList
End Function
This is how I am calling it, in 1 combo's Not In List event:
Option Explicit
Private Sub FKAuditType_NotInList(NewData As String, Response As Integer)
Dim a1 As String
Dim a2 As String
Dim a3 As String
a1 = Me.FKTypeXYZ.RowSource
a2 = "txtXYZType"
a3 = Me.lblTypeXYZ.Caption
TypeNotInList Me.FKTypeXYZ, a1, a2, a3
Response = acDataErrContinue
End Sub
That should be calling the public function, and passing the 4 parameters.
This is the form load of the generic continuous pop-up form, called frmAddTypeVal:
Option Explicit
Private Sub Form_Load()
Dim VarArgs() As String
VarArgs = Split(Me.OpenArgs, "|")
Me.Form.RecordSource = VarArgs(0)
Me.txtType.ControlSource = VarArgs(1)
Me.lblType.Caption = VarArgs(2)
End Sub
When I run this as is, my debug.print (s) give me the following:
ctl = FKFKTypeXYZ
arg1 = SELECT tblXYZType.ID, tblXYZType.txtXYZType FROM tblXYZType ORDER BY tblXYZType.txtXYZType;
arg2 = FKXYZType
arg3 = XYZ Type
openargs =
I get each value, but the open args is null. What the heck, Beck?
Can anyone help guide this clueless coder? lol
Thanks!
I edited this to update the code, with the changes made. Now it's working! At least the first part of the process. The openargs get passed and the pop-up form works correctly. When I click close on that form, I'm back on the form with the notinlist combo. That resumes it's process and I get a message: The text you entered isn't an item in the list.
It know that's the default notinlist message. The thing is, the public function is supposed to handle this. It has, in the if Response = vbYes Then
ctl.undo
'undo trying to add a value that is not in the list yet
and then after the open form (which would involve the close of that form, I would think)
ctl.requery
'requery the combo, so the added value(s) can be seen
Anyone know how I can adjust this to prevent that message, but not just disable all warnings?
Thanks!
Got it! In the not in list, after I call the public function, I have to add:
Response = acDataErrContinue
This let's the default error message take a seat lol.
Thanks for all the help! This is going to make setting this up for every darn combo so much easier!!!!
I'm using a VBA user-form in order to edit some text by using a rich text format textbox from the InkEdit control.
I'm trying to insert html tags in specific location when the user click on a command button on the user-form.
for example if the user clicks the "strong" button the following code is executed and the text is inserted on the cursor location inside the textbox:
InkEdit1.SelText = "<strong>"
I have another button for the closing statment which runs:
InkEdit1.SelText = "</strong>"
I'm trying to find a way that the opening statement ans the closing statement will be applied together. When the user will select a text from the text box and click the button then "strong" will be inserted before the selection and "/strong" will be inserted after the selection:
Does this work:
InkEdit1.SelText = "<strong>" & InkEdit1.SelText & "</strong>"
If you really want to get fancy, you can reselect just the original text:
Dim lPos As Long
lPos = InkEdit1.SelStart
Dim lLength As Long
lLength = InkEdit1.SelLength
InkEdit1.SelText = "<strong>" & InkEdit1.SelText & "</strong>"
InkEdit1.SelStart = lPos + Len("<strong>")
InkEdit1.SelLength = lLength
Protip: Make sure the "HideSelection" property is set to "False"
If you're not using an actual RitchTextBox, try this: Toos > Additional Controls > check Microsoft Rich Textbox
How do you bundle an applescript that has a main script which is reading scripts randomly from a folder?
Check out this code: http://macosxautomation.com/applescript/linktrigger/index.html.
It's doing exactly that (besides other things) and you can use the sub-routine there for the script-handling.
Here is a full script that works when you follow these steps: save it as an application and put all your scripts into the "Resources" folder of that application (as described at the webpage, "Show Package Contents"). Good Luck.
property MyUserName : ""
if MyUserName is "" then
display dialog "User Name:" default answer "" buttons {"Cancel", "Continue…"} default button 2
copy the result as list to {returnedButton, returnedText}
if returnedButton is "Cancel" then return
-- What to do when the user did not input any text?
if returnedText is "" then return -- we stop.
set MyUserName to returnedText
say "Hello," & MyUserName & "!" using "Karen"
else
display dialog "User name: " & MyUserName buttons {"Ok"} default button 1 with icon 1 giving up after 10
end if
say "For your information, please start the Amuse App everytime you log on... and I will speak to you at random times during your visit with me." using "Karen"
delay 20
try
repeat 105 times
set rnd to (random number from 1 to 105)
set rndFileName to (rnd as text) & ".scpt"
if my run_scriptfile(rndFileName) is false then -- if the script execution fails,…
error number -128 -- … stop this app
end if
end repeat
on error the error_message number the error_number
display dialog "Error: " & the error_number & ". " & the error_message buttons {"OK"} default button 1
return
end try
on run_scriptfile(this_scriptfile)
-- This handler will execute a script file
-- located in the Resources folder of this applet
try
set the script_file to path to resource this_scriptfile
return (run script script_file)
on error
return false
end try
end run_scriptfile
This is how it looks with (only) 3 of the scripts you wanna randomly execute:
Your question is clear but here's an script that loads randomly a script from a folder, if the folder contains any.
set theFolder to choose folder as string
set theFiles to do shell script "ls " & quoted form of posix path of theFolder & " | grep '.scpt$' || true"
if theFiles = "" then return
set theFile to some item of (paragraphs of theFiles)
set randomScript to load script file (theFolder & theFile)
I have a series of HTTP links stored in the database the have a named tag as part of the link (e.g. http://somecompany.com/products#123332) which represents a product 123332 in a rather large page.
The above link works fine when using IE but doesn't work with Chrome. The # character gets converted to %23 and Chrome can't find the ref. Changing the %23 back to # in the browser's address field works correctly.
The link is stored in a standard VB String and I've tried replacing the # with different values via String.Replace(). There must be a proper way to encode this correctly, I just can't seem to find any references on the web that seem to work.
A simplified example of the call would be something like:
Shell(strBrowser & strLink)
where strBrowser contains all the necessary path and exe name and the strLink is a string similar to what I mentioned above. Also as mentioned it works fine with IE. How can I go about encoding this correctly?
Thanks.
The code
If oFichierAide.LienIntern = 1 Then
strLink = " " + Chr(34) + VarGlobales.EmplacementAppl + oFichierAide.LienFichier + Chr(34)
Else
strLink = " " + Chr(34) + oFichierAide.LienFichier + Chr(34)
End If
Try
regBrowserKey = My.Computer.Registry.ClassesRoot.OpenSubKey("HTTP\shell\open\command", False)
strBrowser = regBrowserKey.GetValue(Nothing).ToString().ToLower().Replace(Chr(34), "")
strBrowser = strBrowser.Substring(0, strBrowser.LastIndexOf(".exe") + 4)
Finally
If regBrowserKey IsNot Nothing Then
regBrowserKey.Close()
End If
End Try
If strBrowser.Length > 0 And strLink.Length > 1 Then
Dim strCall As String = strBrowser + strLink
Shell(strCall, AppWinStyle.NormalFocus, False)
Return True
End If
You can open any chrome window to any URL stored with a string variable via Visual Basic by doing:
Dim appData As String = GetFolderPath(SpecialFolder.ApplicationData)
Dim chromelocation = appdata + "\Local\Google\Chrome\Application\chrome.exe"
process.start(chromelocation + strLink)
Chrome should then open up and the address it goes to should be the contents of strLink.