Filemaker のブログ記事

ライセンス関連でごにゃごにゃもめとるCodeigniter(以下CIと略す)ですけど、
まぁ基本商用においては問題なさそうなので、
仕事では引き続き使っている案件もあります。

なんだかんだ、CIは高速で便利なPHPフレームワークです。
2.0以降CLIからの実行も考慮されていて
http://codeigniter.jp/user_guide_ja/general/cli.html
ローカルアプリケーションを作るのにおいても、結構活躍してくれます。

PHPでFileMakerへODBC接続して、データを取得してこなければならない仕事があるので、
CIでどうにかならんかなと思ってやってみた次第。

結論

$db['default']['hostname'] = 'Driver=FileMaker ODBC;Host=localhost;PRT=2399;database=データベース名;UID=ユーザーID;PWD=パスワード;';
$db['default']['username'] = '';
$db['default']['password'] = '';
$db['default']['database'] = '';
$db['default']['dbdriver'] = 'odbc';
$db['default']['dbprefix'] = '';
$db['default']['pconnect'] = TRUE;
$db['default']['db_debug'] = TRUE;
$db['default']['cache_on'] = FALSE;
$db['default']['cachedir'] = '';
$db['default']['char_set'] = 'utf8';
$db['default']['dbcollat'] = 'utf8_general_ci';
$db['default']['swap_pre'] = '';
$db['default']['autoinit'] = TRUE;
$db['default']['stricton'] = FALSE;

これで接続できます。
で、

上記のCLIからのCIの利用を参考に

php index.php controller_name method_name

これで起動できます。

FileMakerからはpetaexecuteプラグインなどを利用すれば標準出力を取得できるので、なかなか面白いアプリケーションがつくれそうです。

なんども私のブログで出てきましたが、FileMakerで利用できるSQLは、SQL標準に従ってない部分もあります。
したがってSQLを実行する際は、ActiveRecordは使わずにSQL直書きする方が無難でしょう。

ひさびさのなでしこ×FileMakerネタです。

随分前に、なでしこからFileMakerにODBC接続するネタをかきまして、
久々にその方法でFileMaker11に接続しようとしたら、
少し方法が変わってましたので、改めて、メモです。

ODBCの有効化の仕方などはこちらを参考に


CONNECTSTRは、
『DRIVER=FileMaker ODBC;』 &
『Host=localhost;』 &
『PRT=2399;』 &
『database=データベースファイル名;』 &
『UID=ユーザー;』 &
『PWD=パスワード;』

//接続
CONNECTSTRでADO開く。

 
こんな感じです。

データベースファイル名のところは、拡張子を取り除いたものを入れます。
以前と項目名が違ったり、ドライバのバージョンを気遣う必要がなくなりました。
 
毎度のごとく、全角ファイル名はそのまま書くとエラーです。
未検証ですが、今回もUTF-8NでURLエンコして、小文字を大文字に変えたものを入れればOKだと思われます。

何かの役に立てば。
 


 
余談ですが、SELECTは、相変わらず、DBソフトとは思えぬ重さですw

FileMakerで外部の言語やスクリプトと連携するときに、
FMのファイルのパスを取得したいことが結構ある。
 
ただ、FMの標準関数で取得できるのは、FM独自のパス構造で、
書き換えが必要。そんな時のスニペット

Mac用がこちら

Let (
$path = Substitute ( Replace ( Get ( ファイルパス ) ; 1 ; 5 ; "" ) ; "/" ; ¶ ) ;
"/Volumes" & Substitute ( LeftValues ( $path ; ( ValueCount ( $path ) - 1 ) ) ; ¶ ; "/" )
)

でWin用がこちら

Let (
$path = Substitute ( Replace ( Get ( ファイルパス ) ; 1 ; 5 ; "" ) ; "/" ; ¶ ) ;
Substitute (MiddleValues ( $path ; 2 ; ( ValueCount ( $path ) - 2 )  ) ; ¶ ; "\\" )
)

