2019年10月27日日曜日

FileMaker 18 標準機能でHTMLメール,複数添付ファイルを送信|Send HTML Email with cURL

FileMaker 18 標準機能でHTMLメール,複数添付ファイルを送信
送信先、送信元の表示名設定可能

動作検証
Windows 10
FileMaker 16, 17, 18
(FMP16,17は、外部 cURL を使用)
Windows 10 Ver.1803(RS4)以降は、cURL標準搭載

iOS 13.1.3
FileMaker Go 18

Mac OS 10.13.6
FileMaker 16, 17, 18
(FMP16,17は、外部 cURL を使用)

完成品をダウンロード(\500)
https://fm-aid.stores.jp/items/5db51c8cbc45ac23540f9787
Q&A 不明な点は以下で問い合わせ下さい。
https://fm-aid.com/community/viewforum.php?id=6

          使用方法          




SMTP設定:
 SMTP_Server:SMTPサーバー
 SMTP_Port:25,587,465
 SMTP_SSL:SSL ON=1, OFF=0
 SMTP_account:SMTPアカウント
 SMTP_password:SMTPパスワード
 From_Name:送信元アドレス表示名
 From_address:送信元メールアドレス
BodyTEXT
 メール内容 プレーンテキスト
BodyHTML
 [GetAsCSS]ボタンでBodyTEXTをCSS化、または、任意のHTMLを設定
Attachd File
 添付ファイルを設定
cURL Path
 Windows 10 Ver.1803(RS4)より前の場合、cURLをインストールし、
 curl.exe のフルパスを設定。例:C:\curl\curl.exe

[送信]ボタンでメールが送信されます。

FileMaker 16, 17 の場合、メールメッセージファイルを作成し、外部cURLで送信されます。

          作成方法          

テーブル:

フィールド:





リレーション:

Logs:

Mail_AttachedFile:

レイアウト:

ボタン設定:
 [送信]ボタンに スクリプト:SendMail を設定
 [GetAsCSS]ボタンに フィールド設定 [Mail::BodyHTML; GetAsCSS ( Mail::BodyTEXT )] を設定

     スクリプト     

