Pagesでオープン中の最前面の書類の1ページ目に存在する表オブジェクト中の背景色を置換するAppleScriptです。カラー選択のポップアップメニューUser Interfaceをpickup colorライブラリに分離したため、実行できる環境が増えました(Script Debugger上でも動くようになりました)。
–> Download Code-signed AppleScript applet with sample Pages data
Pages書類の「表オブジェクト」にAppleScriptからアクセスするためには、Pages上で表オブジェクトを選択した状態で、
「オブジェクトの配置」を「移動しない」に事前に設定しておく必要があります。
本AppleScriptを実行可能なランタイム環境は、スクリプトエディタ、アプレットの2つです。スクリプトメニューおよびScript Debuggerでは各GUI部品のクリックイベントを拾えないために、実行しても選択などが行えません。
のように、1ページのみのPages書類に表オブジェクトを入れて、「移動しない」設定にしてある状態で本AppleScriptを実行。
表のセル中の色をすべて取得して、ユニーク化してポップアップメニューから「変更元」の色を選択できます。
選択して、「OK」ボタンをクリック。ここで選択した色が置換されます。
選択した色をどの色に変更(置換)するのかを指定します。
グレーを選択。
AppleScript名:Pages書類の1ページ目の表の背景色を置換 v5 |
— Created 2017-07-15 by Takaaki Naganoya — Modified 2019-10-25 by Takaaki Naganoya — 2019 Piyomaru Software use AppleScript version "2.4" use scripting additions use framework "Foundation" use framework "AppKit" use Bplus : script "BridgePlus" –https://www.macosxautomation.com/applescript/apps/BridgePlus.html use pickLib : script "pickup color" –http://piyocast.com/as/asinyaye –v1:First Version –v2:Pick Up target cells by calculate every background color (35% speed up) –v3:Draw cells by range (x20 speed up) –v3.1:Bug Fix (retRangeFromPosList) –v3.1.1:Bug Fix (retRangeFromPosList) –v4:Two-way Simulation (Horizontal / Vertical scan), Corner-Rounded NSImage, Dynamic Color Naming –v4.1:Correct Vertical Scan simulation (Sort list for vertical range evaluation, at first) –v5: Use "pickup color" library, Auto color name suggestion function was removed property NSArray : a reference to current application’s NSArray property SMSForder : a reference to current application’s SMSForder –初期化 load framework –Pagesの1ページ目にある表の塗り色を取得 tell application "Pages" if (count of (every document)) = 0 then return tell front document if (count of (every table)) = 0 then return tell table 1 set c1List to background color of every cell set aProp to properties set xCount to column count of aProp end tell end tell end tell –色データをユニーク化(重複削除) set bList to uniquifyList(c1List) of me –Convert 1D List to 2D List set c3List to (SMSForder’s subarraysFrom:c1List groupedBy:xCount |error|:(missing value)) as list –missing value(背景色なし)を除外する set c2List to (SMSForder’s arrayByDeletingBlanksIn:(bList)) as list –Popup Menuで置換色選択 set cRes to pickup color c2List main message "Select Target Color" color max max65535 if cRes = 0 then return set fromCol to (contents of item cRes of c2List) –カラーピッカーで置換色選択 set tCol to choose color default color fromCol set d1 to current date –実際に表の背景色を置換する set hitList to findDataFrom2DList(fromCol, c3List) of me –データ上で当該色のセル情報を計算する –Rangeを横スキャンと縦スキャンの2通りで試算(Two way Simulation) set rList1 to retRangeFromPosListHorizontal(hitList) of me –横方向へのrange評価 set rList2 to retRangeFromPosListVertival(hitList) of me –縦方向へのrange評価 –Simulationの結果、要素数の少ない方(=処理時間の短い方=高速な方)を採用する –log {"Simulation", (length of rList1), (length of rList2)} if (length of rList1) < (length of rList2) then copy rList1 to rangeList else copy rList2 to rangeList end if tell application "Pages" activate tell front document tell table 1 repeat with i in rangeList set j to contents of i ignoring application responses –非同期実行モードで高速実行 set background color of range j to tCol end ignoring end repeat end tell end tell end tell set d2 to current date return d2 – d1 on uniquifyList(aList as list) set aArray to NSArray’s arrayWithArray:aList set bArray to aArray’s valueForKeyPath:"@distinctUnionOfObjects.self" return bArray as list end uniquifyList on findDataFrom2DList(anItem, aList as list) script spd property aList : {} property resList : {} end script set (aList of spd) to aList set (resList of spd) to {} set yCount to 1 repeat with i in (aList of spd) set aResList to (Bplus’s indexesOfItem:anItem inList:i inverting:false) as list set tmpList to {} if aResList is not equal to {} then repeat with ii in aResList set jj to contents of ii set the end of tmpList to {jj, yCount} end repeat set (resList of spd) to (resList of spd) & tmpList end if set yCount to yCount + 1 end repeat return (resList of spd) –return {{x, y}…..} item list (1-based) end findDataFrom2DList on retRangeFromPosListVertival(posList as list) script rangeSPD property posList2 : {} end script –縦方向へのrange評価に都合がいいようにソート set (posList2 of rangeSPD) to shellSortListAscending(posList, {1, 2}) of me –先頭データをピックアップ set firstData to first item of (posList2 of rangeSPD) set (posList2 of rangeSPD) to rest of (posList2 of rangeSPD) copy firstData to {curX1, curY1} set tmpRangeStr to aNumToExcelColumn(curX1) of me & (curY1 as string) & ":" set tmpRange to {} set hitF to false set outList to {} repeat with i in (posList2 of rangeSPD) copy i to {tmpX, tmpY} –log {"{curX1, curY1}", {curX1, curY1}} –log {"{tmpX, tmpY}", {tmpX, tmpY}} if (curX1 = tmpX) and (curY1 + 1 = tmpY) then –Y方向への連続値を拾っている最中 if hitF = false then –log "case 1a" –log {"hitF", hitF} set hitF to true else –log "case 1b" –log {"hitF", hitF} –横に連続しているブロックの途中 end if else –直前の値と連続していない if hitF = false then –log "case 2a" –log {"hitF", hitF} set tmpRangeStr to tmpRangeStr & aNumToExcelColumn(curX1) of me & (curY1 as string) set the end of outList to tmpRangeStr set tmpRangeStr to aNumToExcelColumn(tmpX) of me & (tmpY as string) & ":" set hitF to false else –log "case 2b" –log {"hitF", hitF} –連続ブロックの末尾を拾った set tmpRangeStr to tmpRangeStr & aNumToExcelColumn(curX1) of me & (curY1 as string) set the end of outList to tmpRangeStr set tmpRangeStr to aNumToExcelColumn(tmpX) of me & (tmpY as string) & ":" set hitF to false –log {"tmpRangeStr", tmpRangeStr} end if end if copy {tmpX, tmpY} to {curX1, curY1} end repeat –log {tmpRangeStr, hitF} if (hitF = true) or (tmpRangeStr is not equal to "") then set tmpRangeStr to tmpRangeStr & aNumToExcelColumn(curX1) of me & (curY1 as string) set the end of outList to tmpRangeStr end if return outList end retRangeFromPosListVertival on retRangeFromPosListHorizontal(posList as list) script rangeSPD property posList2 : {} end script copy posList to (posList2 of rangeSPD) –先頭データをピックアップ set firstData to first item of (posList2 of rangeSPD) set (posList2 of rangeSPD) to rest of (posList2 of rangeSPD) copy firstData to {curX1, curY1} set tmpRangeStr to aNumToExcelColumn(curX1) of me & (curY1 as string) & ":" set tmpRange to {} set hitF to false set outList to {} repeat with i in (posList2 of rangeSPD) copy i to {tmpX, tmpY} –log {"{curX1, curY1}", {curX1, curY1}} –log {"{tmpX, tmpY}", {tmpX, tmpY}} if (curX1 + 1 = tmpX) and (curY1 = tmpY) then –X方向への連続値を拾っている最中 if hitF = false then –log "case 1a" –log {"hitF", hitF} set hitF to true else –log "case 1b" –log {"hitF", hitF} –横に連続しているブロックの途中 end if else –直前の値と連続していない if hitF = false then –log "case 2a" –log {"hitF", hitF} set tmpRangeStr to tmpRangeStr & aNumToExcelColumn(curX1) of me & (curY1 as string) set the end of outList to tmpRangeStr set tmpRangeStr to aNumToExcelColumn(tmpX) of me & (tmpY as string) & ":" set hitF to false else –log "case 2b" –log {"hitF", hitF} –連続ブロックの末尾を拾った set tmpRangeStr to tmpRangeStr & aNumToExcelColumn(curX1) of me & (curY1 as string) set the end of outList to tmpRangeStr set tmpRangeStr to aNumToExcelColumn(tmpX) of me & (tmpY as string) & ":" set hitF to false –log {"tmpRangeStr", tmpRangeStr} end if end if copy {tmpX, tmpY} to {curX1, curY1} end repeat –log {tmpRangeStr, hitF} if (hitF = true) or (tmpRangeStr is not equal to "") then set tmpRangeStr to tmpRangeStr & aNumToExcelColumn(curX1) of me & (curY1 as string) set the end of outList to tmpRangeStr end if return outList end retRangeFromPosListHorizontal –2008/05/01 By Takaaki Naganoya –10進数数値をExcel 2004/2008的カラム表現にエンコードするサブルーチン を使いまわし –1〜1351までの間であれば正しいエンコーディング結果を返す on aNumToExcelColumn(origNum as integer) if origNum > 1351 then error "エラー:Excel 2004/2008的カラム表現(A1形式)への変換ルーチンにおいて、想定範囲外(1351以上)のパラメータが指定されました" end if set upperDigitEncTable to {"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "A"} set lowerDigitEncTable to {"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "A"} set oNum to origNum set nTh to 26 set stringLength to 4 –数字が1桁の場合の対応 if origNum < 27 then set aRes to (item origNum of upperDigitEncTable) as string return aRes end if if origNum > 702 then –3桁になる場合 set upupNum to oNum div 676 –整数除算–上の上の桁 set oNum to oNum – (upupNum * 676) set upNum to oNum div 26 –整数除算–上の桁 set lowNum to oNum mod 26 – 1 –余剰計算–下の桁 –超つじつま合わせ処理 if lowNum = -1 then set upNum to upNum – 1 set lowNum to 25 end if set upupChar to (item upupNum of upperDigitEncTable) as string set upChar to (item upNum of upperDigitEncTable) as string set lowChar to (item (lowNum + 1) of lowerDigitEncTable) as string set resText to upupChar & upChar & lowChar else –2桁の場合 set upNum to oNum div 26 –整数除算–上の桁 set lowNum to oNum mod 26 – 1 –余剰計算–下の桁 –超つじつま合わせ処理 if lowNum = -1 then set upNum to upNum – 1 set lowNum to 25 end if set upChar to (item upNum of upperDigitEncTable) as string set lowChar to (item (lowNum + 1) of lowerDigitEncTable) as string set resText to upChar & lowChar end if return resText end aNumToExcelColumn –入れ子のリストを昇順ソート on shellSortListAscending(a, keyItem) return sort2DList(a, keyItem, {true}) of me end shellSortListAscending –入れ子のリストを降順ソート on shellSortListDecending(a, keyItem) return sort2DList(a, keyItem, {false}) of me end shellSortListDecending –2D Listをソート on sort2DList(aList as list, sortIndexes as list, sortOrders as list) –index値をAS流(アイテムが1はじまり)からCocoa流(アイテムが0はじまり)に変換 set newIndex to {} repeat with i in sortIndexes set j to contents of i set j to j – 1 set the end of newIndex to j end repeat –Sort TypeのListを作成(あえて外部から指定する内容でもない) set sortTypes to {} repeat (length of sortIndexes) times set the end of sortTypes to "compare:" end repeat –Sort set resList to (SMSForder’s subarraysIn:(aList) sortedByIndexes:newIndex ascending:sortOrders sortTypes:sortTypes |error|:(missing value)) as list return resList end sort2DList |
More from my site
(Visited 144 times, 1 visits today)