Recently upgraded to Adobe CC 2020 and my script will now not work. Also Script Editor changed class names.
I am getting an error such that:
error "Can’t get every page of alias \"Untitled - Data:Users:gregory:Desktop:FORUM_MayJun_0414_B Folder:FORUM_MayJun_0414_fortesting.indd\"." number -1728 from every «class page» of alias "Untitled - Data:Users:gregory:Desktop:FORUM_MayJun_0414_B Folder:FORUM_MayJun_0414_fortesting.indd"
Here is my script:
global WordDocName
global wrongText
global myStories
--set uniqueInCopyStories to {}
--set wrongText to "BASE"
set theDoc to choose file without multiple selections allowed
--set theDoc to POSIX path of theDoc
set theDocInfo to info for theDoc
set theDocName to name of theDocInfo
set theDocName to characters 1 thru -6 of theDocName as text
set WordDocName to theDocName
set theDocName to theDocName & return
set myStories to {}
my processFiles(theDoc)
set mylist to items 1 thru -1 of myStories
set firstList to mylist
set secondList to RemoveDuplicates(firstList)
--secondList --> {1, 2, 3, 4}
set mynewlist to {}
repeat with i from 1 to (count of secondList)
set myitem to item i of secondList as text
set end of mynewlist to myitem
end repeat
set mystring to mynewlist as string
--return mystring
my processWordDoc(theDocName, mystring, WordDocName)
on processFiles(theDoc)
tell application "Adobe InDesign 2020"
activate
open theDoc
tell theDoc
set myPages to every «class page»
repeat with i from 1 to count of myPages
tell item i of myPages
set myTextFrames to (every «class txtf» of item i of myPages)
repeat with aTextFrame in myTextFrames
if «class plnk» of «class strp» of aTextFrame is not «constant senmnada» then
if «class strp»'s «class plnk»'s «class lnkt» of aTextFrame is "InCopyInterchange" then
set mystorytitle to «class sTtl» of aTextFrame's «class strp»
set myLabel to «class ptag» of aTextFrame
set myText to characters 1 thru -1 of mystorytitle as text
--if myText does not contain wrongText then
set myStory to aTextFrame's «class strp»'s contents
copy "Page " & (name of item i of myPages) & " " & mystorytitle & return & myLabel & return & myStory & return & return to end of myStories
end if
end if
--end if
end repeat
end tell
end repeat
end tell
end tell
end processFiles
on processWordDoc(theDocName, mystring, WordDocName)
tell application "Microsoft Word"
activate
set newDoc to make new document
copy theDocName & mystring to content of text object of newDoc
save as active document file name WordDocName
my textblue()
end tell
end processWordDoc
on textblue()
with timeout of 60000 seconds
tell application "Microsoft Word"
set myPars to every paragraph of active document
set myTitle to text object of paragraph 1 of active document
set color index of font object of myTitle to blue
repeat with aPar in myPars
if content of text object of aPar starts with "Page" then
set myRange to text object of aPar
set color index of font object of myRange to blue
end if
end repeat
end tell
end timeout
end textblue
on RemoveDuplicates(inputList)
set outputList to {}
repeat with i from 1 to length of inputList
-- We make testItem a single-item list to ensure
-- that sublists of the inputList are properly
-- looked for in the outputlist.
--
set thisItem to item i of inputList
set testItem to {thisItem}
if (outputList does not contain testItem) then
set end of outputList to thisItem
end if
end repeat
return outputList
end RemoveDuplicates
What I don't understand is why my script thinks I am asking to get every page of every page, when it was automatic that every page would be every page of theDoc
theDoc is an AppleScript alias specifier, but you are using it (also) as an InDesign document reference.
The easiest solution is to replace
tell theDoc
with
tell active document
Related
When I open a T-Code from SAP GUI, some of the fields are pre-populated from past queries. Is it possible to enter a T-Code and all the fields in the next window to be forced blank?
I develop scripts for SAP GUI and run into problems if fields already have content from prior queries.
The history cannot be disabled user-wise. Period.
Either all or nobody.
If you want to disable the history go to SAPgui options into Local data setting
The history in Windows is a simple Access MDB file but it is password-protected, so you may try to crack it and delete only your user lines but it is a bunch of work.
However, I guess the history that makes you crazy is not what I described above, but SPA/GPA parameters. Check it first
You can empty some fields with :
""
session.findById("wnd[1]/usr/ctxtRMMG1_REF-BWTAR").Text = ""
But doesn't work all the time...
My method for this is to loop through all the fields (and recursively on all children elements) and set the text value of them to an empty string.
On read-only fields it throws an error and this is why "On Error Resume Next" is necessary.
Sub Start_Clearing()
'setup SAP
If Not IsObject(SAPApplication) Then
Set SapGuiAuto = GetObject("SAPGUI")
Set SAPApplication = SapGuiAuto.GetScriptingEngine
End If
If Not IsObject(Connection) Then
Set Connection = SAPApplication.Children(0)
End If
If Not IsObject(Session) Then
Set Session = Connection.Children(0)
End If
If IsObject(WScript) Then
WScript.ConnectObject Session, "on"
WScript.ConnectObject SAPApplication, "on"
End If
Dim UserArea As Object
Set UserArea = Session.findByID("wnd[0]/usr")
Clear_Fields UserArea
End Sub
'_______________________________
Sub Clear_Fields(Area As Object)
Set SAPApplication = GetObject("SAPGUI").GetScriptingEngine
Dim Obj As Object
Dim NextArea As Object
On Error Resume Next
For i = 0 To Area.Children.Count - 1
Set Obj = Area.Children(CInt(i))
If Obj.ContainerType = True Then
If Obj.Children.Count > 0 Then
Set NextArea = SAPApplication.findByID(Obj.ID)
Clear_Fields NextArea
End If
End If
Obj.Text = ""
Next i
End Sub
I currently have a set of xml child nodes that are bound to a table using the data binding of CustomerInvoice.PriceAndTax.PriceComponents[*].
The PriceComponent element structure is:
<PriceComponents>
<Description languageCode="EN">Value Added Tax (%)</Description>
<Rate>
<DecimalValue>13.5</DecimalValue>
<MeasureUnitCode>P1</MeasureUnitCode>
</Rate>
<RateBaseQuantityTypeName languageCode="EN"> </RateBaseQuantityTypeName>
<RateBaseMeasureUnitName languageCode="EN"> </RateBaseMeasureUnitName>
<CalculationBasis>
<BaseCode>1</BaseCode>
<Amount currencyCode="EUR">1500.00</Amount>
</CalculationBasis>
<CalculationBasisBaseName languageCode="EN">Percentage (of one hundred)</CalculationBasisBaseName>
<CalculationBasisQuantityMeasureUnitName languageCode="EN"> </CalculationBasisQuantityMeasureUnitName>
<CalculationBasisQuantityTypeName languageCode="EN"> </CalculationBasisQuantityTypeName>
<CalculatedAmount currencyCode="EUR">202.50</CalculatedAmount>
</PriceComponents>
Currently this is outputting all the PriceComponent nodes to the table in the form, I want it to only output the nodes that have a description of Value Added Tax (%).
Is there a way to do this in the Object Palette - Binding - Data Binding property?
I ended up solving this using a script.
I added a sub form to the table, nested in the repeating row. In here I added the fields from the CustomerInvoice.PriceAndTax.PriceComponents child nodes that I wanted to display and the Description field to check the value of.
The structure of the table
-- tblVATAnalysis
-- HeaderRow
--- header fields ---
-- MainRow
-- Row1
-- colRate
-- colSupplies
-- colVATAmount
-- HiddenRow
-- lblDescription
-- decRate
-- decSupplies
-- decVATAmount
Then I added the following script:
FormInvoiceRequest.bdyMain.frmSummaryData.tblVATAnalysis.MainRow.HiddenRow
::initialize - (FormCalc, client)
var content = "";
if(this.decRate.rawValue <> null & this.decRate.rawValue <> "")
then
if(this.lblDescription.rawValue == "VAT (%)")
then
content = this.decRate.rawValue;
endif
if(this.parent.parent.frmTaxAmount.decTaxAmount == 0)
then
if(this.lblDescription.rawValue == "Total Item Net Value")
then
content = this.decRate.rawValue;
endif
endif
endif
if(content <> "")
then
FormInvoiceRequest.bdyMain.frmSummaryData.tblVATAnalysis.MainRow.Row1
.colRate.rawValue = content;
else
FormInvoiceRequest.bdyMain.frmSummaryData.tblVATAnalysis.MainRow.Row1
.presence = "hidden";
endif
This populates a variable called content if the row has a description of VAT (%), then if content doesn't have a value the row is hidden.
The UI is as following:
The tool "AutoIt Window Info" can only locate the elements in red (red rectangle area), the sub items can not be located.
So how can I expand or operate these items?
Usually Windows controls can be accessed using keystrokes as well.
In the screen-dump the Farmtt element is selected. That would be your starting point.
You may try:
Send("{DOWN}") Move down an element.
Send("{TAB}") Navigate to next control (button, checkbox, etc)
Send("{NumPadMult}") Recursively expands folders in a SysTreeView32.
Send("{ENTER}") ENTER key on the main keyboard
etc.
Reference:
https://www.autoitscript.com/autoit3/docs/appendix/SendKeys.htm
There are two things over here:
1) Use the following code snippet:
;Gets the handle for the text
Func readFirstlevelTreeNodes($hWndCtrl)
Local $firstItemHandle = _GUICtrlTreeView_GetFirstItem ($hWndCtrl)
Local $iCount = _GUICtrlTreeView_GetSiblingCount( $hWndCtrl, $firstItemHandle )
Dim $aRet[$iCount]
$aRet[0] = $firstItemHandle
For $index = 1 To $iCount - 1
$aRet[$index] = _GUICtrlTreeView_GetNextSibling ( $hWndCtrl, $firstItemHandle )
$firstItemHandle = $aRet[$index]
Next
getTreeNodeTextList($hWndCtrl,$aRet)
EndFunc
; Gets the text for given sibling node handle lists
Func getTreeNodeTextList($hWndCtrl,$aRet)
ConsoleWrite("Tree Node first level list"&#CRLF)
For $index = 0 To Ubound($aRet) -1
ConsoleWrite(_GUICtrlTreeView_GetText ( $hWndCtrl, $aRet[$index] )&#CRLF)
Next
EndFunc
You may see the output for the first level tree nodes.
2) If you still dont see the output then please verify the control handle values and window handles. If they are correct and it still doesnt show the first level tree nodes then try running your sciTE editor as administrator.
I think this should help.
I need to create a field editor in a LiveCode DataGrid that grows as the user types to fit the formattedHeight of the field. The rest of the underlying row control needs to resize too along with shifting any subsequent row controls down.
Answering my own question as it may be useful to others.
Copy the field editor behavior button from the revDataGridLibrary stack to the card with the row template on it.
Edit the script of the field to be edited as follows (note you will need to fix the behavior button reference to be the long id of your new field edtior behaviour):
on preOpenFieldEditor pEditor
set the behavior of pEditor to the long id of button id 1023 of card id 1010 of stack "Data Grid Templates 1362091650635"
set the uRowControl of pEditor to the long id of the owner of me
end preOpenFieldEditor
Edit the field editor behavior script adding the following:
local sHeight,sRowControl
setProp uRowControl pRowControl
put pRowControl into sRowControl
end uRowControl
on openField
put the formattedHeight of me into sHeight
pass openField
end openField
on textChanged
local tHeight,tRect
lock screen
put the formattedHeight of me into tHeight
if sHeight <> tHeight then
put the rect of me into tRect
put item 2 of tRect+ tHeight into item 4 of tRect
set the rect of me to tRect
put tHeight into sHeight
dispatch "UpdateRow" to sRowControl with the long id of me
end if
unlock screen
pass textChanged
end textChanged
Now edit the row template behaviour adding the following handler (Note that in this case the field being edited is named "note" so you will want to change that for your use case):
on UpdateRow pFieldEditor
set the rect of graphic "Background" of me to the rect of pFieldEditor
set the rect of fld "note" of me to the rect of pFieldEditor
set the rect of me to the formattedRect of me
put the uScriptLocal["sTableObjectsA"] of me into tTableObjectsA
repeat for each line tControl in tTableObjectsA["all row controls"]
delete word -2 to -1 of tControl -- of me
put tControl into tControlA[the dgIndex of tControl]
end repeat
put the bottomLeft of me into tTopLeft
repeat for each item tIndex in tTableObjectsA["current"]["indexes"]
if tIndex > the dgIndex of me then
set the topLeft of tControlA[tIndex] to tTopLeft
put the bottomLeft of tControlA[tIndex] into tTopLeft
end if
end repeat
end UpdateRow
Looks useful, Monte. Question: why the preOpenField handler? Can't that info just be set once at design time? Does the DataGrid create a new field control each time the editor is invoked?
I'm very new to VBS and experimenting with removing the read only attribute from a directory recursively.
It's removing the read only attribute for files but not for the directories. Also The files within these directories seem to have lost their associated program link and are now all showing as an unregistered file type. Any help is greatly appreciated.
Update: I can see why the files have lost their associations now. It's because the . which separates the name from the extension has been removed! Doh! Ideally I'd like to rename the filename only.
re.Pattern = "[_.]"
re.IgnoreCase = True
re.Global = True
RemoveReadonlyRecursive("T:\Torrents\")
Sub RemoveReadonlyRecursive(DirPath)
ReadOnly = 1
Set oFld = FSO.GetFolder(DirPath)
For Each oFile in oFld.Files
If oFile.Attributes AND ReadOnly Then
oFile.Attributes = oFile.Attributes XOR ReadOnly
End If
If re.Test(oFile.Name) Then
oFile.Name = re.Replace(oFile.Name, " ")
End If
Next
For Each oSubFld in oFld.SubFolders
If oSubFld.Attributes AND ReadOnly Then
oSubFld.Attributes = oSubFld.Attributes XOR ReadOnly
End If
If re.Test(oSubFld.Name) Then
oSubFld.Name = re.Replace(oSubFld.Name, " ")
End If
RemoveReadonlyRecursive(oSubFld.Path)
Next
End Sub
It seems you want to automate a repeatable action by a script. Why don't you use the attrib command to do that for you:
attrib -r "T:\Torrents\*.*" /S
You can place that in a batch file if you want to attach it to an clickable icon.
EDIT:
To run it from VBScript silently:
Set WshShell = WScript.CreateObject("WScript.Shell")
WshShell.Run "attrib -r ""T:\Torrents\*.*"" /S", 0, true)
EDIT2:
To replace everything except the last period, use a regular expression like:
filename = "my file.name.001.2012.extension"
Set regEx = New RegExp
' Make two captures:
' 1. Everything except the last dot
' 2. The last dot and after that everything that is not a dot
regEx.Pattern = "^(.*)(\.[^.]+)$" ' Make two captures:
' Replace everything that is a dot in the first capture with nothing and append the second capture
For each match in regEx.Execute(filename)
newFileName = replace(match.submatches(0), ".", "") & match.submatches(1)
Next