スクリプト:SendMail
2019/10/28 テキストを挿入 部分のテキストが抜けていたので記述
変数を設定 [ $$Result; 値:"" ]
変数を設定 [ $$dump_header; 値:"" ]
スクリプト実行 [ 「_AttachedFile」 ]
変数を設定 [ $AttachedFile; 値:Get(スクリプトの結果) ]
テキストを挿入 [ 選択; ターゲット:$RawMail ;「Subject: =?utf-8?B?{Subject}?=
To: "=?utf-8?B?{To_Name}?=" <{To_Address}>
From: "=?utf-8?B?{From_Name}?=" <{From_Address}>
Content-Type: multipart/mixed; boundary={boundary}

--{boundary}
Content-Type: multipart/alternative;boundary=1_{boundary}

--1_{boundary}
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: base64

{BodyTEXT}
--1_{boundary}
Content-Type: text/html; charset=utf-8
Content-Transfer-Encoding: base64

{BodyHTML}
{AttachedFile}
--1_{boundary}--
--{boundary}--」 ]
変数を設定 [ $DATA; 値:Substitute ( $RawMail ; [¶ ; Char(13) & Char(10) ] ; ["{boundary}" ; Mail::_k ] ; ["{Subject}" ; Base64EncodeRFC ( 4648 ; Mail::Subject )] ; ["{To_Name}" ; Base64EncodeRFC ( 4648 ; If ( IsEmpty ( Mail::To_Name ) ; Mail::To_Address; Mail::To_Name ) )] ; ["{To_Address}" ; Mail::To_Address ] ; ["{From_Name}" ; Base64EncodeRFC ( 4648 ; If ( IsEmpty ( mail_account::disp_mail_address ) ; mail_account::mail_address; mail_account::disp_mail_address ) )] ; ["{From_Address}" ; mail_account::mail_address ] ; ["{BodyTEXT}" ; Base64EncodeRFC ( 2045 ; Mail::BodyTEXT )] ; ["{BodyHTML}" ; Base64EncodeRFC ( 2045 ; If ( IsEmpty ( Mail::BodyHTML ) ; Mail::BodyTEXT; Mail::BodyHTML ) )] ; ["{AttachedFile}" ; $AttachedFile] ) ]
#アプリケーションバージョン チェック $App,$Ver
変数を設定 [ $er; 値:Let([ $App_Ver=Get (アプリケーションバージョン) ;$App_Ver_List=Substitute ( $App_Ver ; [" " ; ¶]; ["." ; ¶] ) ;$App=GetValue ( $App_ver_List ; 1 ) ;$Ver=GetValue ( $App_ver_List ; 2 ) ]; 0 ) ]
変数を設定 [ $cURL_URi; 値:Let([ ¢SMTP="{protocol}://{SMTP_Server}:{SMTP_Port}" ]; Substitute ( ¢SMTP ; [ "{protocol}" ; If ( mail_account::SMTP_SSL ; "smtps" ; "smtp" ) ] ; [ "{SMTP_Server}" ; mail_account::SMTP_Server ] ; [ "{SMTP_Port}" ; mail_account::SMTP_Port ] ) ) ]
変数を設定 [ $cURL_Options; 値:Let([ ¢Options=" --globoff --user {SMTP_account}:{SMTP_password} --mail-from {mail-from} --mail-rcpt {mail-rcpt} --upload-file $DATA {ssl} --show-error --dump-header $$dump_header " ]; Substitute ( ¢Options ; [ "{SMTP_account}" ; mail_account::SMTP_account ] ; [ "{SMTP_password}" ; mail_account::SMTP_password ] ; [ "{mail-from}" ; mail_account::mail_address ] ; [ "{mail-rcpt}" ; Mail::To_Address ] ; [ "{ssl}" ; If ( mail_account::SMTP_SSL ; "--ssl-reqd" ; "" ) ] ) ) /*--trace-ascii $$trace_ascii*/ ]
If [ GetAsNumber ( $Ver ) ≥ 18 ]
URL から挿入 [ $$Result; $cURL_URi; cURL オプション: $cURL_Options ] [ URL を自動的にエンコードしない; 選択; ダイアログなし ]
変数を設定 [ $LastError; 値:Get ( 最終エラー ) ]
Else
変数を設定 [ $bool; 値:ValueCount ( FilterValues ( $App ; "ProAdvanced¶Pro" )) ]
If [ $bool = 0 ]
カスタムダイアログを表示 [ タイトル: "!"; メッセージ: "この機能は、「ProAdvanced」または、「Pro」で利用可能です。"; デフォルトボタン: 「OK」, 確定: 「はい」 ]
現在のスクリプト終了 [ ]
End If
変数を設定 [ $System_platform; 値:Get (システムプラットフォーム) ]
#メールをファイル保存|戻り値:ファイルパス
スクリプト実行 [ 「ExportMailDataWithcURL(DATA)」; 引数: $DATA ]
変数を設定 [ $DataPath; 値:Get ( スクリプトの結果 ) ]
変数を設定 [ $Command; 値:$cURL_URi & " " & $cURL_Options ]
If [ $System_platform = -2 /*Windows*/ ]
変数を設定 [ $DataPathFor_cURL_Op; 値:Substitute ( $DataPath ; "file:///" ; "" ) ]
変数を設定 [ $DirPath; 値:Get ( テンポラリパス ) ]
変数を設定 [ $DirPathFor_cURL_Op; 値:Replace ( $DirPath ; 1 ; 1 ; "" ) ]
変数を設定 [ $dump_header_path; 値:$DirPathFor_cURL_Op & "dump_header_" & Mail::_k & ".txt" ]
変数を設定 [ $Command; 値:Substitute ( $Command ; [ "$DATA" ; Quote ( $DataPathFor_cURL_Op ) ] ; [ "$$dump_header" ; Quote ( $dump_header_path)] ) ]
スクリプト実行 [ 「Get_ProperPath(arg)」; 引数: "file:///" & $dump_header_path ]
変数を設定 [ $dump_header_pathFor_cURL; 値:Get ( スクリプトの結果 ) ]
URL から挿入 [ $$er; $dump_header_pathFor_cURL; cURL オプション: Let($DATA=0; " -T $DATA --trace-ascii $$trace " ) ] [ URL を自動的にエンコードしない; 選択; ダイアログなし ]
変数を設定 [ $cURL_Command; 値:If ( IsEmpty ( Setting_cURL::Path ) ; "curl" ; Setting_cURL::Path ) & Char ( 32 ) & $Command ]
Event を送信 [ ファイル/アプリケーションを開く; $cURL_Command ]
変数を設定 [ $LastError; 値:Get ( 最終エラー ) ]
Loop
スクリプト一時停止/続行 [ 間隔(秒): 1 ]
Exit Loop If [ $n>30 ]
URL から挿入 [ $$dump_header; $dump_header_pathFor_cURL ] [ URL を自動的にエンコードしない; 選択; ダイアログなし ]
Exit Loop If [ not IsEmpty ( $$dump_header ) and $$dump_header ≠ 0 ]
変数を設定 [ $n; 値:$n+1 ]
End Loop
変数を設定 [ $$dump_header; 値:Substitute ( $$dump_header ; Char(10) ; "" ) ]
Else If [ $System_platform = 1 /*Mac*/ ]
変数を設定 [ $DataPathFor_cURL_Op; 値:Substitute ( $DataPath ; "file://" ; "" ) ]
変数を設定 [ $Command; 値:Substitute ( $Command ; [ "$DATA" ; Quote ( $DataPathFor_cURL_Op ) ] ; [ "$$dump_header" ; "-"] ) ]
変数を設定 [ $AS; 値:Let([ AS= " set Result to do shell script {Command}¶ set cell \"Logs::dump_header\" of current record to Result " ]; Substitute ( AS ; "{Command}" ; Quote ( "curl " & $Command ) ) ) ]
AppleScript を実行 [ 計算済みの AppleScript: $AS ]
変数を設定 [ $LastError; 値:Get ( 最終エラー ) ]
変数を設定 [ $$dump_header; 値:Logs::dump_header ]
End If
End If
フィールド設定 [ Logs::LastError; $LastError ]
フィールド設定 [ Logs::dump_header; $$dump_header ]
フィールド設定 [ Logs::Result; $$Result ]
フィールドへ移動 [ ]