これでFMのデータベースファイルのある
ディレクトリパスが(絶対パス)取得できます。
 
スタンドアロンで動いていることを前提としています。
サーバーで使う場合は、パス構造がかなり違うので、
ご注意ください。

独立に際して、FileMakerで顧客管理/タスク管理/請求書類を一括管理できるDBを作っています
これまではクライアントとの兼ね合いで、WindowsでFileMakerDBを構築していましたが
今回は自分のDBということで自分の環境に合わせてMacで構築することにしました。

こういうDBを構築するとき、FM自体や、FMから出力したデータをもとにHTMLベースで
帳票関連を出力する方が多いと思いますが
個人的には、その方法はあまり好きではないです。
これらの方法を使うと、出力した帳票が固定したフォーマットになってしまい、
運用で例外のフォーマットに対応ができなくなるためです。
僕は、DBはあくまでデータ管理に徹底して、
帳票関連はエクセルやOpenOffice.orgなどに出力して表示する方法をとります。


Windowsでは、なでしこプラグインを使ったり、
Event送信で、あらかじめ作っておいたWSHファイルを起動したりすれば、
比較的簡単にエクセルやOOoを操作できます。


Macはどうでしょうか。
さすが、FileMakerです。Appleの子会社なだけあって、
AppleScriptの操作体系はかなり完璧に操作できます。
FileMakerのスクリプトでAppleScriptを実行できるので、
http://karaiblog.blog45.fc2.com/blog-entry-201.html
この方法を使えば、比較的簡単に、エクセルへデータを流し込むことができます。

Mac素敵!


…なんですが…ここはドMなプログラマ根性を発揮して、
ShellとLLでどうにかできないか考えてしまいました。

いろいろ調べた結果、様々なLLでエクセルファイルをごにょごにょするライブラリは出てますが、
テンプレート読み込み→データ流しこみ→別ファイルへ出力
ということをやろうと思うと、
エクセル側のバージョンアップに追いついていなかったり、
日本語処理が十分でなかったりと、
使えるレベルのライブラリはありませんでした。
 


じゃあ、規格がオープンであるOpenOffice.orgならどうなんだろうということで調べたら、
Perlにライブラリがありました。
OpenOffice::OODocです。

ざっと読むと
テンプレート読み込み→データ流しこみ→別ファイルへ出力
ができるじゃないか!
 


というわけで、使ってみました。

!!っが!!

いろいろ問題が。

基本的な使い方は、CPANでOpenOffice::OODocをインストールしたうえで、

#!/usr/bin/perl -w
use strict;
use utf8;
use Encode;
use OpenOffice::OODoc;

my $doc = odfDocument( file => 'テンプレート.ods' );#テンプレートファイル読み込み

#A1へデータを流しこむ
$doc->updateCell( 'Sheet1', 1, 0, 'text' );

#A2へデータを流し込む
#数字の場合は型指定が必要
$doc->cellValueType( 'Sheet1', 2, 0, 'float' );#型指定
$doc->updateCell( 'Sheet1', 2, 0, 125 );

#ファイル出力
$doc->save('出力先.ods');

どうですか?なんかできそうです。
 
ところがで、OOo3.3で見てみると、
セル結合されているカラムのある行へは、
期待通りのセルへ値が入りません(T_T)
バグなのか、OOoの規格についていってないのかわかりませんが、
どのように値がはいるかいちいちトライしてみる必要があります。

どういうわけだが、何がなんでも値が入らないセルとか、
繰り返し値が入ってしまうセル番号もあります。。。
そういうときは、カラム挿入をしてズラしてやったりなどする必要があります。


まぁそんなこんなで何度となくトライして数時間。
期待通りの場所へ値が入るようになって、
FMから出力したCSVをパースして値を流しこんで帳票完成。

よかったよかった。
 
