前回は単一レコードの編集処理について取りあげた。今回は続きとして、繰り返しフィールド・関連先テーブルにあるレコード・フィールドの編集処理について紹介しよう。

繰り返しフィールドの編集方法について

繰り返しフィールドとは、FileMaker独自の考え方だ。通常のフィールドの場合は1つのデータのみしか格納できないが、繰り返しという属性をフィールドにつけることで「繰り返しフィールド」となり、1つのフィールドに設定した数だけのデータが格納できるようになる。

フィールドオプションの「データの格納」タブ内より、最大繰り返し数を設定することで該当フィールドは繰り返しフィールドとなる

繰り返しフィールドにすることで、1レコードの1フィールド内に、複数のデータを格納することができるようになる。わずかな設定をするだけで使える便利な機能だが、その分制約も多い

Webから繰り返しフィールドに対してデータを入力するには、setField, setFieldFromTimestampメソッドの第三引数に「データを格納したいフィールドの繰り返し数-1」の数値を設定する。実際に作成したテキストタイプの繰り返しフィールド「ft_repetitionText」にデータを格納してみよう。

fmapi_edit_test.php

<?php

include_once('../FileMaker.php');

$data = new FileMaker('fmapi_test', 'http://localhost:80', 'admin', 'admin');

$editCommand = $data->newEditCommand('fmapi_edit',20);

$editCommand->setField('ft_repetitionText', '繰り返し[1]に編集', 0);
$editCommand->setField('ft_repetitionText', '繰り返し[2]に編集', 1);
$editCommand->setField('ft_repetitionText', '繰り返し[3]に編集', 2);
$editCommand->setField('ft_repetitionText', '繰り返し[4]に編集', 3);
$editCommand->setField('ft_repetitionText', '繰り返し[5]に編集', 4);

$result = $editCommand->execute();

if (FileMaker::isError($result))
{
    // エラー処理..
    echo 'FileMaker Error Code: ' . $result->getErrorString();
    echo '<p>'. $result->getMessage() . '</p>';
}
else
{
    // 正常処理..
    $records = $result->getRecords();
    ?>
    <table border="1">
        <tr>
            <th>ft_serial</th>
            <th>ft_registTimeStamp</th>
            <th>ft_updateTimeStamp</th>
            <th colspan="5">ft_repetitionText</th>
        </tr>
    <?php
    foreach ($records as $record)
    {
        echo '<tr>';
        echo '<td>' . $record->getField('ft_serial') . '</td>';
        echo '<td>' . $record->getField('ft_registTimeStamp') . '</td>';
        echo '<td>' . $record->getField('ft_updateTimeStamp'). '</td>';
        echo '<td>' . $record->getField('ft_repetitionText',0). '</td>';
        echo '<td>' . $record->getField('ft_repetitionText',1). '</td>';
        echo '<td>' . $record->getField('ft_repetitionText',2). '</td>';
        echo '<td>' . $record->getField('ft_repetitionText',3). '</td>';
        echo '<td>' . $record->getField('ft_repetitionText',4). '</td>';
        echo '</tr>';
    }
    ?>
    </table>
<?php
}
?>

setFieldメソッドの第三引数($repetition)に「繰り返し数-1」の数値をセットし、編集を実行する。繰り返しフィールドからデータを取得する場合は、同様にgetField, getFieldUnencoded, getFieldAsTimestampの第二引数($repetition)に「繰り返し数-1」の数値をセットする。これをWebブラウザで表示してみよう。

fmapi_edit_test.phpをWebブラウザで表示させたところ。繰り返し数-1の値を引数として渡すことで、繰り返しフィールドの特定の箇所にデータを格納・表示することができる

レイアウトに存在しない繰り返し数を指定して編集をおこなうと「Field is missing」エラーが返る。似たエラーにフィールドを配置しないことで起こる「Field Not Found」があるので、間違わないように注意しよう

繰り返しフィールドは手軽に複数データを格納できる便利な機能だが、さまざまな制約がある。たとえば集計に関しては、FileMaker Proのヘルプ「繰り返しフィールドの定義」において次のようなアナウンスがされている。

繰り返しフィールド内の値を集計してレポートを作成するのは簡単ではありません。

このほか繰り返しフィールドはFileMaker独自の考え方ということで、FileMaker以外のデータベースを用いたアプリケーションと連携をおこなう場合に障壁となる可能性がある。

  • 外部アプリケーションとの連携を考慮しないスタンドアロンとして実装する
  • データの統計をおこなわない
  • 繰り返しフィールドに格納する内容は、キーやスクリプト中の定数・計算式で使うといった2次利用をおこなわない

繰り返しフィールドを使用すると最初は楽ができるが、運用がはじまってデータの2次・3次利用利用をしたいときに思うようにデータの整理ができず、苦労しやすい欠点がある。これらの条件がそろわない場合は、繰り返しフィールドは使わずテーブルを分離して別個に管理・ポータルで表示するといった方法をとるのが良いだろう。

繰り返しフィールドの内容をCSVに出力した結果。繰り返しフィールド内は特殊なコードで区切られる

関連レコード・フィールドの編集方法について

リレーション先テーブルのフィールドやポータル内のレコードを編集する場合は、FX.php同様フィールドの前にテーブルオカレンス(TO)名をコロン付けで指定する。まずはそのまま別テーブルのフィールドを配置しているだけのパターンから試してみよう。あたらしく作成したテーブルと、既存テーブルとの関係情報は次のとおり。