スクリプト:_AttachedFile
2019/10/28 テキストを挿入 部分のテキストが抜けていたので記述
テキストを挿入 [ 選択; ターゲット:$header ;「--2_{boundary}
Content-Type: application/octet-stream;name="=?utf-8?B?{FileName}?=" 
Content-Transfer-Encoding: base64
Content-Disposition: attachment;filename="=?utf-8?B?{FileName}?=" 」]
変数を設定 [ $MAX; 値:Count ( Mail_AttachedFile::_k ) ]
変数を設定 [ $n; 値:1 ]
変数を設定 [ $CRLF; 値:Char(13) & Char(10) ]
Loop
Exit Loop If [ $n>$MAX ]
変数を設定 [ $File; 値:GetNthRecord ( Mail_AttachedFile::objFile ; $n ) ]
If [ not IsEmpty ( $File ) ]
変数を設定 [ $AttachedFile; 値:$AttachedFile & If (IsEmpty ( $AttachedFile ) ; ""; $CRLF ) & Substitute ( $header ; [¶ ; $CRLF ] ; ["{boundary}" ; Mail::_k ] ; ["{FileName}" ; Base64EncodeRFC ( 4648 ; GetContainerAttribute ($File; "filename") )] ) & $CRLF & $CRLF & Base64EncodeRFC ( 2045 ; $File ) ]
End If
変数を設定 [ $n; 値:$n+1 ]
End Loop
変数を設定 [ $DATA; 値:If ( not IsEmpty ( $AttachedFile ) ; "--1_" & Mail::_k & $CRLF & "Content-Type: multipart/mixed;boundary=2_" & Mail::_k & $CRLF & $CRLF & $AttachedFile & $CRLF & $CRLF & "--2_" & Mail::_k & "--" ) ]
現在のスクリプト終了 [ 結果: $DATA ]

