Database Events (3)

前々回は、データベースを作成しました。前回は、データベースにデータを追加してみました。今度は、データを利用してみます。前々回、前回で作成した都道府県データベースを使っていますので、まずは、そちらを参照してみてください。

Database Events には、データの操作に関する命令なんかは用意されていません。ですので、ソートや検索などは AppleScript の機能を利用して行うことになります。record の name 属性に県名を指定しておいたので名前参照でレコードを指定することができます。

Script Editor で開く

set theFolder to path to documents folder as Unicode text
set databaseFile to POSIX path of (theFolder & "データベース:MyDatabase.dbev")

tell application "Database Events"
    tell database databaseFile
        record "愛知県"
    end tell
end tell

範囲参照や全要素参照、任意参照、中央参照、番号参照も使うことができます。おおむねほとんどの参照方法を利用できますが、やはり、一番強力なのはフィルタ参照でしょう。以下のようにすることで人口 400 万人以上の県名だけを取得することができます。

Script Editor で開く

set theFolder to path to documents folder as Unicode text
set databaseFile to POSIX path of (theFolder & "データベース:MyDatabase.dbev")

tell application "Database Events"
    tell database databaseFile
        name of records whose value of field "population" of it is greater than 4000000
    end tell
end tell

--> {"北海道", "埼玉県", "千葉県", "東京都", "神奈川県", "愛知県", "大阪府", "兵庫県", "福岡県"}

何人以上、何人以下ということも可能です。指定する field を変更することで文字列でフィルタ参照を行うことももちろん可能です。

Script Editor で開く

set theFolder to path to documents folder as Unicode text
set databaseFile to POSIX path of (theFolder & "データベース:MyDatabase.dbev")

tell application "Database Events"
    tell database databaseFile
        name of records whose name of it contains "川"
    end tell
end tell

川の字の入っている県名だけを抜き出しています。フィルタ参照を利用することでデータの取得はかなり柔軟に行えると思います。問題は、ソートですね。AppleScript にはソートの命令がないので自前でソートのハンドラを作るか、シェルの sort コマンドを利用するのが最も手早い解決になります。例えば、人口 400 万人以上の県を人口でソートして結果を返す、といったことを行ってみましょう。

Script Editor で開く

set theFolder to path to documents folder as Unicode text
set databaseFile to POSIX path of (theFolder & "データベース:MyDatabase.dbev")

tell application "Database Events"
    tell database databaseFile
        -- 人口 400 万人以上を抽出
        set theResult to value of field "population" of (records whose value of field "population" of it is greater than 4000000)
        -- 結果の比較用のリストを作成
        set beforeSortList to name of records whose value of field "population" of it is greater than 4000000
        --ソートし、人口が多い順に結果を反転
        my simpleSort(theResult)
        set theResult to reverse of theResult

        -- ソートした結果を元にレコードを取得
        set sortedList to {}
        repeat with thisValue in theResult
            set thisRecord to (records whose value of field "population" of it is (thisValue as integer))
            set end of sortedList to name of (item 1 of thisRecord)
        end repeat

        --結果を比較(分かりやすいように県名で)
        {beforeSortList, sortedList}
    end tell
end tell

on simpleSort(theList)
    -- 昇順
    set scoreCount to count theList -- リスト内の数   
    set sortedCount to 1 -- ソート済みの最初の範囲

    repeat while sortedCount < scoreCount
        set minimumIndex to sortedCount
        repeat with i from sortedCount to scoreCount
            if item minimumIndex of theList > item i of theList then
                set minimumIndex to i
            end if
        end repeat
        set temp to item minimumIndex of theList
        set item minimumIndex of theList to item sortedCount of theList
        set item sortedCount of theList to temp
        set sortedCount to sortedCount + 1
    end repeat
end simpleSort

ソートする項目が少ないので AppleScript だけで行っています。最初に人口のリストを取得しています。このリストをソートし、ソートした結果を元に繰り返しでフィルタ参照で目的の record を探しています。これで人口 400 万人以上の県を人口の多い順にソートした結果になります。ちなみにシェルの sort を使って同じ結果を取得するには、次のような方法があります。

Script Editor で開く

set theFolder to path to documents folder as Unicode text
set databaseFile to POSIX path of (theFolder & "データベース:MyDatabase.dbev")

tell application "Database Events"
    tell database databaseFile
        -- 人口400 万人以上を抽出
        set theResult to value of fields of (records whose value of field "population" of it is greater than 4000000)

        -- シェルの sort で使うスペース区切りのデータを作成
        set tmpText to ""
        set lastNum to count theResult
        repeat with i from 1 to count theResult
            set theList to item i of theResult

            if i is lastNum then
                set tmpText to tmpText & my listToText(reverse of theList, space)
            else
                set tmpText to tmpText & my listToText(reverse of theList, space) & (ASCII character 10)
            end if
        end repeat
        --return tmpText
        my shellSort(tmpText)
    end tell
end tell

on listToText(theList, delimStr)
    set the AppleScript's text item delimiters to delimStr
    set theText to theList as text
    set the AppleScript's text item delimiters to ""
    return theText
end listToText

on shellSort(theData)
    do shell script "echo " & quoted form of theData & " | sort -nr"
end shellSort

この場合は、最初のフィルタで全ての field の値を取り出しています。結果は、

11680490 東京 東京都
8624045 大阪 大阪府
8324355 横浜 神奈川県
6875723 名古屋 愛知県
6838164 浦和 埼玉県
5863182 千葉 千葉県
5691737 札幌 北海道
5500842 神戸 兵庫県
4955439 福岡 福岡県

このようなテキストになります。あるいは、このソートの方が使い勝手がいいかもしれません。いずれにしても AppleScript にソートがないために少しばかりスクリプトの手数が必要になってきます。

0 件のコメント :

コメントを投稿