Cocoa AppleScript テキストファイルの入出力 UTF-8 TSVデータ作成 AppleScript [07]

AppleScript[07](CatchImage)

AppleScript [07] Cocoa AppleScript 第3版 テキストファイルの入出力 UTF-8 TSVデータ作成
 友人から「せっかくだから、テキストファイル入出力も...」と要望があったので、最後に「UTF-8 テキストファイル入出力」機能を付加。 (クリップボードと同一フォーマットの)タブ区切りの「TSVデータ」を作成するオリジナル関数と併せて公開!
 Excel とのデータ受け渡しは、今までと同様テキスト あるいは クリップボードを利用。 データフォーマットは「UTF-8 CRLF改行コード タブ区切り」を想定! パラメータ区切りにも今回 LFではなく CRLF を利用したのは、「 Excelのセル内改行コードが LF 」のため区別が付くように...

 (注) AppleScript にて、フォルダ選択ダイアログ あるいは ファイル選択ダイアログ を利用します!

 2021/10/03  Ver. 3.2「Cocoa AppleScript 第3版」に改良!
→ AppleScript は "filePath.scpt" ファイル内のコード全て「差し替え」、VBAコードは「追加となります。(インターフェースとヘルパー用プロシージャ)

 【注意】テキストファイルの上書き(置き換え)を行う場合、必ず該当ファイルを閉じてから実行して下さい!!
 テキストエディタ等で閉じるのを忘れた場合(つまり、ファイルをオープンしたままだと)、メモリ不足など Mac が深刻な症状に陥る場合があります。 筆者もテストの際2、3度「やっちまった」次第で、いきなり Safari や Excelが終了してビックリ...


 【AppleScriptの差し替え】 AppleScript [07] Cocoa AppleScript 第3版 テキストファイルの入出力 UTF-8 TSVデータ作成 

 まず、Excel メニューバーの [ヘルプ] - [更新プログラムのチェック] にて、適用されていないアップデートがあれば行ってください。


 VBA の AppleScriptTask コマンド パラメータの注意点 

  ファイルパスと区別するため フォルダパス指定には 末尾に必ず / を付加 してください! フォルダフルパス なら 先頭と末尾が必ず / となります。
 OneDriveiCloudDropboxBox 等のサービスをブラウザ利用でなくフォルダにリンクしている場合も(リンク)パスが判れば指定可能ですが、https:// が先頭に付いたり ネットワーク経由のアクセスのためとんでも無く時間がかかりますので ローカルPC(Mac本体内の高速なSSDやHDDドライブ)上のフォルダパスを指定してください。


 第3版 Cocoa AppleScript コードの全置換(一部はVanilla AS記述) 

(1)  以前に  作成したExcelファイルをマクロを有効にして開き、続いて VBEウィンドウ を開く。

(2) ~/ライブラリ/Application Scripts/com.microsoft.Excel/ フォルダ内に保存した filePath.scpt をダブルクリック等で("スクリプトエディタ"アプリにて)開き、 ファイル内の全AppleScriptコードを以下のコードで置換し、 コンパイル後に ファイルを保存 したら "スクリプトエディタ"アプリは終了してください。

 上記の操作方法がよく解らない方は、  以前の投稿  をお読みください。

 VBA、AppleScript 両方のコードに コメントをたくさん記述しておいたので、宜しければ ご覧ください!

 2021/10/03  Ver. 3.2「Cocoa AppleScript 第3版」に改良!
→ AppleScript は "filePath.scpt" ファイル内のコード全て「差し替え」、VBAコードは「追加となります。(インターフェースとヘルパー用プロシージャ)

 全置換となるため 以下の全AppleScriptコードを コピー&ペースト(貼り付け)後、 コンパイル後に ファイルを保存 してください。 VBAコード に関しては「次章」に記載します。

 補足ですが、 AppleScript 44行目の「 property HIDDEN_FILES : true 」の true を fasle に置換して コンパイル後に ファイルを保存 すると、フォルダ階層(子フォルダ)に対応したパスやファイル名を返す AppleScriptTask の場合、 隠しファイルも表示 されるようになります。 確認後は、 true に戻すことをオススメします!


 AppleScript "filePath.scpt" をダウンロード可能にしました。   Download Here 
 ( ダウンロードしてダブルクリックすると、 "スクリプトエディタ.app" を起動! )

 上記リンクを右クリックして「リンク先のファイルをダウンロード」等を選択してダウンロード可能。