スクリプト: ExportMailDataWithcURL(DATA)
変数を設定 [ $DATA; 値:Get(スクリプト引数) ]
変数を設定 [ $FileName; 値:Mail::_k & ".eml" ]
変数を設定 [ $DirPath; 値:Get ( テンポラリパス ) ]
// 変数を設定 [ $DirPath; 値:Get ( ドキュメントパス ) ]
変数を設定 [ $FilePath; 値:"file:///" & Substitute ( $DirPath ; "\\" ; "/" ) & If ( Right ( $DirPath ; 1 ) ≠ "/" ; "/" ) & $FileName ]
変数を設定 [ $FilePath; 値:Substitute ( $FilePath ; ["file:////" ; "file:///"] ) ]
If [ Get (システムプラットフォーム) = -2 /*Windows*/ ]
#Windowsの場合は、SHIFT-JIS URLエンコード
変数を設定 [ $Path; 値:Let( [ $Val = $FilePath ; $MAX = Length ( $Val ) ; $n = 1 ; $fnc0= "Case ( $n > $MAX ; $Result ; Let( [ $text=Middle ( $Val ; $n ; 1 ); $Result = $Result & if(Code ( $text )>127; Let( [ $txt = HexEncode ( TextEncode ( $text ; \"shift_jis\" ; 1 ) ) ; $pos = Length ( $txt ) - 1 ; $fnc= \"Case ( $pos < 0 ; $txt ; Let( [ $txt = Replace ( $txt ; $pos ; 0 ; \\\"%\\\" ) ; $pos = $pos - 2 ]; Evaluate($fnc)) )\" ]; Evaluate($fnc) ) ; Middle ( $Val ; $n ; 1 ) ); $n = $n + 1 ]; Evaluate($fnc0)) )" ]; Evaluate($fnc0) ) ]
Else
#/var/から始まるパスでないとエラーになる
変数を設定 [ $FilePath; 値:"file:///" & "/var/" & GetValue ( Substitute ( $DirPath ; "/var/" ; ¶ ) ; 2 ) & If ( Right ( $DirPath ; 1 ) ≠ "/" ; "/" ) & $FileName ]
変数を設定 [ $FilePath; 値:Substitute ( $FilePath ; ["file:////" ; "file:///"] ) ]
変数を設定 [ $Path; 値:$FilePath ]
End If
エラー処理 [ オン ]
URL から挿入 [ $Result; $Path; cURL オプション: " -T $DATA --trace-ascii $trace " ] [ URL を自動的にエンコードしない; 選択; ダイアログなし ]
エラー処理 [ オフ ]
フィールドへ移動 [ ]
現在のスクリプト終了 [ 結果: $Path ]

スクリプト: Get_ProperPath(arg)
#Windows、全角やスペースw含むパスの対応
変数を設定 [ $FilePath; 値:Get(スクリプト引数) ]
変数を設定 [ $FilePath; 値:Substitute ( $FilePath ; ["file:////" ; "file:///"] ) ]
If [ Get (システムプラットフォーム) = -2 /*Windows*/ ]
#Windowsの場合は、SHIFT-JIS URLエンコード
変数を設定 [ $Path; 値:Let( [ $Val = $FilePath ; $MAX = Length ( $Val ) ; $n = 1 ; $fnc0= "Case ( $n > $MAX ; $Result ; Let( [ $text=Middle ( $Val ; $n ; 1 ); $Result = $Result & if(Code ( $text )>127; Let( [ $txt = HexEncode ( TextEncode ( $text ; \"shift_jis\" ; 1 ) ) ; $pos = Length ( $txt ) - 1 ; $fnc= \"Case ( $pos < 0 ; $txt ; Let( [ $txt = Replace ( $txt ; $pos ; 0 ; \\\"%\\\" ) ; $pos = $pos - 2 ]; Evaluate($fnc)) )\" ]; Evaluate($fnc) ) ; Middle ( $Val ; $n ; 1 ) ); $n = $n + 1 ]; Evaluate($fnc0)) )" ]; Evaluate($fnc0) ) ]
Else
変数を設定 [ $Path; 値:$FilePath ]
End If
現在のスクリプト終了 [ 結果: $Path ]
完成品をダウンロード(\500)
https://fm-aid.stores.jp/items/5db51c8cbc45ac23540f9787
Q&A 不明な点は以下で問い合わせ下さい。
https://fm-aid.com/community/viewforum.php?id=6

2019年10月24日木曜日

FileMakerからWord(.docx)ファイルへデータ差し込み|使い方

動作検証:
FileMaker Pro 16以降
Windows 10
PowerShell 5.1
Word 2016

プラグイン不要

※元のテンプレートとなるWordファイルを作成時は、Wordが必要ですが、
FileMakerからWord(.docx)ファイルを出力する時は、Word無しでOK。