今回あたらしく作成したテーブル「fmapi_sub_table」。共通フィールドのほかに、親テーブルのシリアルを格納するfst_ft_serialと、データを格納するfst_text、そしてレコードID確認要のfst_recidを作成した

既存テーブルとのリレーション図。シリアル値のみでリレーションをおこなっている、親子関係のテーブルだ

Webアプリケーションからアクセスするレイアウト「fmapi_edit_2」。関連テーブルの「fst_serial」「fst_text」2フィールドを直に配置している

直に配置している他テーブルのフィールドは、フィールド名の先頭に「(TO名)::」を追加するだけだ。たとえばfst_textに変更をかけたい場合は、$editCommand->setField('fmapi_sub_table::fst_text', ...)となる。実際に編集をおこなうPHPコードは次のとおり。

fmapi_edit_test_2.php

<?php

include_once('../FileMaker.php');

$data = new FileMaker('fmapi_test', 'http://localhost:80', 'admin', 'admin');

$editCommand = $data->newEditCommand('fmapi_edit_2',20);

$editCommand->setField('fmapi_sub_table::fst_text', '関連先フィールドの変更テスト');

$result = $editCommand->execute();

if (FileMaker::isError($result))
{
    // エラー処理..
    echo 'FileMaker Error Code: ' . $result->getErrorString();
    echo '<p>'. $result->getMessage() . '</p>';
}
else
{
    // 正常処理..
    $records = $result->getRecords();
    ?>
    <table border="1">
        <tr>
            <th>ft_serial</th>
            <th>ft_registTimeStamp</th>
            <th>ft_updateTimeStamp</th>
            <th>fst_text</th>
        </tr>
    <?php
    foreach ($records as $record)
    {
        echo '<tr>';
        echo '<td>' . $record->getField('ft_serial') . '</td>';
        echo '<td>' . $record->getField('ft_registTimeStamp') . '</td>';
        echo '<td>' . $record->getField('ft_updateTimeStamp'). '</td>';
        echo '<td>' . $record->getField('fmapi_sub_table::fst_text'). '</td>';
        echo '</tr>';
    }
    ?>
    </table>
<?php
}
?>

このファイルをWebブラウザで表示させてみよう。

fmpi_edit_test2.phpをWebブラウザで表示させたところ。実際に関連先テーブルのフィールド値が書き換わっていることが確認できる

つづけてポータル行に対して変更をおこなう場合だ。ポータル行のレコード・フィールドは、フィールド名末尾に続けて次の文字列を追記する。

  • レコードを登録する場合: 「.0」 (「このリレーションシップを使用して、このテーブルでのレコードの作成を許可」にチェックが入っている場合のみ有効)
  • レコードを変更する場合: 「.(レコードID)」

実際に編集をおこなうレイアウトとPHPコードは次のとおり。

Webアプリケーションからアクセスするレイアウト「fmapi_edit_3」。ポータルにはリレーション先テーブル「fmapi_sub_table」のフィールドを3つ配置した

fmapi_edit_test_3.php

<?php

include_once('../FileMaker.php');

$data = new FileMaker('fmapi_test', 'http://localhost:80', 'admin', 'admin');

$editCommand = $data->newEditCommand('fmapi_edit_3',20);

$editCommand->setField('fmapi_sub_table::fst_text.2', 'ポータル編集テスト1');

$result = $editCommand->execute();

if (FileMaker::isError($result))
{
    // エラー処理..
    echo 'FileMaker Error Code: ' . $result->getErrorString();
    echo '<p>'. $result->getMessage() . '</p>';
}
else
{
    // 正常処理..
    $records = $result->getRecords();
    ?>
    <table border="1">
        <tr>
            <th>ft_serial</th>
            <th>ft_registTimeStamp</th>
            <th>ft_updateTimeStamp</th>
            <th>fmapi_sub_table::</th>
        </tr>
    <?php
    foreach ($records as $record)
    {
        echo '<tr>';
        echo '<td>' . $record->getField('ft_serial') . '</td>';
        echo '<td>' . $record->getField('ft_registTimeStamp') . '</td>';
        echo '<td>' . $record->getField('ft_updateTimeStamp'). '</td>';
        echo '<td>';
        echo '<table border="1">';
        echo '<tr>';
        echo '<th>fst_text</th>';
        echo '<th>fst_recid</th>';
        echo '</tr>';
        foreach ($record->getRelatedSet('fmapi_sub_table') as $portalRecord)
        {
            echo '<tr>';
            echo '<td>' . $portalRecord->getField('fmapi_sub_table::fst_text') . '</td>';
            echo '<td>' . $portalRecord->getField('fmapi_sub_table::fst_recid') . '</td>';
            echo '</tr>';
        }
        echo '</table></td>';
        echo '</tr>';
    }
    ?>
    </table>
<?php
}
?>

このファイルをWebブラウザで表示させてみよう。

fmapi_edit_>test_3.phpをWebブラウザで表示させたところ。ポータル1行目(レコードID: 2)のレコードのみ編集されたことが確認できる

ポータル内のレコードが編集されていることが確認できた。レコードIDさえ事前にわかっていれば、1回で複数レコードの一括編集が可能だ。またポータル内のレコード編集方法についてはPHP API Documentationのほか、fms10_cwp_php_en.pdfにもわかりやすく解説されている。併せて参考したいところだ。

FileMaker API for PHPの基礎編もいよいよ大詰めだ。次回は削除機能について紹介しよう。