でも面倒!!Σ(ー◇ー;!!


あとは、FMのスクリプトからシェルを起動すれば、帳票データ完成です。

シェルは、AppleScriptで、

do shell script "perl スクリプトファイル"

とか、

do shell script "cd スクリプトファイルのディレクトリ;perl スクリプトファイル"

とかすればOK。
 
注意点として、AppleScriptからのシェル起動の場合、
@INCの中身がターミナルからの起動と差異がある場合があるので、
AppleScriptがエラーを吐き出す場合は、
use libなどしてモジュールを探すディレクトリを追加してやってください。

 
だったら全部AppleScriptでやれよ!Σ(ー◇ー;!!


そして、最後に作った帳票データをFMのスクリプトから自動起動しましょう。

AppleEventからファイルを指定して起動しようとしたところ、
どうもうまくいきません。
どうやらOOoにファイルパスがうまく渡っていないようです。

というわけで、こちらもシェルで。

do shell script "open /Applications/OpenOffice.org.app ファイルパス"

ってやれば、無事起動できました。



今日の教訓!
極力AppleScriptでやることを考えよ!!

去る2010/11/20 FileMaker中部ユーザーグループ(FM-Chubu)にて、
ESSとMySQLの接続/連携について、40分ほど、
おはなしをさせていただきました。
 
内容については、
わざわざ遠方からご参加いただいた方もいらっしゃいますので、
掲載は控えさせていただきます。
 
ご参加されるみなさんのESSに対する興味や、理解度などがはかれなかったので、
ちょっと短めにして、
好きなときに話を止めてもらえるようにしたり、
質問を長めにとったのですが、正解でした。
 
非常に突っ込んだ内容でご質問をいただき、
FileMakerのESSへのみなさんの興味/期待を感じました。
 

ご質問いただいた中でODBCドライバについてのご質問がありましたが、
失念していた部分もありましたので、補足させていただきます。
 
FileMakerの公式に案内があります。
http://www2.filemaker.co.jp/fmi/xsl/techinfo/browserecord.xsl?AnswerID==7040
 
補足として、
Windowsで64bitOSを利用している場合は、
コントロールパネルに表示されるODBCマネージャーから登録はできません。
C:\Windows\SysWOW64\odbcconf.exe
から設定を行います。
 
今回利用いたしました、スライドをDLできるようにしておきました。
http://agilmente.com/wp-contents/uploads/fmchubu11.pdf
 
今回皆さんありがとうございました!

なでしこには、変数を破棄する命令がありません。(ないんだよね?)
 
普通になでしこ単体でプログラムを組む分には、
なでしこは定型処理ツールに近く、何度も変数を使うということがないので、
ほとんど問題にはならないのですが、
Filemakerプラグインで使う場合は、
メモリ上に常駐させて使いまわすケースが個人的に多く、
配列やハッシュを使いまわす場合など、結構困ります。
 
ということで、どうしたらいいんだろうと思って、いろいろ考えた結果、
 

ARRAYとは文字列。
ARRAY = 「」。
ARRAYとは配列。

 
このように、一旦文字列型などにしてしまうことで、
配列を再初期化できます。(というより、多分内部的には再生成している)
 
これ使わないと、FileMakerのLoopと組み合わせる時とか、苦しい・・・。

昨日のファイルメーカーランタイムの記事のWindowVista版についておはなし。
 
何がしたいかは、昨日の記事を御覧ください。
 
基本的には対策はWindows7と同じでOKですが、
WindowsVistaは御存知の通り、到底出来のいいOSとは言えないOSで、
セキュリティ面に関しては、行き過ぎなところと、
逆に全然行き届いてないところがあります。
なんというか、非常に雑な印象を持ちます。
そりゃ、マイクロソフトにとっても黒歴史になりうるものだと思います。
(↑言いたい放題)
 
それはさておき、では、Filemakerのランタイムをインストーラーとして用意したとき、
WindowsVistaで起こりうる問題についてお話します。
 
前述の通り、基本的にはWindows7と同じでいいです。
 
が、ひとつ問題が。これは環境差があるようで、発生するマシンとそうでないものがありました。問題になった場合の対応策として考えてください。
 
ランタイムを起動したとき、データが更新するタイミングで、
ランタイムアプリケーションがフリーズする現象に見舞われることがあります。
 
これに3ヶ月近く悩まされていたのですが、
ようやく対応策がわかりました。
 
WindowsXP SP2以降、Windowsには、DEPという機構が設けられています。
(決して某県刈谷市にあるプロレス団体のことではないwww)
 
これがどうも悪さをしていたようです。
詳しい説明をすると、アホみたいに話が難しくなるので、
割愛しますが、DEPをWindowsの設定により、
明示的にランタイムアプリケーションに対して除外設定を行うことで、
このフリーズ現象が回避できました。
 
しかし、WindowsXP SP2以降で導入されている機能にも関わらず、
なぜWindowsVistaでのみそのような現象が起きているのかワケが分かりません…。
 
そして、どういうわけか、DEPの設定での回避は
サービスパックの最新版を適用していないと、
うまく回避が出来ませんでした…これもまた謎です。
 
しかも、サービスパック適用→DEPの設定の順で行わないと、回避できません。
Windowsアプリの専門家ではないので、
頭がオーバーフローしてしまい、
その日は非常によく眠れました(何のこっちゃ。)
 
というわけで、WindowsVistaでFilemakerランタイムを使うにあたって、
このへんは気をつけていきたいものです。


 
現在Filemakerのランタイムアプリケーションと、
なでしこプラグインのランタイム版を使ったアプリケーションを開発中だ。
そのアプリケーションをインストーラーとして固めて配布するときの注意Win7版覚書です。
 
ランタイムアプリケーションは、
Filemaker本体なしで、FMのDBアプリケーションが利用できる有用な機能だ。
(DB構造が変更できないなど制限はある)
ノンプログラマでも、スタンドアロンアプリケーションが作れる。
 
 
ランタイムアプリを作成すると、
フォルダの中に非常に多くのファイルが詰め込まれた状態で、
アプリケーションがアウトプットされる。
普通に使うには、
そのフォルダをデスクトップやマイドキュメントあたりに格納して使えば
特に問題はおきません。
 
しかし、それらをインストーラーとして固めて配布する場合に注意すべき点が多々あります。


  
1)インストール先
ファイルメーカーはデータベースソフトウェアで、
ランタイム版も同様にデータベースソフトウェアです。
データベースならば、当然、アプリケーション自体または付属のファイルに
利用する都度ファイル保存や書き換えが行われます。

通常アプリケーションの格納場所は
C:¥program files¥
だと思うのですが、
このディレクトリの下にあるファイルは、
通常ユーザーではファイルの保存や変更はアプリケーションから行うことができません。
つまり、Filemakerのランタイムアプリでは、
レコードの追加やフィールドの変更など、
データベースとして重要な機能を使えず、
ReadOnlyなデータベースアプリケーションになってしまうというわけです。
 
これでは話になりません。
 
ということで、Filemakerランタイムアプリの場合は、
ドキュメントフォルダや、ユーザーデータフォルダなどにインストールするように、
インストーラーを設計した方が吉です。
私の実験では、C:¥直下でも大丈夫だったようですが、
世間的にはあまり推奨されていないようです。
 


 
2)ファイルのコピー
多分、通常のランタイムアプリをインストーラーにする場合は、
1の対応だけで問題ないはずですが、
 

 
今回は、エクセルのテンプレートファイルを用意しておき、
エクセル表示時に表示用のファイルをコピーで新たに作成して、
表示用ファイルへ表示する内容を流し込む。
という動きを自動的に行うよう、
なでしこプラグインによって制御しているのですが、
このコピーという動作は、
たとえ、ユーザーデータフォルダや、ユーザードキュメントフォルダであっても、
UACの制限をうけ、アプリケーションから実行することができませんでした。
 