"Google Chrome" ブラウザの場合、上記リンクを右クリックして「名前を付けてリンク先を保存」を選択してダウンロード )
 (注) [ Unicode(UTF-8) 、改行コードは LF ] ファイル置き場として、筆者の旧ブログを利用


 ちなみに、  ret  で始まる AppleScript の ハンドラー (VBAのプロシージャ相当の呼び出し単位)は Cocoa AS で主処理が実装されていますので、カスタマイズは慎重にお願いします。 その他の ハンドラー も Cocoa AS 実装の部分が判るように記述 しています。(何も記述が無ければ、Vannila AS ということ) Vanilla AS 部分はカスタマイズが楽で「 AppleScriptTask コマンド経由の呼び出し」ではなく、「 filePath.scpt をダブルクリック後に起動される スクリプトエディタ.app にて実行」すれば( Vanilla AS 部分の場合 )エラー発生箇所が判ります。 先頭部分の on test() から end test 内にサンプルのデバッグ用コードを記述済みのため、変更後に [command]+[K] でコンパイル、 test() の実行は [command]+[R] で可能です。 動作に問題が無い場合は [command]+[S] にて保存を忘れないように!

 VBA だけでなく AppleScript コードも テキスト保存が可能なため、変更前に [command]+[A] にて全選択後 [command]+[C] でコピー してテキストエディタ等に [command]+[V] にてペースト(貼り付け)しておけば元に戻せます。 カスタマイズ作業前に filePath.scptAppleScriptTaskコマンドを記述したExcelファイル を ローカルPC上か クラウド領域にバックアップしておくと なお良いでしょう。


AppleScript[07] Png00

 【VBA I/F追加】 AppleScript [07] Cocoa AppleScript 第3版 テキストファイルの入出力 UTF-8 TSVデータ作成 

 VBAコード の追加のため、末尾に 以降のコードを順番にコピー&ペースト(貼り付け) 


'「Selection範囲」をクリップボードにコピー 後、「完了」メッセージを表示する
Sub CopyToClipboard()

    Selection.Copy ' クリップボードにコピー
    Application.CutCopyMode = False 'コピー範囲の解除
    MsgBox "クリップボードにコピー【完了】" & vbNewLine & _
    "[ " & Selection.Address(False, False) & " ]"
    
End Sub


 テキストデータは今回 Selection(Excelシート上でセル選択した)範囲を対象として、タブ区切りのTSVデータを作成後に 書き込みます!

【注意】実行前に、データを作成する「対象シート(ActiveSheet)」を選択!



 【TSVデータ作成、オリジナル関数】「クリップボードへコピー」されたTSVデータで、不都合がある場合の対処 