作成方法は、コチラ
https://qbxxdp.blogspot.com/2019/10/filemakerworddocx.html

使用方法:
テンプレートとなるWordファイルを作成。
{受取人名} の様な {*****} の部分をFileMakerで置換します。
Wordファイル作成時注意事項:
Wordファイルを編集していくと文字列の断片化が発生します。
*.docx 内の document.xml 内で文字列の断片化が発生した場合、以下のようになり、
 {*****} の部分の置換が出来なくなります。
解消方法(1)
XMLファイルを直接編集。後で説明※1

解消方法(2)
Word上で {受取人名} をコピー メモ帳(notepad.exe)に貼り付け > メモ帳 上の  {受取人名} をコピー > Wordに貼り付け。
※XMLの確認方法は後で説明※1

FileMaker
サンプルファイル「FmToDocx.fmp12」
フィールド:Title|任意の名前を設定
フィールド:obj_docx|Wordファイルを挿入

[*.docx内のXMLを取得] ボタンをクリック
*.docx 内の document.xml の内容が取得できます。
文字列の断片化の確認修正が行えます。※1

サンプルファイル「FaxCoverSheet.fmp12」

フィールド:id_FmToDocx|ファイル「FmToDocx.fmp12」の対象レコードを選択
各フィールドに置換する文字列を入力


[Create_docx]ボタンをクリック
Word(.docx)ファイルが作成されます。





FileMakerからWord(.docx)ファイルへデータ差し込み|作り方

動作検証:
FileMaker Pro 16以降
Windows 10
PowerShell 5.1
Word 2016

プラグイン不要

※元のテンプレートとなるWordファイルを作成時は、Wordが必要ですが、
FileMakerからWord(.docx)ファイルを出力する時は、Word無しでOK。

使用方法は、コチラ
https://qbxxdp.blogspot.com/2019/10/filemaker-word-docx.html

作るのが面倒な場合は、完成品をダウンロード(\500)
https://fm-aid.stores.jp/items/5db13868745e6c1bce94c7db

作成:
──────────ファイル「FmToDocx.fmp12」──────────
テーブル:

フィールド:

レイアウト:

 ボタン[*.docx内のXMLを取得] に スクリプト:Get_DocumentXml を割り当て


スクリプト:


Get_DocumentXml
変数を設定 [$docx; 値: FmToDocx::obj_docx]
変数を設定 [$FileName; 値: GetContainerAttribute ($docx ; "filename")]
If [Right ( $FileName ; 5 ) ≠ ".docx"]
カスタムダイアログを表示 ["!"; $FileName & " は、ファイル:*.docx ではありません。"]
現在のスクリプト終了 [テキスト結果: ]
End If
スクリプト実行 [指定:一覧から; 「Expand_docx」; 引数: ]
スクリプト実行 [指定:一覧から; 「Import_DocumentXml」; 引数: ]
現在のスクリプト終了 [テキスト結果:FmToDocx::document_xml]

Create_docx(XML)
変数を設定 [$XML; 値: Get(スクリプト引数)]
If [IsEmpty ( $XML )]
現在のスクリプト終了 [テキスト結果: ]
End If
ブレークポイント スクリプト実行 [指定:一覧から; 「Expand_docx」; 引数: ]
スクリプト一時停止/続行 [間隔(秒): 1]
ブレークポイント スクリプト実行 [指定:一覧から; 「Export_DocumentXml(XML)」; 引数:$XML]
ブレークポイント スクリプト実行 [指定:一覧から; 「Compress_docx」; 引数: ]
ブレークポイント 変数を設定 [$WordDocxPath_win; 値: Get(スクリプトの結果)]
変数を設定 [$WordDocxPath; 値: "/" & Substitute ( $WordDocxPath_win ; "\\" ; "/" )]
スクリプト一時停止/続行 [間隔(秒): 1]
ファイルを挿入 [ターゲット:FmToDocx::gResult_docx; 「$WordDocxPath」]
フィールドへ移動 []
現在のスクリプト終了 [テキスト結果:FmToDocx::document_xml]