管理者権限でアプリケーションを実行している場合のみ、
コピーの制御ができるようです。
 
Vistaのときは、いつでも管理者権限でアプリを起動する手段があったようですが、
Win7はどうなんだろう…どっちにしても回り道なのであまり考えたくありません。
 
コピーがだめなら、エクセルを制御しているわけだから、
一度テンプレートのエクセルファイルを開いてしまって、
自動で別名保存するようにすればいいじゃないかと思って、
これも行ってみましたが、拒否されるようです。
(なぜかOpenOffice.orgを制御する場合はそれでいけた)
 
どうしようか…と思って試行錯誤したところ、
なでしこでテンプレートファイルの内容をバイナリとして、
なでしこの変数に保存し、
なでしこでファイルを作成して、そこへ変数に保存されたバイナリを流しこんで保存。
という回りくどい手段を使えば、擬似的にコピーを
UACの影響なしに行えることがわかりました。
 
多分ですが、Win32APIのCopyFile関数がUACの監視下にあるのだと思います。
開いて内容取得→ファイル作る→取得した内容保存
ですと、CopyFileを使うことはないのでUACの影響を受けなかったのではと思います。
 
これはおそらく他の言語とかでも役に立つはず。
 


Win7でFilemaker+なでしこのランタイムアプリをインストーラーで配布する場合は、
とりあえず、以上で今のところ問題点は見つかっていません。
 
