Archive for 7月, 2008

2008/07/30 小数点以下を指定桁で切り捨て

数値を指定桁で切り捨てる(roundする)サブルーチンです。絶対にいつかどこかで作ったはずなのに、見つからなかったのでその場で作ってしまいました。

InDesign CS3で表を作るときに、単純に作成予定サイズを行数で割った数を使うだけでは誤差が出てしまったので、割った数をこのように任意桁で切り捨てて処理してみました。それでも計算が合わなかったので、現実的な解決方法(やや仕上がりサイズを小さくしておく)で帳尻を合わせましたが……。

スクリプト名:小数点以下を指定桁で切り捨て
set a to 3.14159265359
set aRes to roundWithSpecifiedDigit(a, 2) of me
> 3.14

小数点以下を指定桁で切り捨て
on roundWithSpecifiedDigit(aNum, aDigit)
  set bNum to aNum * (10 ^ aDigit)
  
set cNum to round bNum rounding down
  
set dNum to cNum / (10 ^ aDigit)
  
return dNum
end roundWithSpecifiedDigit

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

2008/07/28 iCalに「日本の祝日」を追加

iCalに、「Japanese Holidays」というAppleが配布しているWebcalの登録確認を行い、登録していない場合には登録するという処理を行います。

一部、GUI Scriptingによる処理を含んでいるため、Mac OS X 10.6以降でそのまま動くという保証はまったくないのですが、自前で日本の祝日を計算しなくてもiCalに問い合わせるだけでいい(しかも、祝日が増えた場合でも自動対応してくれる)ため、実装実験を行ってみたものです。

結局、このルーチンは実戦投入されませんでしたが、何かの折に使ってみたいものです。

スクリプト名:iCalに日本の祝日を追加
set aRes to addJapaneseHolidays() of iCalLib

script iCalLib
  iCalに「日本の休日」のwebcalを追加する
  
on addJapaneseHolidays()
    OSバージョンの確認を行う
    
set v2 to system attribute sys2 > 4/5
    
if v2 < 4 then return false 10.3や10.2などであれば実行禁止
    
    
GUI scriptingの有効チェックを行う
    
set guiRes to retGUIScriptingEnabled() of me
    
if guiRes = false then return false
    
    
repeat
      using terms from application iCal
        tell application iCal
          set cList to name of every calendar
          
          
if Japanese Holidays is not in cList then
            インターネット接続確認
            
set a to connection_check() of me
            
if a = false then return false
            
            
ignoring application responses
              GetURL webcal://ical.mac.com/ical/Japanese32Holidays.ics
            end ignoring
          else
            return true
          end if
        end tell
      end using terms from
      
      
activate application iCal
      
tell application System Events
        tell process iCal
          tell window 1
            tell sheet 1
              click button 2
            end tell
            
            
repeat
              delay 1
              
tell sheet 1
                set bCount to count every button
                
if bCount is not equal to 1 then exit repeat
              end tell
            end repeat
            
            
tell sheet 1
              if v2 = 4 then
                Mac OS X 10.4の場合
                
set value of checkbox 1 to 1
                
set value of checkbox 2 to 1
                
                
click button 2 of list 1 OKボタン
              else if v2 = 5 then
                Mac OS X 10.5の場合
                
tell list 1
                  set value of checkbox 1 to 1
                  
set value of checkbox 2 to 1
                  
set value of checkbox 3 to 1
                end tell
                
                
click button 1 OK
                
              else
                return false 10.6などの想定外のバージョンであった場合    
              end if
            end tell
          end tell
        end tell
      end tell
    end repeat
  end addJapaneseHolidays
  
  
on connection_check()
    try
      tell application System Events
        do shell script sbin/ping -c 1 www.google.com
      end tell
      
set the connection_status to true
    on error
      set the connection_status to false
    end try
    
return connection_status
  end connection_check
  
  
GUI Scriptingの設定判定。10.4/10.5対応
  
on retGUIScriptingEnabled()
    set v2 to system attribute sys2 > 4, 5
    
    
Mac OS X 10.4以上なら実行
    
if v2 > 3 then
      tell application System Events
        set anUIe to UI elements enabled
      end tell
      
      
if anUIe = true then
        return true UI Element Scripting (GUI Scripting)がイネーブルならtrueを返す
      else
        beep
        
display dialog UI Element Scriptingが有効になっていません。 & return & return & 「システム環境設定」の「ユニバーサルアクセス」で、「補助装置を使用可能にする」のチェックボックスにチェックを入れてから再実行してください。 with icon stop
        
if button returned of result is OK then
          tell application System Preferences
            activate
            
set current pane to pane com.apple.preference.universalaccess
          end tell
          
return false
        end if
      end if
    end if
  end retGUIScriptingEnabled
end script

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

2008/07/28 曜日リストの並び順をチェック v2