'Selection範囲内の「Excel用TSVデータ」を作成する、オリジナル関数
'Excel TSV書式(UTF-8 CRLF改行コード 「列」毎に水平タブ[chr(09)]を挟む セル内改行コードはLF)
'クリップボードによるTSVデータ作成結果で、以下2つの問題に対処(必要なら対処を追加して下さい)
'[1] 1行単位で、「末尾の余分なタブコード」を削除
'[2] #NAME? 対策 → Cells(row, col).Formula「計算式」を利用(ただし、先頭の"="は削除)
Function CreateTsvDataFromSelection(newLineCode As String) As String

    CreateTsvDataFromSelection = ""

    Dim HT As String: HT = Chr(9) '「列」(フィールド)区切り用「水平タブ」コード HT
    Dim row As Long, col As Long
    Dim textData As String: textData = "" 'TSV(タブ区切りの)テキストデータ
    Dim lineData As String: lineData = "" 'work用の「行」テキストデータ
    

    'HT & 改行コード を挿入し、TSV(タブ区切りの)フォーマットのテキストデータを作成
    'Excelの場合セル内改行コードは LF となるため、Macでも改行コード CRLF を利用すべき
    
    'Selection(1)はSelection範囲の左上のセル、Selection(Selection.Count)は(同)右下のセルを示す
    For row = Selection(1).row To Selection(Selection.Count).row
    
        For col = Selection(1).Column To Selection(Selection.Count).Column
        
            If col = Selection(Selection.Count).Column Then '「最終列」の処理
                If IsError(Cells(row, col)) Then ' #NAME? 対策
                    lineData = lineData & Mid(CStr(Cells(row, col).Formula), 2) '先頭の"="を削除
                Else
                    lineData = lineData & CStr(Cells(row, col).Text)
                End If
            Else '「最終列」以外の処理(末尾に、タブ区切りのコードを挿入)
                If IsError(Cells(row, col)) Then ' #NAME? 対策
                    lineData = lineData & Mid(CStr(Cells(row, col).Formula), 2) & HT
                Else
                    lineData = lineData & CStr(Cells(row, col).Text) & HT
                End If
            End If
            
        Next col
        
        '(1行単位で)末尾の余分な HT を削除
        Do While (Len(lineData) <> 0 And (Right(lineData, 1) = HT))
            lineData = Left(lineData, Len(lineData) - 1) '末尾の1文字(HT)を削除
        Loop

        If row = Selection(Selection.Count).row Then
            textData = textData & lineData '最終行
        Else
            textData = textData & lineData & newLineCode '最終行以外は末尾に改行コードを挿入
        End If
        
        lineData = "" 'work用の「行」テキストデータを初期化
        
    Next row
    
    CreateTsvDataFromSelection = textData
    
End Function


↑ 「クリップボード」内に格納されるTSVデータで問題がある場合は、オリジナルなVBAコードでTSVデータを作成します!
 ① 行単位で「末尾の余分なタブコード」を削除
 ② #NAME? 対策
以上2つの問題に対処済みで、 必要なら対処を追加・変更して下さい!


AppleScript[07] Png01


 【テキストファイル書き込み】Selection範囲を対象として、「クリップボードへコピー」または「TSVデータを自実装で作成」にて書き込みデータを作成 

'UTF-8エンコードで、テキストデータをファイル書き込み(既に存在する場合は、置き換え)
' パラメータ[1] useCB As Boolean: false or true(クリップボードを利用するかどうか?)
' パラメータ[2] append As String: "create"(書き込み) or "append"(追記)
' パラメータ[3] newLineCode As String:"CRLF" or "LF" or "CR"(テキストデータ内の改行コード)
' 結果 true(書き込み成功 or 置き換え成功)、 false(失敗)
Function WriteTextFile(useCB As Boolean, append As String, newLineCode As String) As Boolean
    On Error GoTo myError
    
    WriteTextFile = False
    Dim textData As String
    Dim CRLF As String: CRLF = Chr(13) & Chr(10) 'vbCrLfで、 (0d0a)h がセットされなかったため
    
    'Selection範囲の指定(1行目は「見出し行」を想定し、2行目以降を対象とする)
    ActiveSheet.Select
    Range("A2", ActiveCell.SpecialCells(xlLastCell)).Select '"A2" TSV出力したいセル範囲の開始セル
    'MsgBox Selection.Address(False, False) ' ex) A2:D2039  1行目は「見出し」行のため
    
    'ExcelTSVデータ UTF-8 CRLF改行コード 「列」毎に水平タブ[chr(09)]を挟む セル内改行コードはLF
    If useCB Then
        textData = ""
        Call CopyToClipboard 'データの受け渡しに、クリップボードを利用する(範囲:Selection)
    Else
        textData = CreateTsvDataFromSelection(CRLF) '範囲:Selection、引数は(挿入)改行コード
    End If
    
    Dim filePath As Variant
    Dim extList(2) As String '拡張子を2つ指定する場合
    extList(0) = "tsv"
    extList(1) = "txt" 'Excelで「タブ区切り」を選ぶと、拡張子は txt となるため
    filePath = ""
    
    ' 指定した拡張子(配列)でない場合、再度ダイアログを表示
    Do Until (filePath = False Or filePath <> "")
        filePath = MAC_GetSaveAsFilename("fileName", extList)
    Loop
    
    If filePath = False Then 'ダイアログで「キャンセル」した場合、コピー保存しない
        MsgBox "処理が「キャンセル」されました!" & vbCrLf & "( GetSaveAsFilename )"
        Exit Function
    End If