Win7は比較的セキュリティは高いのに、仕組みはシンプルなので、
要点を押さえれば、アプリ開発はすんなりいきます。 
問題はVistaです。こっちはハマりまくったので、
また次回レポします。

個人プロジェクトで、
FMランタイムアプリ + なでしこプラグイン
で作ったアプリケーションをインストーラー付きで販売することになった。
 
その際、Vista以降はUACという消えれるか死ぬかすればいい仕組の問題でうまくいかないことが多々あって、色々試行錯誤のうえ、ようやく完成した。その覚書&報告。
 


まず、ランタイムアプリケーション。
FilemakerのAdvancedバージョンで作るのは、FM開発者ならおなじみ。
FMのアプリケーションを、FMなしで動くようにできる仕組みですね。
ランタイムアプリを作成すると、ランタイムフレームワークや起動用EXEファイル、データベースの実体バイナリなどが、
ひとつのフォルダに詰め込まれて作成されます。
 
で、まぁ通常の感覚で言えば、これをそのまま、圧縮して、
インストーラー作成ソフトなどをつかってインストーラー作っちゃえばいいのですが、ひとつ問題があります。
 
通常、アプリケーションは「C:\ProgramFiles\」にインストールするのですが、
UACの働きで、「C:\ProgramFiles\」配下はデータの書き換えが基本的にできません。.exe以外は基本的に読み取り専用です。
したがって、データの書き換えが必要なFMランタイムアプリは読み取り専用のDBになってしまうことを意味します。
 
実際は、レジストリとかいじれば、出来るのですが、インストーラーを走らせている間に、
レジストリをゴニョゴニョして。。。とか正直やってられません。
それに、レジストリを汚すのはイヤです。
 
私の場合、特殊ディレクトリである、アプリケーション設定フォルダにランタイムアプリの実体を全てインストールし、「C:\ProgramFiles\」配下には、アプリ設定フォルダに置かれたランタイムアプリを実行するだけの小さなアプリケーションを作ることで対応しました。
これにより、ランタイムアプリが読み取り専用になってしまうことを防げます。
 
ランタイムアプリを呼び出すだけの小アプリは、なでしこで簡単につくれますし、なでしこの場合は、指定アプリケーションを管理者権限で起動する命令もありますから、なお一層安心してアプリづくりができます。
 


 
次になでしこ。
前述のインストール箇所の問題をクリアできれば、まずほとんどの機能は問題なく動きます。
 
注意したいのは以下。
 
・ファイルコピーは鬼門。使わない方がいい。やるなら、一旦コピー元のファイルを開いて、新規保存する手順を、VBSなどで行うほうが良い。(なでしこにはVBS標準装備)
・なでしこの命令を別プロセスで動かす場合は、Windows標準の各セキュリティ機能に加えて、ノートン先生などにも気を配る必要があることがあるので、極力避けたい。
 
