Archive for 8月, 2008

2008/08/25 数値テキストに対して指定桁ごとにセパレータ文字を入れる

数値テキスト(例:”39800″)に対して、指定桁ごとに任意の区切り文字を入れるサブルーチンです。3桁ごとにカンマを入れたりします。

そもそも、Excel 2004のワークシート上の選択部分からデータを取り出したときに、value of selectionで取得すると、数値が小数点つきで返ってきたため、formula of selectionで取得。しかし、プログラムの仕様上、3桁区切りのセパレータ文字が付いていなければならなかったため、その場で作って組み込んだ記憶があります。

Excel 2008ならstring value of selectionで表示どおりの形式でデータが得られるのですが……(汗)

スクリプト名:数値テキストに対して指定桁ごとにセパレータ文字を入れる
set aNumStr to "398890"
set aRes to insertDigitSeparatorChar(aNumStr, 3, ",") of me
> "398,890"

数値テキストに対して指定桁ごとにセパレータ文字を入れる
on insertDigitSeparatorChar(aNumStr, digitNum, aSeparatorStr)
  set cList to characters of aNumStr
  
set rcList to reverse of cList
  
set aLen to length of rcList
  
  
set newList to {}
  
set tmpC to digitNum
  
set totalCount to 1
  
  
repeat with i in rcList
    set the beginning of newList to (i as string)
    
set tmpC to tmpC - 1
    
if tmpC = 0 then
      if aLen > totalCount then
        set the beginning of newList to aSeparatorStr
      end if
      
set tmpC to digitNum
    end if
    
set totalCount to totalCount + 1
  end repeat
  
return newList as string
end insertDigitSeparatorChar

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

2008/08/20 指定日に在任中の内閣総理大臣の氏名を取得

たまたま、国民栄誉賞のことを調べていたら手塚治虫氏が受賞していないとか、亡くなった時期に誰が内閣総理大臣だったかをついでに調べ……気がついたら、こんなルーチンを作っていました。

ほとんどデータのコピー&ペーストだけで、プログラム部分は作るのに2・3分ぐらいもかからなかったような……(汗) 作っておいてなんですが、どんな使い道があるのか自分自身さっぱり不明です。ただ、中学・高校と近現代史はさっぱりやっていなかったので、なんとなくいい勉強になってしまったかもしれません。

一度、某政権与党関連の仕事をして、歴代総理大臣の写真のスキャン画像のうち、トリミングが若干異なる重複写真をピックアップするというプログラムをAppleScriptで組んで実戦投入しましたが……こちらの(日付→在任中の総理大臣)ルーチンが活躍する日は来るのでしょうか。

スクリプト名:指定日に在任中の内閣総理大臣の氏名を取得
set aDateStr to 1989/02/09
set aName to retPrimeMinisterInJapan(aDateStr) of me
> “竹下登”

指定日に在任中の内閣総理大臣の氏名を取得
【参照】 http://ja.wikipedia.org/wiki/内閣総理大臣の一覧
on retPrimeMinisterInJapan(aDate)
  議院内閣制成立以前ならfalse
  
set lowDate to 1885/12/22
  
if aDate < date lowDate then
    display dialog まだ議院内閣制がはじまっていない時代です。
    
return false
  end if
  
  
