Keynoteでオープン中の書類の表示中のスライド(ページ)上にある表を2つ選択して、縦方向に連結するAppleScriptです。
実行頻度から、横連結だけでいいかと思っていたのですが、結局縦連結のScriptも書いておきました。たぶん、こっち(縦連結)は(個人的には)使わないでしょう。
一定の実用性を確保するためには、各表のヘッダー行のラベルを見て、同じラベルのデータを同じ列に入れる必要があることでしょう。本Scriptの実装レベルだと、物理的にただ表をつなげるだけです。
また、ヘッダー部分の処理は一切行っていません。実用性を考えればヘッダー行やヘッダー列を無視して、データ部のみ連結するといった処理が必要になってくると思います。現状の実装では「(作った本人が)わかっているから別にそこまでしなくていい」という程度のお手軽実装です。
▲マージ対象の表
▲現在表示中のスライド(ページ)中に存在している表のタイトルが一覧表示される。座標位置をもとに上→下、左→右とソートした順で表示
▲複数項目を選択する場合にはCommandキーを押しながら選択
▲2つの表を縦方向にマージ(連結)。マージされたほうの表は削除
macOS 10.14.5+Keynote v9.0.2で作成および動作確認を行っています。macOS 10.14上ではBridgePlusを呼び出すためにScript Debugger上で実行するか、アプレット書き出しして実行する必要があります。または、アプレット書き出ししてスクリプトメニューから呼び出してもよいでしょう。
# 個人的には、めんどくさいのでmacOS 10.14環境ではSIP(System Integrity Protection)をオフにして使っています
macOS 10.13.x、macOS 10.12.xでは普通にスクリプトエディタなどから実行可能です。
AppleScript名:Keynoteで表示中のスライド上の表を2つ、縦方向に連結する.scpt |
— Created 2019-05-21 by Takaaki Naganoya — 2019 Piyomaru Software use AppleScript version "2.4" — Yosemite (10.10) or later use framework "Foundation" use scripting additions use Bplus : script "BridgePlus" –https://www.macosxautomation.com/applescript/apps/BridgePlus.html tell application "Keynote" tell front document tell current slide set tCount to count every table if tCount < 2 then display dialog "There is no tables to merge" buttons {"OK"} default button 1 return end if set tList to every table set tInfoList to {} repeat with i in tList set {tPosX, tPosY} to position of i set tName to name of i set the end of tInfoList to {tName, tPosX, tPosY} end repeat end tell end tell end tell –表のY座標、X座標で昇順ソート(上→下、左→右の順で並べる) set sortedList to sort2DList(tInfoList, {3, 2}, {true, true}) of me –表リストから名前だけ抽出 set tmpTList to retSpecifiedItemFrom2DList({1}, sortedList) of me –マージ対象のテーブルを名称で選択 set tRes to choose from list tmpTList with title "Vertial Merge Tables" with prompt "Select merge target two table names " & return & "(Sorted Up-> Down, Left->Right)" with multiple selections allowed if tRes = false then display dialog "Canseled" buttons {"OK"} default button 1 return end if if length of tRes is not equal to 2 then display dialog "Select *two* tables" buttons {"OK"} default button 1 return end if –set mDirection to contents of (choose from list {"Vertival", "Horizontal"} with title "Select Merge Direction" without empty selection allowed) set mDirection to "Vertival" set f1Table to contents of item 1 of tRes –Left (Original) set f2Table to contents of item 2 of tRes –Right (merged) tell application "Keynote" tell front document tell current slide –マージ先の表のサイズを取得(幅、高さ) tell table f1Table set f1Width to column count set f1Height to row count end tell –マージされるの表のサイズを取得(幅、高さ、データを2D Listで) tell table f2Table set f2Width to column count set f2Height to row count set f2DatList to {} repeat with i from 1 to f2Height tell row i set aRowDat to value of every cell end tell set the end of f2DatList to aRowDat end repeat end tell –マージ先の表のサイズを変更して新規追加したセルにデータを埋める tell table f1Table set row count to row count + f2Height –表リサイズ set rowCount to f1Height + 1 repeat with i in f2DatList set colCount to 1 tell row rowCount repeat with ii in i set jj to contents of ii if jj is not equal to missing value then –空白セルを処理スキップ tell cell colCount set value to jj end tell end if set colCount to colCount + 1 end repeat end tell set rowCount to rowCount + 1 end repeat end tell delete table f2Table end tell end tell end tell –2D Listをソート on sort2DList(aList as list, sortIndexes as list, sortOrders as list) load framework –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 set resList to (current application’s SMSForder’s subarraysIn:(aList) sortedByIndexes:newIndex ascending:sortOrders sortTypes:sortTypes |error|:(missing value)) as list return resList end sort2DList –指定2Dリストから、各要素の指定アイテム目を取り出して(1D Listで)返す on retSpecifiedItemFrom2DList(aList as list, bList as list) set newList to {} repeat with i in aList repeat with ii in bList set j to contents of ii set a to contents of (item i of j) set the end of newList to a end repeat end repeat return newList end retSpecifiedItemFrom2DList |