Setting_FilePath
変数を設定 [$TempPath; 値: Get ( テンポラリパス )]
変数を設定 [$$WordZipPath; 値: $TempPath & "word.zip"]
変数を設定 [$$TempPath_win; 値: Substitute ( Replace ( $TempPath ; 1 ; 1 ; "" ) ; "/" ; "\\" )]
変数を設定 [$$WordZipPath_win; 値: $$TempPath_win & "word.zip"]
変数を設定 [$$wordArchivePath_win; 値: $$TempPath_win & "word_archive"]
変数を設定 [$$DocumentXmlPath_win; 値: $$TempPath_win & "word_archive\word\document.xml"]

Expand_docx
If [IsEmpty ( $$WordZipPath )]
スクリプト実行 [指定:一覧から; 「Setting_FilePath」; 引数: ]
End If

# ファイル:*.docx を ファイル名:word.zip でテンポラリフォルダへ保存
フィールド内容のエクスポート [FmToDocx::obj_docx; 「$$WordZipPath」; フォルダを作成:オフ]

# *.docx を展開したフォルダ:word_archive を削除
変数を設定 [$Command; 値: Let([ ¢cm=" Remove-Item -Recurse {TargetFolder}; " ]; Substitute ( ¢cm ; ["{TargetFolder}" ; Quote ( $$wordArchivePath_win )] ) )]
変数を設定 [$PS; 値: "powershell -WindowStyle Hidden -Command " & Quote ( $Command )]
Event を送信 [「aevt」; 「odoc」; $PS]
スクリプト一時停止/続行 [間隔(秒): .5]

# word.zip を展開 -> フォルダ:word_archive
変数を設定 [$Command; 値: Let([ ¢cm=" Expand-Archive -Force -Path {source} -DestinationPath {TargetFolder}; " ]; Substitute ( ¢cm ; ["{source}" ; Quote ( $$WordZipPath_win )] ; ["{TargetFolder}" ; Quote ( $$wordArchivePath_win )] ) )]
変数を設定 [$PS; 値: "powershell -WindowStyle Hidden -Command " & Quote ( $Command )]
Event を送信 [「aevt」; 「odoc」; $PS]



変数を設定 [$Command; 値: Let([ ¢cm=" Test-Path {Target}|clip; " ]; Substitute ( ¢cm ; ["{Target}" ; Quote ( $$wordArchivePath_win )] ) )]
変数を設定 [$PS; 値: "powershell -WindowStyle Hidden -Command " & Quote ( $Command )]
フィールド設定 [FmToDocx::gForScriptText; ""]
変数を設定 [$n; 値: 1]
ブレークポイント Loop
Exit Loop If [$n>10]
Exit Loop If [ValueCount ( FilterValues ( Lower ( FmToDocx::gForScriptText ) ; "true" ) )]
Event を送信 [「aevt」; 「odoc」; $PS]
スクリプト一時停止/続行 [間隔(秒): 1]
貼り付け [選択; FmToDocx::gForScriptText]
フィールドへ移動 []
変数を設定 [$n; 値: $n+1]
End Loop
If [$n>10]
カスタムダイアログを表示 ["!ERROR"; Get ( スクリプト名 )]
全スクリプト終了
End If

現在のスクリプト終了 [テキスト結果: ]

Compress_docx
変数を設定 [$WordDocxPath_win; 値: $$TempPath_win & GetContainerAttribute (FmToDocx::obj_docx ; "filename")]


# *.docx を削除
変数を設定 [$Command; 値: Let([ ¢cm=" Remove-Item -Recurse {Target}; " ]; Substitute ( ¢cm ; ["{Target}" ; Quote ( $WordDocxPath_win )] ) )]
変数を設定 [$PS; 値: "powershell -WindowStyle Hidden -Command " & Quote ( $Command )]
Event を送信 [「aevt」; 「odoc」; $PS]
スクリプト一時停止/続行 [間隔(秒): .5]


# フォルダ:word_archive 圧縮 -> word.zip
# 拡張子変更 word.zip -> *.docx
変数を設定 [$Command; 値: Let([¢cm="Set-Location -Path {source};Compress-Archive -Force -literalPath _rels, docProps, word, '[Content_Types].xml' -Destination {Target};Move-Item -Force {Target} {TargetDocx} ;"];Substitute ( ¢cm ; ["{source}" ; Quote ( $$wordArchivePath_win )]; ["{Target}" ; Quote ( $$WordZipPath_win ) ]; ["{TargetDocx}" ; Quote ( $WordDocxPath_win ) ] ))]
変数を設定 [$PS; 値: "powershell -WindowStyle Hidden -Command " & Quote ( $Command )]
Event を送信 [「aevt」; 「odoc」; $PS]