set primeList to {{”伊藤博文“, 1885/12/22“}, {”黒田清隆“, 1888/04/30“}, {”三條實美“, 1889/10/25“}, {”山縣有朋“, 1889/12/24“}, {”松方正義“, 1891/05/06“}, {”伊藤博文“, 1892/08/08“}, {”黒田清隆(臨時兼任)“, 1896/08/31“}, {”松方正義“, 1896/09/18“}, {”伊藤博文“, 1898/01/12“}, {”大隈重信“, 1898/06/30“}, {”山縣有朋“, 1898/11/8“}, {”伊藤博文“, 1900/10/19“}, {”西園寺公望(臨時兼任)“, 1901/05/10“}, {”桂太郎“, 1901/06/02“}, {”西園寺公望“, 1906/01/07“}, {”桂太郎“, 1908/07/14“}, {”西園寺公望“, 1911/08/30“}, {”桂太郎“, 1912/12/21“}, {”山本權兵衞“, 1913/02/20“}, {”大隈重信“, 1914/04/16“}, {”寺内正毅“, 1916/10/09“}, {”原敬“, 1918/09/29“}, {”内田康哉(臨時兼任)“, 1921/11/04“}, {”高橋是清“, 1921/11/13“}, {”加藤友三郎“, 1922/06/12“}, {”内田康哉(臨時兼任)“, 1923/08/24“}, {”山本權兵衞“, 1923/09/02“}, {”若槻禮次郎“, 1926/01/30“}, {”田中義一“, 1927/04/20“}, {”濱口雄幸“, 1929/07/02“}, {”若槻禮次郎“, 1931/04/14“}, {”犬養毅“, 1931/12/13“}, {”高橋是清(臨時兼任)“, 1932/05/16“}, {”齋藤實“, 1932/05/26“}, {”岡田啓介“, 1934/07/08“}, {”廣田弘毅“, 1936/03/09“}, {”林銑十郎“, 1937/02/02“}, {”近衞文麿“, 1937/06/04“}, {”平沼騏一郎“, 1939/01/05“}, {”阿部信行“, 1939/08/30“}, {”米内光政“, 1940/01/16“}, {”近衞文麿“, 1940/07/22“}, {”東條英機“, 1941/10/18“}, {”小磯國昭“, 1944/7/22“}, {”鈴木貫太郎“, 1945/04/07“}, {”東久邇宮稔彦王“, 1945/08/17“}, {”幣原喜重郎“, 1945/10/09“}, {”吉田茂“, 1946/05/22“}, {”片山哲“, 1947/05/24“}, {”芦田均“, 1948/03/10“}, {”吉田茂“, 1948/10/15“}, {”鳩山一郎“, 1954/12/10“}, {”石橋湛山“, 1956/12/23“}, {”岸信介“, 1957/02/25“}, {”池田勇人“, 1960/07/19“}, {”佐藤榮作“, 1964/11/09“}, {”田中角榮“, 1972/07/07“}, {”三木武夫“, 1974/12/09“}, {”福田赳夫“, 1976/12/24“}, {”大平正芳“, 1978/12/07“}, {”伊東正義(臨時代理)“, 1980/06/12“}, {”鈴木善幸“, 1980/07/17“}, {”中曾根康弘“, 1982/11/27“}, {”竹下登“, 1987/11/06“}, {”宇野宗佑“, 1989/06/03“}, {”海部俊樹“, 1989/08/10“}, {”宮澤喜一“, 1991/11/05“}, {”細川護熙“, 1993/08/09“}, {”羽田孜“, 1994/04/28“}, {”村山富市“, 1994/06/30“}, {”橋本龍太郎“, 1996/01/11“}, {”小渕恵三“, 1998/07/30“}, {”森喜朗“, 2000/04/05“}, {”小泉純一郎“, 2001/04/26“}, {”安倍晋三“, 2006/09/26“}, {”福田康夫“, 2007/09/26“}}
  
  
set prList to reverse of primeList
  
  
set hitF to false
  
repeat with i in prList
    set aPrimeDate to contents of (item 2 of i)
    
if aDate > aPrimeDate then
      set hitF to true
      
exit repeat
    end if
  end repeat
  
  
if hitF = false then return false
  
  
return contents of (item 1 of i)
  
end retPrimeMinisterInJapan

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

2008/08/16 MACアドレスを取得する(Mac OS X 10.5のバグ回避版)

EthernetのMACアドレスを取得して、コロンを外すのにシェルからの戻り値を分解するのに「word of〜」を使用していたのですが、Mac OS X 10.5になってからこのword ofの挙動が変わったためにバグレポートを書いたりAppleの担当とやりあっていました。

word ofは自然言語のテキストを単語分解するために使うものであって、shellの結果をパターン分解するためのものではないというのがApple側の主張。

しかし、日本語の単語分解なんかAppleScriptのword ofでできるわけではないし、やってみてもただ「文字種類の変わり目で適当に区切っているだけ」という、ナメた結果が返ってくるだけです。

Apple側の主張はともかく、従来のMac OS X 10.4までの挙動と変わってしまったので、これを回避するルーチンが、MLにいろいろ投稿されました。海外のScripter連中には、いつも世話になっています。

スクリプト名:MACアドレスを取得する(Mac OS X 10.5のバグ回避版)
Original By Philip Aker (Thanks!)
set myMacAdr to (words of (do shell script ifconfig en0 ether | grep ether | tr : ‘ ‘ | cut -d ‘ ‘ -f 2-“)) as string

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

2008/08/11 ポップアップメニュー項目の高速生成

AppleScript Studioで、ポップアップメニューの項目を追加する場合には、一度popup buttonのmenu内のmenu itemを削除してから、リストに入った項目をひたすらループで追加していくのが常でしたが……海外のMLの過去ログを調べてみたら、call method命令で一括追加する方法を発掘しました。

