FileMakerでWordファイルを出力する(.docx)

## はじめに

FileMakerでWordファイルの出力をしたい！でもFileMakerの標準機能では出力できない！
どうしたらいいんだ～！！ と試行錯誤した経過の記録です。

そもそもWord出力する必要ある？というツッコミはごもっともですが、弊社には先方が指定するテンプレートに合わせてWord文書を作成するお仕事がいっぱいあるのです。[^1] それ以外にも社内にある膨大な帳票…すべてFileMakerのレイアウトで再構築するのは大変！このWordファイルを利用したい！ですよね！

[^1]: [申請書類の書き方ガイド](https://www.pcinfo.jpo.go.jp/guide/DocGuide.htm)

## プラグインの導入

色々試した結果、[「360Works Scribe」](https://360works.com/filemaker-pdf-plugin/)というプラグインにたどり着きました。
導入や費用についてはこちらの記事が詳しいです。有料プラグインですが、無料のデモバージョンがあります。
[FileMaker - Microsoft Word / Excel 連携 - p388cell](https://note.com/filemaker/n/n23dd2bc895c5)


## 概要

ある案件についてWord文書を作成するという状況を考えます。
FileMakerにはdocx形式の帳票テンプレートが格納されていて、帳票テンプレートには【hoge】のように隅付き括弧で囲まれたテキスト(帳票代名詞)が書かれています。[^2] この帳票テンプレートの【hoge】部分(帳票代名詞)をひたすら置換するというロジックです。

帳票テンプレート

<img width="300" alt="帳票テンプレート" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1140682/484832c4-d6bb-4d55-eab6-a7bea9108c79.png"> 
↑これが ↓こうなる
出力結果
<img width="300" alt="出力結果" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1140682/0828e564-c489-71a9-757f-5ebab2f0ef52.png">



[^2]: 置換できればよいので、帳票代名詞はかならずしも隅付き括弧で囲む必要はありません。しかし、意図しない置換を防ぐため何かの記号をつけることをおすすめします


## 下準備

1. テーブルを作成

| テーブル名 | 
|:--|
| 案件  | 
| 顧客マスタ  |
| 帳票テンプレートマスタ  |
| 帳票代名詞マスタ  |

   - 案件
<img width="300" alt="テーブル" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1140682/42c78304-edb0-8d23-15b6-b6422592b3ce.png">

   - 顧客マスタ
<img width="300" alt="テーブル" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1140682/6b390c5b-1ab3-1e3b-4389-bc66d7862773.png">


   - 帳票テンプレートマスタ
<img width="300" alt="テーブル" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1140682/56d5f5ea-7d72-58ba-5e9b-cdeb4fd46647.png">

   - 帳票代名詞マスタ
<img width="300" alt="テーブル" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1140682/bc7767f6-4126-d686-1130-81cea47d17ce.png">

2.リレーションを設定
<img width="300" alt="リレーション" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1140682/8ac6cfba-760f-2c28-532c-cd3d94bd7284.png">
3. レイアウトを作成

|レイアウト名| 備考 |
|:--|:--|
| 案件_detail  | 表示用  |
| 顧客マスタ_list  | 表示用 |
| 帳票テンプレートマスタ_list  |表示用 |
| 帳票代名詞マスタ_list |表示用 |
| Ca001_案件 帳票代名詞登録用_prg | 置換に使うフィールドが配置されていればOK |
| Ca001_案件_prg | スクリプト用。フィールド配置や見た目はなんでもOK |
| Aa001_顧客マスタ_prg | スクリプト用。フィールド配置や見た目はなんでもOK |
| Ab001_帳票テンプレートマスタ_prg | スクリプト用。フィールド配置や見た目はなんでもOK |
| Ac001_帳票代名詞マスタ_prg | スクリプト用。フィールド配置や見た目はなんでもOK |
 

- 案件_detail

<img width="500" alt="画面イメージ" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1140682/6cd92c81-dbbe-1d1c-c14a-e7dc51800060.png">

- 帳票テンプレートマスタ_list

<img width="300" alt="レイアウト" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1140682/c459164e-e7a7-df6a-b214-09a9fe1b3f06.png"> 

- 帳票代名詞マスタ_list

<img width="300" alt="レイアウト" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1140682/95cd99b8-7ced-cc03-7140-166d66da0a39.png"> 

 - Ca001_案件 帳票代名詞登録用_prg

<img width="300" alt="レイアウト" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1140682/c8187fa9-3e8d-ba10-20de-e1ba96ec272b.png"> 


4.プラグインの登録
上述したプラグイン「360Works Scribe」をインストールしてください。


## スクリプト
スクリプトは以下の６つ。Windowsなのでスクリプトをテキストで貼ることができない。
画像で貼っちゃうよ！

| スクリプト名 | 
|:--|
| 帳票代名詞マスタの更新【Btn】  | 
| 帳票代名詞グローバル変数設定【Sub】   | 
| 帳票出力開始【Btn】  | 
| 帳票テンプレ―トの決定【Sub】  | 
| 帳票出力実行【Sub】  | 
| ウインドウを閉じる【Btn】 |  

- 帳票代名詞マスタの更新【Btn】

<img width="300" alt="スクリプト" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1140682/845547ab-2aba-c553-c94c-3de0f4a5c7eb.png"> 
<img width="300" alt="スクリプト" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1140682/5c255e90-d3fc-c4d2-d33e-96cd162ae4b2.png"> 

- 帳票代名詞グローバル変数設定【Sub】 

帳票代名詞マスタの内容をグローバル変数に格納します。弊社では頻繁にWord出力するのでグローバル変数($$帳票代名詞Json)を利用しましたが、グローバル変数を使いたくないとかWord出力の頻度があまり高くないなら、Word出力のたびにローカル変数($帳票代名詞Json)を算出してスクリプト結果で受け渡しても問題ありません。
 <img width="300" alt="スクリプト" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1140682/9afe1079-7022-8b33-aa77-91a23baff3e5.png"> 

31行目の内容は

```
JSONSetElement (  $帳票代名詞Json 
  ;[ "帳票代名詞["& $JsonCnt &"].帳票代名詞" ; Ac001_帳票代名詞マスタ::帳票代名詞 ; JSONString]
  ;[ "帳票代名詞["& $JsonCnt &"].フィールド名" ; Ac001_帳票代名詞マスタ::フィールド名 ; JSONString]
 )
```
- 帳票出力開始【Btn】
 <img width="300" alt="スクリプト" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1140682/9979dc98-bc11-b9ef-01ff-ec1e2f19dd93.png"> 


- 帳票テンプレートの決定【Sub】
 <img width="300" alt="スクリプト" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1140682/1f61c60c-abd9-5530-e89e-bdfac6791840.png"> 


- 帳票出力実行【Sub】 

 <img width="300" alt="スクリプト" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1140682/706330de-fba9-b0ef-fcc8-4248b445059e.png"> 
 <img width="300" alt="スクリプト" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1140682/f54294a5-35c6-a167-a245-bbab1abdc39c.png"> 
77行目のReplaceTextの内容は

```
Let ( 
     [
       %フィールド名 = JSONGetElement ( $$帳票代名詞Json  ; "帳票代名詞[" &  $JsonCnt & "].フィールド名" ) ;
       %フィールド内容 = GetField( %フィールド名 ) ;

       //日付タイプなら年月日の形式にする
       %フィールドタイプ = FieldType ( Get ( ファイル名 ) ; %フィールド名 ) ;
       %フィールド内容 = Case( 
                           PatternCount( %フィールドタイプ ; "Date" ) > 0 ; 
                           Year(%フィールド内容) & "年" & Month(%フィールド内容) & "月" & Day(%フィールド内容) & "日" ;
                           %フィールド内容
                          );
       %end = ""
     ]; 
     %フィールド内容
    )

```


- ウインドウを閉じる【Btn】

 <img width="300" alt="スクリプト" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1140682/e119f1de-f6f8-b582-f615-afb836b638c0.png"> 


## 工夫したところ

案件情報はフィールド名を指定することにより取得しています。しかし、このフィールド名を気分で変えたくなるので、帳票代名詞マスタにフィールドIDを格納しておき、フィールドIDに基づいてフィールド名を更新できるようにしました。後はJsonを使ってみました。


## おわりに
上記は、案件テーブルとその関連テーブルの内容を置換するだけですが、スクリプトをいじれば「案件テーブル」「ユーザテーブル」「当社情報テーブル」といった関連していない複数のテーブル内容を変換することもできます。また、すべての帳票代名詞を力技でゴリゴリ置換してますが、Wordのコンテンツコントロールという機能を使えば必要なものだけ置換することもできます。複数の案件を選択して、リスト形式のようなWord文書を作成することもできます。私は使っていませんが、プラグインはExcel出力やPDFでのOCRにも対応しているようです。

サンプルファイルアップロードしようとおもったらできなかった。これで見られるかな？
レイアウトとかは適当なのだ
https://www.dropbox.com/s/msg5mclryhyl5ux/%E5%B8%B3%E7%A5%A8%E4%BD%9C%E6%88%90.fmp12?dl=0

用語がおかしいよとか理解が間違ってるよというツッコミがあれば教えてください！