曜日リストの並び順チェックを書き直して、短くしたものです。

スクリプト名:曜日リストの並び順をチェック v2
set mStrList to {"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", ""}

set chkList to {"", "", "", "", "", "", ""}

set mhLen to length of mStrList
set mPointer to 1
set tmpStrlist to {}

repeat with i from 1 to mhLen
  set aData to contents of (item mPointer of chkList)
  
set the end of tmpStrlist to aData
  
set mPointer to mPointer + 1
  
if mPointer = 8 then set mPointer to 1
end repeat

if mStrList is not equal to tmpStrlist then
  display dialog "エラー:曜日ヘッダーで異常が見つかりました。曜日文字列が正しい順序で並んでいません。" buttons {"OK"} default button 1
  
return
end if

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

2008/07/28 曜日リストの並び順をチェック

あまり汎用性の高いモジュールではありませんが、与えられたリストの内容が日〜土の曜日の文字列の繰り返しであることを検証するための処理です。あまり効率がよろしくなく、処理内容が美しくなかったので、あとで書き直してみました。

スクリプト名:曜日リストの並び順をチェック
set mStrList to {"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", ""}

set chkList to {"", "", "", "", "", "", ""}

set exitF to false
repeat while mStrList is not equal to {}
  set resLen to length of mStrList
  
if resLen > 7 then
    if mStrList begins with chkList then
      set mStrList to items 8 thru -1 of mStrList
    end if
  else
    set ap to 1
    
set apLen to length of mStrList
    
repeat with i in chkList
      set curStr to item ap of mStrList
      
log curStr
      
if contents of i is not equal to curStr then
        display dialog "エラー:曜日ヘッダーで異常が見つかりました。曜日文字列が正しい順序で並んでいません。" buttons {"OK"} default button 1
        
return
      end if
      
set ap to ap + 1
      
if ap > apLen then
        set exitF to true
        
exit repeat
      end if
    end repeat
  end if
  
  
if exitF = true then exit repeat
end repeat

exitF

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

2008/07/28 奇数かどうかチェック

奇数かどうかをチェックするサブルーチンと、偶数かどうかのチェックを行うサブルーチンの詰め合わせです。

ある意味、そこまで細かい機能モジュールをサブルーチン化しておく意味があるのかどうか、その限界のような気もしますが……使い回しを促進することを考えるなら、このぐらいの機能モジュールがサブルーチンとして存在していてもいいのかもしれません。

スクリプト名:奇数かどうかチェック
set a to 5
set aRes to chkOddNum(a) of me
> true

set b to 8
set bRes to chkEvenNum(b) of me
> true

奇数かどうかチェック
on chkOddNum(aNum)
  set a to aNum mod 2
  
if a = 1 then
    return true
  else
    return false
  end if
end chkOddNum

偶数かどうかチェック
on chkEvenNum(aNum)
  set a to aNum mod 2
  
if a = 0 then
    return true
  else
    return false
  end if
end chkEvenNum

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

2008/07/26 shell sortで入れ子のリストをソート

shell sortのルーチンをいじくり回して、入れ子になっているリスト(例:{{1,”abc”},{2,”cde”}})をソートできるようにしてみました。Bubble SortやMax Sortの5倍、いつも使っているApple製ソートルーチン改の2.5倍高速です。
(more…)

2008/07/25 シェルソート