InDesign CS3用のScriptアプリで、使用可能な書体をすべて取得してpopup menuに追加しようとしたら……システム中に600書体ぐらいあって(汗) さらに、1画面中にそれが複数個あったりして(汗) popup buttonにメニュー項目を追加したときに、それなりに待たされてしまうので困っていました。このルーチンを使うと、激的に高速化できます。

call method命令だとオーバーヘッドが大きいので(cocoa分らないと書けないし、、、)、よほどの効果が期待できないかぎり、使わないようにしているものですが……このぐらい速度向上が著しい場合には、使うべきでしょう。

menuObjectにpopup buttonへのオブジェクト参照(popup button 1 of window 1とか)を入れ、textListにpopup menuに入れるテキストのリスト({”melon”, “apple”, “mango”}など)を入れて本ルーチンを呼び出せばOKです。

スクリプト名:ポップアップメニュー項目の高速生成
ポップアップメニューの初期化(2008/8/11超高速化)
on initPOPUPMenu(menuObject, textList)
  
tell menuObject
    
tell menu 1
      
delete every menu item
    
end tell
  
end tell
  
  
call method addItemsWithTitles: of menuObject with parameter textList
end initPOPUPMenu

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

2008/08/05 カレンダーのインクリメント/デクリメント

日付関連処理を行う際に、月のデータを変数に入れて順次処理を行おうとしても……12月を過ぎれば「年」の繰り上げが必要になりますし、月も1に戻す必要があります。毎回同じ処理を書くというのでは、ちょっとウンザリする内容です。

そこで、年と月を別々の変数に保持しておき、これらをペアとして扱ってインクリメント(+1)およびデクリメント(−1)するサブルーチンを用意しました。それほど長いものではありませんが、有用性は高いと思います。

スクリプト名:カレンダーのインクリメント_デクリメント
set aYear to 2008
set aMonth to 12
set {bYear, bMonth} to incrementMonth(aYear, aMonth) of me
{bYear, bMonth}
> {2009, 1}

カレンダー(年と月のペア)をインクリメント(+1)
on incrementMonth(aYear, aMonth)
  if aMonth < 12 then
    1から11月の場合
    
set nMonth to aMonth + 1
    
return {aYear, nMonth}
    
  else if aMonth = 12 then
    12月の場合
    
set nYear to aYear + 1
    
set nMonth to 1
    
return {nYear, nMonth}
    
  else
    月パラメータが1から12の範囲になかった
    
return {false, false}
  end if
end incrementMonth

カレンダー(年と月のペア)をデクリメント(−1)
on decrementMonth(aYear, aMonth)
  if aMonth > 1 then
    2から11月の場合
    
set nMonth to aMonth - 1
    
return {aYear, nMonth}
    
  else if aMonth = 1 then
    1月の場合
    
set nYear to aYear - 1
    
set nMonth to 12
    
return {nYear, nMonth}
    
  else
    月パラメータが1から12の範囲になかった
    
return {false, false}
  end if
end decrementMonth

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に

2008/08/05 指定の数値リストを作成する

ループ内で、イレギュラーな処理をしたいような場合……たとえば、ループカウンタが奇数のときだけ処理を行いたいが、20のときにも例外的に処理を行いたい……といった場合、まあ普通はif文で条件分岐するわけですが、これが増えた場合には大変なことになります。
(more…)

2008/08/05 Excelで、バージョンに依存しないで選択範囲のデータ取得

Excelで最も利用するAppleScript処理は、選択範囲内のデータの取得でしょう。
(more…)

2008/08/01 MindManagerで、ルートトピックを選択状態にする

Mindjet MindManagerで、ルートトピックを選択状態にします。Mail.appからメールのスレッドを取得してメールのやりとりをMindManager上にマインドマップでビジュアル化するAppleScriptを作るときに使ったものです(正確にいえば、その部分の処理は必要なかったので没になってしまいましたが)。

マインドマップで図示したあとで、ルートトピックを選択状態にして各ノードに付加したノード(メール本文が入っている)をウィンドウ下部に表示するよう、GUI Scriptingをまじえつつ処理を書いてみました。うんざりするほどメールの本数が多い場合でも、メールの流れを視覚化できるので、非常に有効です。あまりに有用性が高いので、単体でツールとしてリリースするかもしれません>マインドマップでメールフローを図示するAppleScript

スクリプト名:MindManagerで、ルートトピックを選択状態にする
MindManagerで、ルートトピックを選択状態にする
tell application Mindjet MindManager
  if document 1 exists then
    set rootTopic to the id of central topic of document 1
    
select {topic id rootTopic of document 1}
  end if
end tell

▼新規書類に ▼カーソル位置に ▼ドキュメント末尾に