'以下は、AppleScriptTaskコマンドのパラメータ説明
' パラメータ区切りは、LF ではなく CRLF を利用!(Excel TSVファイルデータ対応)
' パラメータ[1]  (書き込む)ファイルのフルパス
' パラメータ[2]  Appendなら "append" 、Createなら "create" 文字列指定
' パラメータ[3]  改行コード "CRLF" 又は "LF" 又は "CR"
' パラメータ[4〜n]パラ3指定の改行コード区切りのUTF-8テキストデータ 連結してテキストデータとする
'      【注意】"" の場合は、クリップボード内のUTF-8テキストデータを書き込む
' 実行結果 書き込み(置き換え)エラー時は""、正常終了なら該当ファイルの「ファイル名」が返る
'Excel用TSVファイル(CRLF改行コード、タブ区切り「HT:Chr(09)」、セル内改行はLF)にて テスト済み
    Dim scriptResult As String '    AppleScript 実行結果  (文字列)
    Dim scriptParam As String '     AppleScript パラメータ(文字列)
    'クリップボード利用時は、textData = ""
    scriptParam = filePath & CRLF & LCase(append) & CRLF & UCase(newLineCode) & CRLF & textData
    scriptResult = AppleScriptTask("filePath.scpt", "putTextFileAsUTF8", scriptParam)
    
    If scriptResult <> "" Then
        Rem MsgBox scriptResult '正常終了時、書き込みファイルの「ファイル名」が返る
        WriteTextFile = True
    End If
    Exit Function
    
myError:
    MsgBox "エラー発生!(WriteTextFile)"
End Function


WriteTextFile関数の利用方法(イミディエイト ウィンドウからテスト可!)
パラメータ[3]の改行コードは、 append 選択時 データの追記前に 挿入されます。
 ① ? WriteTextFile(True, "create", "CRLF")  CB利用、ファイル作成
 ② ? WriteTextFile(True, "append", "CRLF") CB利用、ファイル追記
 ③ ? WriteTextFile(False, "create", "CRLF")  自実装、ファイル作成
 ④ ? WriteTextFile(False, "append", "CRLF") 自実装、ファイル追記

【注意】実行前に、データを作成する「対象シート(ActiveSheet)」を選択!


AppleScript[07] Png03

AppleScript[07] Png04


 【テキストファイル読み込み】ファイル選択ダイアログで、指定テキストデータをUTF-8で読み込む(クリップボードにもセット) 

' ファイル選択ダイアログで、指定テキストデータをUTF-8で読み込む(クリップボードにもセット)
Function ReadTextFile() As String
'Openダイアログを利用して、テキストデータをUTF-8エンコードで読み込む【クリップボードにもセット】
    On Error GoTo myError
    ReadTextFile = ""
    
'以下は、AppleScriptTaskコマンドのパラメータ説明
' パラメータ[1]  プロンプト文字列:""なら、AppleScriptハンドラー設定の初期値
' パラメータ[2]  初期表示フォルダ:""なら、無指定(前回と同じフォルダを開く)
' パラメータ[3〜6]UTIを4つまで指定可能  ""(無指定)なら"public.plain-text"を利用→ *.tsv対象
' 実行結果[0〜n] エラー時は""、 正常終了なら テキストファイル全体を文字列として返す(改行コードに注意)
'Excel用TSVファイル(CRLF改行コード、タブ区切り「HT:Chr(09)」、セル内改行はLF)にて テスト済み
    Dim scriptResult As String '    AppleScript 実行結果  (文字列)
    Dim scriptParam As String '     AppleScript パラメータ(文字列)
    'scriptParam = "ReadTextFile!" & vbLf & "/Users/username/" & vbLf & "public.plain-text"
    scriptParam = "" & vbLf & "" & vbLf & ""
    scriptResult = AppleScriptTask("filePath.scpt", "getTextFileAsUTF8", scriptParam)
   
    'Debug.Print scriptResult 'for Debug【結果だけでなく、クリップボードにもセット】
    ReadTextFile = scriptResult '改行コードに注意( CRLF 又は LF 又は CR を想定)

    Exit Function
    