変数を設定 [$Command; 値: Let([ ¢cm=" Test-Path {Target}|clip; " ]; Substitute ( ¢cm ; ["{Target}" ; Quote ( $WordDocxPath_win )] ) )]
変数を設定 [$PS; 値: "powershell -WindowStyle Hidden -Command " & Quote ( $Command )]
フィールド設定 [FmToDocx::gForScriptText; ""]
変数を設定 [$n; 値: 1]
Loop
Exit Loop If [$n>10]
Exit Loop If [ValueCount ( FilterValues ( Lower ( FmToDocx::gForScriptText ) ; "true" ) )]
Event を送信 [「aevt」; 「odoc」; $PS]
スクリプト一時停止/続行 [間隔(秒): 1]
貼り付け [選択; FmToDocx::gForScriptText]
フィールドへ移動 []
変数を設定 [$n; 値: $n+1]
End Loop
If [$n>10]
カスタムダイアログを表示 ["!ERROR"; Get ( スクリプト名 )]
全スクリプト終了
End If

現在のスクリプト終了 [テキスト結果:$WordDocxPath_win]

Export_DocumentXml(XML)
変数を設定 [$XML; 値: Get(スクリプト引数)]
If [IsEmpty ( $XML )]
現在のスクリプト終了 [テキスト結果: ]
End If

# $$DocumentXmlPath_win="{TEMP}\word_archive\word\document.xml"
# Windows用にパスをURLエンコード(shift_jis)
スクリプト実行 [指定:一覧から; 「Get_ProperPath(arg)」; 引数:$$DocumentXmlPath_win]
変数を設定 [$DocumentXmlPath_win_enc; 値: Get(スクリプトの結果)]


変数を設定 [$DATA; 値: $XML]
URL から挿入 [選択; ダイアログあり:オフ; $er; "file:///" & $DocumentXmlPath_win_enc; cURL オプション:" -T $DATA "; URL を自動的にエンコードしない]
変数を設定 [$LastError; 値: Get ( 最終エラー )]
フィールドへ移動 []
If [$LastError ≠ 0]
カスタムダイアログを表示 ["!ERROR"; "ERROR CODE: " & $LastError]
End If

Import_DocumentXml
# $$DocumentXmlPath_win="{TEMP}\word_archive\word\document.xml"
# Windows用にパスをURLエンコード(shift_jis)
スクリプト実行 [指定:一覧から; 「Get_ProperPath(arg)」; 引数:$$DocumentXmlPath_win]
変数を設定 [$DocumentXmlPath_win_enc; 値: Get(スクリプトの結果)]

フィールド設定 [FmToDocx::document_xml; ""]
変数を設定 [$n; 値: 1]
Loop
Exit Loop If [$n>20]
スクリプト一時停止/続行 [間隔(秒): 1]
エラー処理 [オン]
ブレークポイント URL から挿入 [選択; ダイアログあり:オフ; ターゲット:FmToDocx::document_xml; "file:///" & $DocumentXmlPath_win_enc; URL を自動的にエンコードしない]
変数を設定 [$LastError; 値: Get ( 最終エラー )]
Exit Loop If [ not IsEmpty ( FmToDocx::document_xml )]
変数を設定 [$n; 値: $n+1]
End Loop
フィールドへ移動 []
If [$LastError ≠ 0]
カスタムダイアログを表示 ["!ERROR"; "ERROR CODE: " & $LastError]
End If