以上の2点です。
別プロセスでなでしこの命令を動かすのは、ランタイムアプリが落ちるのを防ぐなどメリットも沢山あるので、使う場合は、ノートン先生などの設定指示も、アプリケーション配布時に必要になってくるかと思います。
 


 
WindowsXPへのダウングレードが2020年まで保証されてしまったことで、XP/Vista/7 そして次のWindowsと、かなり質の違うWindowsが混在する世の中になってしまいまして(特にUACの部分で)、プログラマとしては非常に腹立たしい事態です。
 
とはいえ、そんなこと言ってても、世の中わからないので、こっちが勉強していかなくてはなりません。
ノンプログラマが使えるFilemakerの世界も同じでしょうねー。
ということで、この記事がFM開発者の方の一助になればと思います。

ここ数カ月FilemakerとMySQLを、
Filemaker9より実装されたESSを使って接続し、
EC向けCMSを作っていました。

そのうえで、いくつかハマってしまったことがあったので、レポ。
(というか、実際は全部不確定要素ですけど・・・。)

まず結論。ESSはそこそこ使えるけど過信はしないほうがよい。


その理由

◆LONGTEXTが使えない??(不確定要素)
LONGTEXTのカラムはFMでは「テキスト」のフィールドとしてマッピングされます。
私の環境ではなぜか、LONGTEXTがTEXTとして扱われ、
65,535バイトで切り捨てられてFM上で表示されました。
DB構築途中でTEXTからLONGTEXTへ変更したのが影響している可能性もあります。
この辺は未確認です。すみません。

 
 
◆リレーションが効かない?
MySQLのテーブルのキーでないカラムに対して、
FMのテーブルとリレーションすることは、
仕組み上できるようになっています。
見た目上一応動きます。
が、MySQL側のレコード数が増えてくるとそれなりに影響が出ます。
たとえば、FMのスクリプト内で、
FMテーブルからMySQLテーブルへ「関連レコードへ移動」をすると、
FMエラー101(レコードなし)が帰ることがあります。
おそらく、MySQL側にインデックスがないためレコードの取得に時間がかかり、
関連レコードなしと判定されるのではと思います。
 
私の場合、MySQLのテーブルにルックアップを指定しておいて、
関連レコードに移動し再ルックアップ。
関連レコードがなければ、FM側のレコードの値を利用して、
MySQL側にレコードを新規作成。
というスクリプトを作っていたのですが、
関連レコードがあるにもかかわらず、なしと判断され、
不要なレコードを作成してしまうケースに悩まされました。

対応策としては、
主キーでリレーションするか、
リレーションしたいカラムにINDEXを作っておくというのが手でしょう。
まぁ、そもそも、キーでもなくINDEXもないカラムでリレーションとか、
プログラマ的にアホすぎるだろって自分でも反省しています。

ちなみにレコードのインポートで、一致するレコードを探すときも同じことがおきます。

私の場合は、なでしこでCOUNT()関数を使って、MySQL側にSQL発行し、レコードがあるかなしかを判定させることでとりあえずその場をしのぎました。

◆MySQLのレコードをロックできない。
まぁ当たり前なんですが、必ず頭に入れておかなければならないことです。
複数人やさまざまなインターフェイスからMySQLのレコードを操作する可能性がある場合は、
FMでどうにかしようというのは考えないほうがいいでしょう。

編集中のフラグをMySQL側のテーブルに用意して、 
そこに何かあるときは編集しないようにすれば一応はいけるでしょう。
ただ、やっぱりこれもFMだけで判定するのはよくないかなと思いましたので、
私の場合は、なでしこでSQL発行して、判断しています。
 
 


 
 
いまのところ私が困ったESSのハマりどころはこんな感じです。

別になでしこ開発コミュニティの回し者ではないですが、
やはり、なでしこプラグインがあることによって、かなり幸せになれます。
Windows版FMのDB構築する上で、なでしこは必須だろうと、改めて思いました。