シェルソートでリストをソートするルーチンです。やっぱり速い(^ー^;; これを入れ子のリストに対応させたら素敵。
(more…)

2008/07/25 挿入ソートを入れ子のリストに対して行う(ソートキー項目指定つき)

挿入ソート(Insertion Sort)のルーチンに手を加えて、昇順/降順のルーチンを別々に用意し、入れ子になったリストをソートできるように書き換え、各リスト項目のどのアイテムをソート用のキーにするか指定できるようになっています。
(more…)

2008/07/25 Insertion Sortでリストをソートする

Insertion Sortでリストをソートします。前出のBubble Sort、Max Sortよりも高速です。300件の乱数リストを用いたところ、Max Sortが10秒、Bubble Sortが9秒、Insertion Sortが7秒という結果が出ました。
(more…)

2008/07/25 Max Sortでリストをソートする

Max Sortでリストをソートするサブルーチンです。あれ? Max Sortってなんだっけ?(汗) Bubble Sortより遅いです……。
(more…)

2008/07/25 Bubble Sortでリストをソートする

バブルソートでリストをソートするサブルーチンです。HDDの中に転がっていたものなので、出所はどこだったか覚えていないのですが……MLだったような。
(more…)

2008/07/21 書式設定したセルから情報を取り出して調べる

Excel 2008で、表中のセルに対してGUIから書式設定した内容を調べるサンプルです。
(more…)

2008/07/21 セルの文字列を取得する

Excel 2008で、valueによって値を取得するのと、string valueによって文字列(文字フォーマットに影響を受ける)を取得するのとで、結果が異なることを把握するためのサンプルです。
(more…)

2008/07/21 指定範囲の値を取得する

Excel 2008で、指定範囲(range)の値を取得します。
(more…)

2008/07/21 指定セルの値を取得/設定する

Excel 2008で、指定セルの内容(value)を取得したり設定したりするサンプルです。
(more…)

2008/07/21 条件を指定してセルを抽出する

Excel 2008で、Rangeオブジェクトの中から、条件を指定してセルを抽出します。
(more…)

2008/07/20 指定範囲のセルを選択状態にする

Excel 2008で、指定範囲のセルを選択状態にします。
(more…)

2008/07/20 複数の選択範囲(areas)を取得する

Excel 2008で、Control+Option+クリックで複数の範囲を選択できますが……それを取得するScriptです。
(more…)

2008/07/20 Unionコマンドで複数の範囲を同時に使う

Excel 2008には複数の範囲を同時に指定するためのオブジェクトとして、range1からrange30までの予約語が用意されています。30個までの範囲を一意に指定するrangeを作成して、操作することが可能です。ただ……あまりこの予約語はスマートではありませんね。
(more…)

2008/07/20 active cellが属するentire rowを取得する

Excel 2008で、現在選択中のセルが属する行全体(entire row)を取得します。
(more…)

2008/07/20 現在のactive cellを基準にしてほかの位置のセルを扱う

Excel 2008で、現在選択中のセルを基準としてほかのセルを相対的に指定するScriptです。
(more…)

2008/07/19 dateコマンドから生成した日付テキストから、ASのdateオブジェクトを生成する

dateコマンドから生成した日付のテキストからAppleScriptのdateオブジェクトを生成するサブルーチンです。dateコマンドでYYYYMMDDの形式のテキストを作っておいたものの、それをもとにdateオブジェクトを生成しなくてはならない、といった用途に使いました。

そんな用途はともかくとして、dateオブジェクトを生成する方法が少々風変りなので、覚えておいて損はないと思います。

→ 本Scriptは、一定の日付変換時に問題があることが判明しているため、使用しないでください(書籍:「AppleScript最新フリファレンス Ver.2」P-167 「current date」の項目 をご参照ください)。

スクリプト名:dateコマンドから生成した日付テキストから、ASのdateオブジェクトを生成する
set aDateStr to do shell script date +%Y%m%d
set aDateObj to makeDateObjFromStr(aDateStr) of me
> date “2008年 7月 15日 火曜日 1:53:37 PM”

dateコマンドから生成した日付テキストから、ASのdateオブジェクトを生成する
on makeDateObjFromStr(aDateStr)
  set aDateObj to current date
  
set year of aDateObj to (text 1 thru 4 of aDateStr) as number
  
set month of aDateObj to (text 5 thru 6 of aDateStr) as number
  
set day of aDateObj to (text 7 thru 8 of aDateStr) as number
  
return aDateObj
end makeDateObjFromStr

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

2008/07/18 GUI Scriptingのenable/disableを取得する

UI Element Scripting(GUI Scripting)が有効になっているかどうかを調べるAppleScriptです。UI Element Scriptingといえば、もうただ黙ってPrefab UI Browserを買えという話にしかならないのですが、このPrefab UI Browserが書き出すUI Scriptingの調査用コードというやつが、Mac OS X 10.5(日本語環境)ではそのままでは動かないことに気付きました。

そこで、エラーが出ないように、Mac OS X 10.4でも10.5でも動くように書き換えてサブルーチン化したのがこれです。

prefs.jpg

スクリプト名:GUI Scriptingのenableを取得する
retGUIScriptingEnabled() of me

GUI Scriptingの設定判定。10.4/10.5対応
on retGUIScriptingEnabled()
  set v2 to system attribute sys2 > 4, 5
  
  
Mac OS X 10.4以上なら実行
  
if v2 > 3 then
    tell application System Events
      set anUIe to UI elements enabled
    end tell
    
    
if anUIe = true then
      return true UI Element Scripting (GUI Scripting)がイネーブルならtrueを返す
    else
      beep
      
display dialog UI Element Scriptingが有効になっていません。 & return & return & 「システム環境設定」の「ユニバーサルアクセス」で、「補助装置を使用可能にする」のチェックボックスにチェックを入れてから再実行してください。 with icon stop
      
if button returned of result is OK then
        tell application System Preferences
          activate
          
set current pane to pane com.apple.preference.universalaccess
        end tell
        
return false
      end if
    end if
  end if
end retGUIScriptingEnabled

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

2008/07/15 PDFのページ数を数える

指定のPDFのページ数を数えます。この手の処理を行うには、GhostScriptやらpdftkをインストールして、というのがお約束のやり方です。また、Acrobat Professionalを使ってページ数を数える、というのも一般的な方法でしょう(ふつうのAcrobat Readerは、AppleScript用語辞書が見えるのにAppleScriptからのコントロールを拒絶します)。

Acrobat Professionalは高いし、GhostScriptやらpdftkがあまねくすべてのマシンにインストールされているわけではないため、もうちょっと違うアプローチを試してみたのが本Scriptです。

なんと、Preview.appでオープンしてタイトルバーの文字列を取得して、文字を切り抜きしてページ数を取得するとかいう、えらく強引な方法でやってみました。10.4.11と10.5.4で動作確認してあります。こんな方法がいいとは思わないのですが、AppleScriptからPDFのページ数を調査する手段が限られているため、「ないよりはマシ」といったレベルのScriptです。

ただし、GUI Scriptingがオンになっていないと動作しませんし、日本語環境以外では動きません。

→ こちらのほうがおすすめです(10.5以降)

スクリプト名:PDFのページ数を数える v2
set a to choose file
set pNumStr to getPDFPages(a) of me
set pNum to pNumStr as number

指定PDFのページ数をPreview.appを使って数える。要・GUI Scriptingオン
Mac OS X 10.4および10.5対応
ただし、日本語環境であることが動作の前提条件
on getPDFPages(aFile)
  tell application Preview to open aFile
  
activate application Preview
  
tell application System Events
    tell process プレビュー
      tell window 1
        set aTitle to title
      end tell
      
keystroke w using command down
    end tell
  end tell
  
  
set v2 to system attribute sys2
  
if v2 = 4 then
    Mac OS X 10.4.xの場合
    
set pRes to trimStrings(aTitle, “, ページ)“) of me
  else if v2 = 5 then
    Mac OS X 10.5.xの場合
    