Get_ProperPath(arg)
# Windows、全角やスペースw含むパスの対応
変数を設定 [$FilePath; 値: Get(スクリプト引数)]
変数を設定 [$FilePath; 値: Substitute ( $FilePath ; ["file:////" ; "file:///"] )]
If [Get (システムプラットフォーム) = -2 /*Windows*/]
# 全角有無チェック
変数を設定 [$ByteCount; 値: Length($FilePath & Filter ( $FilePath ; RomanZenkaku ( KanaZenkaku ( $FilePath ) )))]
変数を設定 [$Length; 値: Length ( $FilePath )]
If [$ByteCount = $Length]
変数を設定 [$Path; 値: $FilePath]
Else
# Windowsの場合は、SHIFT-JIS URLエンコード
変数を設定 [$Path; 値: Let([ $Val = $FilePath ; $MAX = Length ( $Val ) ; $n = 1 ; $fnc0= "Case ( $n > $MAX ; $Result ; Let( [ $text=Middle ( $Val ; $n ; 1 ); $Result = $Result & if(Code ( $text )>127; Let([ $txt = HexEncode ( TextEncode ( $text ; \"shift_jis\" ; 1 ) ) ; $pos = Length ( $txt ) - 1 ; $fnc= \"Case ( $pos < 0 ; $txt ; Let( [ $txt = Replace ( $txt ; $pos ; 0 ; \\\"%\\\" ) ; $pos = $pos - 2 ]; Evaluate($fnc)) )\"]; Evaluate($fnc)) ; Middle ( $Val ; $n ; 1 ) ); $n = $n + 1 ]; Evaluate($fnc0)) )"]; Evaluate($fnc0))]
End If

Else
変数を設定 [$Path; 値: $FilePath]
End If
現在のスクリプト終了 [テキスト結果:$Path]

OnLastWindowClose
変数を設定 [$FieldFullName_s; 値: /*ファイル内のすべてのグローバルフィールドの完全名称と繰り返し数を取得。*/Let ([ $query ="select '$FieldFullName='||'\"'||TableName ||'::'||FieldName||'\"','$FieldReps='||'\"'||FieldReps||'\"'FROM FILEMAKER_FIELDSWHERE FieldClass = 'Normal'ANDFieldType LIKE 'global%'"];ExecuteSQL ( $query ; ";" ; "" ))]
変数を設定 [$MAX; 値: ValueCount ( $FieldFullName_s )]
変数を設定 [$n; 値: 1]
Loop
Exit Loop If [$n>$MAX]
変数を設定 [$Val; 値: GetValue ( $FieldFullName_s ; $n )]
変数を設定 [$er; 値: Evaluate ( "Let ( [" & $val & "] ; 0 )" )]
変数を設定 [$k; 値: 1]
Loop
Exit Loop If [$k>$FieldReps]
フィールドを名前で設定 [$FieldFullName & "[" & $k & "]"; ""]
変数を設定 [$k; 値: $k+1]
End Loop
変数を設定 [$n; 値: $n+1]
End Loop


──────────ファイル「FmToDocx.fmp12」──────────
テーブル:

フィールド:

レイアウト:

スクリプト:

Create_docx
変数を設定 [$XML; 値: Substitute ( FmToDocx::document_xml
; ["{受取人名}" ; EscXml ( FaxCoverSheet::受取人名 )]
; ["{受取人FAX}" ; EscXml ( FaxCoverSheet::受取人FAX )]
; ["{受取人の電話番号}" ; EscXml ( FaxCoverSheet::受取人の電話番号 )]
; ["{差出人名}" ; EscXml ( FaxCoverSheet::差出人名 )]
; ["{差出人FAX}" ; EscXml ( FaxCoverSheet::差出人FAX )]
; ["{差出人の電話番号}" ; EscXml ( FaxCoverSheet::差出人の電話番号 )]
; ["{件名}" ; EscXml ( FaxCoverSheet::件名 )]
; ["{日付}" ; EscXml ( FaxCoverSheet::日付 )]
; ["{コメント}" ; EscXml ( FaxCoverSheet::コメント ) ]
)]
関連レコードへ移動 [関連レコードのみを表示; テーブル: 「FmToDocx」; 外部; 使用するレイアウト: 「FmToDocx」]
スクリプト実行 [指定:一覧から; 「Create_docx(XML)」 , ファイル: 「FmToDocx」; 引数:$XML]
ウインドウを選択 [現在のウインドウ]
フィールド内容のエクスポート [FmToDocx::gResult_docx; フォルダを作成:オフ]

カスタム関数:

EscXml(XML)
Substitute ( XML
; ["&";"&amp;"]
; ["\"";"&quot;"]
; ["'";"&apos;"]
; ["<";"&lt;"]
; [">";"&gt;"]
; [¶ ; ""]
)
※上記の &amp;  &quot; &apos; &lt;  &gt; の & が全角になっています。FileMakerに記述する際は、半角に変更して下さい。