myError:
    MsgBox "エラー発生!(ReadTextFile)"
End Function


 ReadTextFile() を実行すると、 全件分 全行分のテキストデータが一度に「結果文字列」として返されます。 (クリップボードにも、同一結果を格納)
結果データは、 CRLF 又は LFCR の3種類想定している改行コードに注意して (Split関数等)処理する必要あり!
 改行コードが CRLF かつ フィールド(項目)の区切りとして「タブコード HT:Chr(09)」を利用している場合は、クリップボードの中身をそのまま Excelワークシート上に [command]+[V] にて貼り付け可能です。

( macOS10以降、 Mac のデフォルトの改行コードは Unix系と同じ LF


AppleScript[07] Png05

AppleScript[07] Png02


 Office2016以降の Excel から AppleScriptTaskコマンドを利用すれば Windows版VBA と大差無く実装可能なことが、今回までの AppleScript 学習で判明しました! AppleScript まで覚えるのは Excelのみの連携であれば 負荷がかかりますが、AppleScript は Mac のデフォルトアプリのみではなく Adobe アプリ等との連携機能も豊富なため 覚えておいて損する事はないと思います。 Windows版VBA ではできるけど Mac版ではできないことや PDF操作連携などを実現する方法として、「Excel2019版 VBA入門」連載後に「AppleScript入門」もありかなと思いました。 次週以降は「VBA入門」に戻る予定ですが、必要であれば AppleScript で補完する方向で進めたいと思います。




 [command] + [Q] にてまず VBE を終了し、Excel のウィンドウ内を選択して [command] + [Q] にて Excel も終了させます。 「作業中のブック」を保存するか確認のダイアログ画面が表示された場合は 「保存」しましょう。 「自動保存」済みの場合、保存するかどうかの確認ダイアログ画面は表示されません。


 AppleScriptTask コマンドの結果文字列(エラーがあれば、空文字 "" を返す)だけでなく、クリップボードにも同じ内容(改行コードは異なる場合あり)をセットしているため、必要があれば「片方のみ」に変更してください。 ただし、「フルパスやファイル名以外」を返す結果文字列の場合 クリップボードにはセットしないため、「イミディエイト ウィンドウ」にて確認してください!
 AppleScript から VBA に数百ファイル以上結果が返されるのであれば、大量データが渡されるオーバーヘッドも含め、クリップボードのみの利用(結果文字列は、正常終了/異常終了のみ判れば良い)がオススメです。 また、バックグラウンド処理前提の場合は 相互で クリップボードの中身を消してしまう可能性 があるため、結果文字列のみの利用が良いでしょう。

 1日2時間くらい2ヶ月 AppleScript を勉強した成果として、今回の記事を書きました。 Cocoa AppleScript に関しては初心者のため、不具合があればコメント等で教えて頂けると嬉しいです。








Macブログ ランキング アイコン
最後まで読んでいただき、ありがとうございます。 また、お越しくださいませ。
// アタル
For follow LINE Reader Group!Subscribe to this blog on Feedly!

Next Post Previous Post
2 Comments
  • アタル
    アタル 2021年11月6日 13:03

    --Copyright 2021- ataruchi. [ https://twitter.com/ataruchi ]
    --「スクリプトエディタ.app」に以下のAppleScriptを貼り付け後 [command]+[R] を実行すると、クリップボード内のテキストデータを「ファイル出力」【無条件、ReWrite】
    --予め、Excelにてワークシート上の「セル領域を選択」後、[command]+[C] でクリップボードへコピー
    --Excelでセル範囲を対象としてコピーすると、TSVデータ(UTF-8、CRLF改行コード、タブ区切り「HT:Chr(09)」、セル内改行はLF)がクリップボードに格納される
    --テキストエディタでフィールドごとにタブで区切ったデータを、クリップボード格納してもOK


    ------------------------------------------------------------
    use AppleScript version "2.4" -- macOS10.10 [Yosemite] ~
    use scripting additions -- use OSAX
    use framework "Foundation" -- use AppleScriptObjC (ASOC) = Cocoa AppleScript


    activate
    set theAlias to (choose file name default name "test.tsv") --「Save file」ダイアログ
    return write_to_text_file_asUTF8(POSIX path of theAlias)



    --UTF-8指定で、テキストデータのファイル書き出し
    --クリップボード内のテキストデータを「出力」【無条件、ReWrite】そのままの改行コードを適用
    --①ファイルのフルパス (POSIX path、UTF-8)
    on write_to_text_file_asUTF8(filePath as text)
    try
    set textData to "" --初期化

    --初期4096Byte(自動拡張)の NSMutableString object を生成
    set mutableStr to (current application's NSMutableString's stringWithCapacity:4096)

    -- 書き込むテキストデータの形式:(UTF-8、複数「列」なら「水平タブ:HT」を挟む)
    if (clipboard info for «class utf8») is {} then --UTF-8テキストデータ?
    activate
    display dialog "★エラー★ クリップボードが空、又はUTF-8テキスト形式以外"
    return false --実行を中断
    else
    set textData to (the clipboard as string) --そのままの改行コードが適用される
    end if

    mutableStr's appendString:textData --textDataを、NSMutableString に変換

    --atomically:true→データは一時ファイルに書き込まれ、エラーが発生しなければ指定パス名にリネーム!
    --つまり、ファイルの書き込みに失敗した場合、(既に同一ファイルが存在時)元のファイルのまま
    set theResult to mutableStr's writeToFile:filePath atomically:true encoding:(current application's NSUTF8StringEncoding) |error|:(missing value) --UTF-8指定で出力

    if (theResult as boolean) then
    return true
    else
    activate
    display dialog "★エラー★ テキストファイル書き出し 失敗"
    return false
    end if

    on error --その他のエラー時
    activate
    display dialog "★エラー★ テキストファイル書き出し 失敗"
    return false
    end try
    end write_to_text_file_asUTF8
    ------------------------------------------------------------

  • アタル
    アタル 2021年11月6日 13:55

    --Copyright 2021- ataruchi. [ https://twitter.com/ataruchi ]
    --「スクリプトエディタ.app」に以下のAppleScriptを貼り付け後 [command]+[R] を実行すると、指定テキストファイルを読み込み、テキストデータをクリップボードにセット!
    --実行後、Excelワークシート上に [command]+[V] で貼り付け可能
    --Excelに貼り付け可能なテキストデータは、TSVデータ(UTF-8、CRLF改行コード、タブ区切り「HT:Chr(09)」、セル内改行はLF)
    --テキストエディタ上にも [command]+[V] で貼り付け可能


    ------------------------------------------------------------
    use AppleScript version "2.4" -- macOS10.10 [Yosemite] ~
    use scripting additions -- use OSAX
    use framework "Foundation" -- use AppleScriptObjC (ASOC) = Cocoa AppleScript


    activate
    set theAlias to (choose file) --「File」ダイアログ
    return read_text_file_asUTF8(POSIX path of theAlias)



    --テキストファイル(UTF-8)を読み込み、そのデータ全体をクリップボード(UTF-8)へ格納
    --Excel用TSVファイル(CRLF改行コード、タブ区切り「HT:Chr(09)」、セル内改行はLF)にて テスト済み
    on read_text_file_asUTF8(filePath as text) --POSIX path
    try
    set textData to "" --初期化

    --テキストデータファイルを UTF-8 で読み込み【そのままの改行コードが適用される】
    set theNSString to (current application's NSString's stringWithContentsOfFile:filePath encoding:(current application's NSUTF8StringEncoding) |error|:(missing value))

    if theNSString is (missing value) then --NSString object の生成に失敗
    error -128 --on error処理へ [注] -128 は、キャンセル時のエラー番号
    end if

    set textData to (theNSString as string) --(UTF-8)
    set the clipboard to {} --クリップボードの初期化
    set the clipboard to textData --読み込みファイルデータを、クリップボードへ格納(UTF-8)

    return true --テキストファイル読み込み 成功

    on error --エラー時
    activate
    display dialog "★エラー★ テキストファイル読み込み 失敗"
    return false
    end try
    end read_text_file_asUTF8
    ------------------------------------------------------------

Add Comment
comment url