set pRes to trimStrings(aTitle, /“, “) of me
  end if
  
return pRes
end getPDFPages

任意の文字列から指定開始子、指定終了子でトリミングした文字列を取り出す
あんまり出来がよくないのでちょっと直した
on trimStrings(aString, fromStr, endStr)
  set fromLen to length of fromStr
  
set eLen to length of endStr
  
  
set sPos to offset of fromStr in aString
  
set body1 to text (sPos + fromLen) thru -1 of aString
  
set ePos to offset of endStr in body1
  
set body2 to text 1 thru (ePos - 1) of body1
  
  
return body2
end trimStrings

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

2008/07/15 空のplistファイルを指定パスに作成するv2

plistファイルを作成するAppleScriptです。Mac OS X 10.4でも10.5でも動作します。10.5上でだけ動けばいいAppleScriptというのはありえないので、こちらのほうがおすすめです。

任意のパスへのplistファイルの生成も、分ってしまえば「なああああんだ」というレベルの内容でしかないのですが、海外でも情報が極端に少ないので唐突に行おうとすると、かなりてこずらされます。

もし、すでにplistファイルに書き込みたい内容が存在しているのであれば、(ダミーではなく)いきなりdeaults writeコマンドで書き込みを行ってもよいでしょう(検証済み)。

スクリプト名:空のplistファイルを指定パスに作成するv2
Original By Phillip Aker
Mac OS X 10.4でも10.5でも動作する

とりあえず、ダミーで何かひとつ要素を(hogehoge)指定しておかないとダメらしい
do shell script defaults write ~/Desktop/some hogehoge -dict

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

2008/07/15 空のplistファイルを指定パスに作成する

各種設定情報を保存しておく、Mac OS X標準のファイル形式である「.plist」ファイルを指定パスに作成します。探してみたら、意外と情報が少なかったので難儀しました。また、本スクリプトはMac OS X 10.4では動作せず、10.5が必要です。10.4でも10.5でも動作するplist作成場合にはv2の方をどうぞ。

スクリプト名:空のplistファイルを指定パスに作成する
Mac OS X 10.4上では動作しない。10.5のみ動作

set dtPath to path to desktop from user domain
set fPath to (dtPath as string) & "test.plist"
set fPath to fPath as Unicode text
set fPOSIXpath to POSIX path of fPath

plistファイルの作成
tell application "System Events"
  set thisFile to make new property list file with properties {name:fPOSIXpath}
end tell

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

2008/07/08 現在の行のセルの高さを変更する

Excel 2008で、現在の行のセルの高さを変更します。幅はcmなのに、高さはポイント数で指定します。
(more…)

2008/07/06 現在の列のセル幅を変更する

現在選択中のセルの幅を変更します。
(more…)

2008/07/06 指定rangeからの相対指定でrangeを取得する

Excel 2008で、指定したrangeからの相対指定で新たなrangeを取得するAppleScriptです。
(more…)

2008/07/06 単独のセルをA1形式で指定

Excel 2008のワークシート上の任意のセルをA1形式で指定します。
(more…)