I'm experimenting with on and end statements in AppleScript.
Consider the following script.
set mytext to "Hello, World"
on greeting(mytext)
display dialog mytext default answer ""
set othertext to text returned of result
end greeting
greeting(mytext)
say othertext
I want to carry over the variable mytext into greeting and I know I can do that by placing mytext in between parentheses after greeting. However, I want to carry over a variable set in the greeting statement, othertext, to the rest of the code.
In the end, I want the script to set othertext to whatever is entered in the text box, and after greeting the script says othertext. I tried putting othertext in between parentheses after end greeting but that doesn't work.
You can return as many variables as you wish from a handler by returning either a list (in the example below) or a record. As long as you know how to find what you want, it works splendidly.
set mytext to "Hello, World"
on greeting(mytext)
display dialog mytext default answer ""
return {(text returned of result), "Another Variable"}
end greeting
set othertext to greeting(mytext)
say othertext's item 1
set mytext to "Hello, World"
on greeting(mytext)
display dialog mytext default answer ""
return text returned of result
end greeting
set othertext to greeting(mytext)
say othertext
Edited to add:
set mytext to "Hello, World"
on greeting(mytext)
display dialog mytext default answer "" buttons {"Yes", "No", "Maybe"}
return {text returned of result, button returned of result}
end greeting
set {othertext, chosenaction} to greeting(mytext)
Related
Is there any way to search only the first line of a Multiline Textbox without knowing exactly at what position the text is you're looking for?
If I knew the position of the text I was looking for I could do something like:
Dim myNotes As String = "The book has a lot of text"
Dim myText As String = "text"
If Not myNotes.Substring(0,4) = myText Then
' Do Something
End If
Or if I wanted to search the entire textbox I could do something like:
Dim myNotes As String = "The book has a lot of text"
Dim myText As String = "text"
If Not myNotes.Contains(myText) Then
' Do Something
End If
But I want to search only the first line of the textbox and I'm not sure at what position the text may be. Is there anyway to do a search like that?
This is another example of why you should ALWAYS read the relevant documentation. If you had read the documentation for the TextBox class then you'd know that it has a Lines property. To get the first line of text, you simply get the first element of that array:
Dim firstLine = myTextBox.Lines(0)
If Not filrstLine.Contains(myText) Then
'Do something
End If
Note that this only applies where the user has explicitly added a line break to the text. I assume that that is what you want, given that you have accepted another answer that does the same thing. If you mean the first line based on automatic word-wrap then that requires a bit more effort.
You could take the text and extract the first line.
int pos = text.IndexOfAny('\r', '\n');
if (pos >= 0)
text = text.SubString(0, pos);
// text now contains only the first line
Then you can search the resulting string.
everybody, I am trying to make the user enter the name of the movie they want subtitles for and the for apple script to automatically search the subtitle website for the name of the movie they inputted.
To do this all of the spaces in the movie name need to be replaced to the + sign because urls convert spaces to the + sign. The code is not working an im getting the following errors:
Expected “end” but found “on”.
A “(” can’t go after this identifier.
Here is my code;
on run
display dialog "What's the name of the movie?" default answer " " with title "What's the name of the movie?" buttons {"OK"} default button 1
set moviename to text returned of the result
set theText to moviename
set theSearchString to " "
set theReplacmentString to "+"
end findAndReplaceInText(theText, theSearchString, theReplacementString)
set AppleScript's text item delimiters to theSearchString
set theTextItems to every text item of theText
set AppleScript's text item delimiters to theReplacementString
set theText to theTextItems as string
set AppleScript's text item delimiters to ""
return theText
end findAndReplaceInText
goToWebPage("https://rs.titlovi.com/prevodi/?prevod= & thetext")
tell application "Safari"
activate
set URL of document 1 to theWebPage
end tell
end goToWebPage
end run
Thank you in advance.
Functions (handlers, in AppleScript speak) may not be nested in AppleScript. So you need to either move findAndReplaceInText and goToWebPage outside of on run, or merge their functionality into on run without using handlers.
Handlers begin with on handlerName and end with end handlerName; you have findAndReplaceInText beginning and ending with end findAndReplaceInText.
Here’s how it might work after separating the handlers:
on run
display dialog "What's the name of the movie?" default answer " " with title "What's the name of the movie?" buttons {"OK"} default button 1
set moviename to text returned of the result
set moviename to findAndReplaceInText(moviename, " ", "+")
goToWebPage("https://rs.titlovi.com/prevodi/?prevod=" & moviename)
end run
on findAndReplaceInText(thetext, theSearchString, theReplacementString)
set AppleScript's text item delimiters to theSearchString
set theTextItems to every text item of thetext
set AppleScript's text item delimiters to theReplacementString
set thetext to theTextItems as string
set AppleScript's text item delimiters to ""
return thetext
end findAndReplaceInText
on goToWebPage(theWebPage)
tell application "Safari"
activate
set URL of document 1 to theWebPage
end tell
end goToWebPage
I’ve verified this code in Safari on Mac OS X 10.14.6.
I want to update a word field content using VBA. I already have a code that works, but I have to refer to the field's index instead of field's name, which I would prefer.
The code I have is as follows:
Sub UpdateField()
Dim myString As String
myString = "asdf"
ActiveDocument.Fields(1).Result.Text = myString
End Sub
Suppose that the field's name is MyField1. The following code will not work (I get the Run-time error '13': Type mismatch'.
Sub UpdateField()
Dim myString As String
myString = "asdf"
ActiveDocument.Fields("MyField1").Result.Text = myString
End Sub
I create my word fields from File Menu > Informations > Advanced Properties > Custom Tab.
So, how to refer to the field's name when we want to update its content?
These are DocProperty fields. If you press Alt+F9 you'll see the field codes.
A DocProperty field references (links to) a Document Property. The Document Property has the name, but this does not "name" the field. Nor is it possible to update a DocProperty field directly since it links to the Document Property. It might be possible to make it temporarily display something else, but this will be lost any time the field is updated.
In order to update a DocProperty field it's necessary to update the underlying Document Property. For example
Sub EditDocPropUpdateDocPropertyField()
Dim doc As Word.Document
Dim prop As Office.DocumentProperty
Dim propName As String
Dim newPropValue As String
Set doc = ActiveDocument
propName = "MyField"
newPropValue = "new value"
Set prop = doc.CustomDocumentProperties(propName)
prop.value = newPropValue
doc.Fields.Update
End Sub
In the VBE, the Object Browser is a great way to find out what's possible. When I find Word>Field and click on it, I see a list of the members of Field. Name is not in that list. This means that the field object does not have a Name property. That's why you get the error.
You can work around this. One way is to create a bookmark around the field in question. Then in code, find the bookmark by name, then find the field by index inside the bookmark range.
Sample to set text to fields by field name:
ThisDocument.FormFields.Item("MyField1").Result = "hello"
The goal of this script is to:
Ask the user how many text replacement (System Preferences>Keyboard>Text) shortcuts they'd like to have. The text returned is set to my variable "gTextReplacementNum" as number. See my second handler "HowMany()"
Have the user provide the text replacement shortcut and the text to do the replacing for the number of shortcuts they wanted. See my third handler "GetText()"
Take the user provided text contained in a variable to create a new AppleScript doc that does all the heavy lifting for them. Code not yet written; not within scope of question.
Then they have a personalized AppleScript Application Bundle they may launch on their Mac to auto-populate the text replacement preferences pane.
I am having trouble getting this to work properly. I need the loop to keep adding the answers to a variable as a list or to a variable that increments its name according to the loop instance (e.g. TextReturned_i, TextReturned_i+1, etc).
Have I adequately explain this?
global gTextReplacementNum
set gTextReplacementNum to 0
# Main Logic Begins
try
Start()
HowMany()
GetText()
on error errText number errNum
display alert "Error " & errNum message errText
end try
# Main Logic Ends
# Handlers Begin
-- First Handler
on Start()
display alert "Automated Text Replacement v1.0" message "Created by: Me
myemail#domain.com" buttons {} giving up after 4
display alert "About" message "This app will have you provide a text 'short cut' to replace with and replacement text. It then compiles all this into an application that can be run on any Mac.
Would you like to continue?" buttons {"No", "Yes"} cancel button 1 default button 2
end Start
-- Second Handler
on HowMany()
display dialog "How many text replacement shortcuts would you like?
Please enter numericals only. (1, 2, 3)" default answer "" buttons {"Cancel", "Okay"} default button 2 cancel button 1
copy the result as list to {ButtonPressed, TextReturned}
set gTextReplacementNum to TextReturned as number
end HowMany
-- Third Handler
on GetText()
repeat with i from 1 to gTextReplacementNum as number
display dialog "What text would you like to replace?
(this is your shortcut)" default answer "" buttons {"Cancel", "Okay"} default button 2 cancel button 1
set TextShortcut to text returned of result as list
display dialog "What is the replacement text?
(this is what the shortcut fills out)" default answer "" buttons {"Cancel", "Okay"} default button 2 cancel button 1
set TextReplaced to text returned of result as list
end repeat
end GetText
# Handlers End
In your GetText() handler, you are replacing the value TextShortcut and TextReplaced each time. You need to
set aList to aList & newValue
to build a list in a repeat loop.
Also, as is, this handler never returns the value of these two lists. So, I'd suggest, using your scheme, make these two variables globals as well.
So, the full changes are:
1. Add to the declarations:
global gTextReplacementNum
global gTextShortcut
global gTextReplaced
set gTextReplacementNum to 0
set gTextShortcut to {}
set gTextReplaced to {}
and 2. edit your GetText() handler:
-- Third Handler
on GetText()
repeat with i from 1 to gTextReplacementNum as number
display dialog "What text would you like to replace?
(this is your shortcut)" default answer "" buttons {"Cancel", "Okay"} default button 2 cancel button 1
set gTextShortcut to gTextShortcut & (text returned of result)
display dialog "What is the replacement text?
(this is what the shortcut fills out)" default answer "" buttons {"Cancel", "Okay"} default button 2 cancel button 1
set gTextReplaced to gTextReplaced & (text returned of result)
end repeat
end GetText
An alternate method would be to read a tab delim file and work from that with a standard script. Something like:
property fileName : "shortcuts.txt"
set filePath to (path to desktop as string) & fileName
set theData to read file filePath
set theRecords to paragraphs of theData
set oldDelim to AppleScript's text item delimiters
set AppleScript's text item delimiters to tab
repeat with thisPair in theRecords
set {theShortcut, theReplacement} to text items of thisPair
setKeyboardPref(theShortcut, theReplacement)
end repeat
set AppleScript's text item delimiters to oldDelim
on setKeyboardPref(theShortcut, theReplacement)
-- set up the pair
display dialog theShortcut & return & theReplacement
end setKeyboardPref
Am using An inputbox in my form.
If i Press OK the code is fine.
When i Press cancel the Program displayin an error. Wat should i Do ?
You should look for an empty string
Dim MyString As String
MyString = InputBox("Please enter something", "Request Info", Nothing)
If (MyString Is Nothing OrElse MyString = "") Then
'User hit cancel
Else
'Read MyString
End If
Change the code that is after the InputBox to support empty strings. InputBox will return an empty string if you cancel so the reason for the error must be that your code expects the string to have a lenght > 0.
If you edit the question to show the code that calls InputBox as well as a few lines following that line, someone can probably point out the exact error.
See the documentation for a working sample:
Interaction.InputBox Method