InDesign JavaScript Excelの内容を配置(画像位置に)

Excelの内容を配置(画像位置に)するスクリプトは、これで良いのかな・・・？

~~~JavaScript
/*
このスクリプトを利用して起こった不具合の責任は取れません。
ご了承下さい。

更新 2022/06/24
*/

// アプリ指定
#target "indesign";

// スクリプト名
const scriptName = "Excelの内容を配置(画像位置に)";

//スクリプトの動作指定（一つのアンドゥ履歴にする、及び、アンドゥ名）
app.doScript(function(){

    // ダイアログ
    var dialogueFlg = confirm("Excelの内容を元に、同名の画像の位置にExcelの内容を入れたテキストフレームを配置します。" + "\r"
    + "\r"
    + "Excelの内容を入れるテキストフレームの雛形を複製するので、オブジェクトスタイル、段落スタイル、レイヤー等が保持されます。" + "\r"
    + "Excelの１列目はテキストフレームの１段目に、２列目は２段目に入ります。列が７つの場合は段落は７つ必要です。" + "\r"
    + "\r"
    + "Excelの内容を入れる雛形のテキストフレームを選択して、スクリプトを実行して下さい。"
    , "", scriptName);

    // Ｎｏの場合
    if(dialogueFlg == false){

        // 終了
        exit();
    }

    // excelの読み込み設定
    app.excelImportPreferences.tableFormatting = TableFormattingOptions.EXCEL_UNFORMATTED_TABLE;
    
    // アンフォーマットテーブルが選ばれていない場合
    if(app.excelImportPreferences.tableFormatting != TableFormattingOptions.EXCEL_UNFORMATTED_TABLE){
        
        // 警告
        alert("scriptでexcelを読み込む為、（excel読み込みオプションでアンフォーマットテーブルを選び）一度配置して下さい。");
        
        // 終了
        exit();
    }
    
    // 結果数
    var resultNumber = 0;
    
    // 選択が有り、かつ、TextFrameの場合
    if(app.activeDocument.selection.length > 0 && app.activeDocument.selection[0].constructor.name == "TextFrame"){
            
            // 雛形のテキストフレーム
            const templateTextFrame = app.activeDocument.selection[0];

    // 以外の場合
    }else{
            
        // 警告
        alert("雛形のテキストフレームを選択して下さい。");
            
        // 終了
        exit();
    }

    // ファイルオープンダイアログ
    var excelFile = File.openDialog("Excelファイルを選択してください","*.xlsx",false);

    // 開けなかった場合
    if(!excelFile){

        // 終了
        exit();
    }

    // 最小化
    app.activeWindow.minimize();

    // 進行状況用パレット
    var palette = new Window("palette");
    palette.text = "進行状況";
    palette.orientation = "column";
    palette.alignChildren = ["left","top"]; 
    palette.spacing = 10; 
    palette.margins = 16; 

    var group1 = palette.add("group"); 
    group1.orientation = "row"; 
    group1.alignChildren = ["left","center"]; 
    group1.spacing = 10; 
    group1.margins = 0; 

    group1.add("statictext").text = "Excel："; 

    var nowRowNumberText = group1.add("statictext");
    nowRowNumberText.text = "-------";

    group1.add("statictext").text = "/"; 

    var excelRowCellFirstItemArrayNumber = group1.add("statictext");
    excelRowCellFirstItemArrayNumber.text = "-------";

    group1.add("statictext").text = "行目"; 

    var group2 = palette.add("group"); 
    group2.orientation = "row"; 
    group2.alignChildren = ["left","center"]; 
    group2.spacing = 10; 
    group2.margins = 0; 

    group2.add("statictext").text = "配置数："; 

    var resultNumberText = group2.add("statictext"); 
    resultNumberText.text = "-------";

    // 表示
    palette.show();

    // エクセルファイル配置用のテキストフレーム追加
    const excelPlaceTextFrame = app.activeDocument.pages.firstItem().textFrames.add();
    
    // 大きさの調整
    excelPlaceTextFrame.geometricBounds = app.activeDocument.pages.firstItem().bounds;

    // 配置
    excelPlaceTextFrame.place(excelFile);
    
    // 前のテキストフレーム
    var previousTargetPreviousTextFrame = excelPlaceTextFrame;
    
    // 次のテキストフレーム
    var nextTargetTextFrame;
    
    // オーバーフロウの場合   
    while(previousTargetPreviousTextFrame.overflows == true){

        // テキストフレーム追加
        nextTargetTextFrame = app.activeDocument.pages.firstItem().textFrames.add();

        // 大きさの調整
        nextTargetTextFrame.geometricBounds = app.activeDocument.pages.firstItem().bounds;
        
        // 連結
        previousTargetPreviousTextFrame.nextTextFrame = nextTargetTextFrame;
        
        // 前のテキストフレームに入れる
        previousTargetPreviousTextFrame = nextTargetTextFrame;
    }

    // excelの最初の列のセルの情報配列
    const excelRowCellFirstItemArray = excelPlaceTextFrame.tables.firstItem().rows.everyItem().cells.firstItem().contents;
    
    // 行の数
    excelRowCellFirstItemArrayNumber.text = excelRowCellFirstItemArray.length;
    
    // リンクファイル名配列
    var linkFileNameArray = [];
    
    // リンクファイルの数だけ繰り返す
    for(var i = 0; app.activeDocument.links.count() > i; i++){
            
        // リンクファイル名収集
        linkFileNameArray.push(app.activeDocument.links.item(i).name.match(/.+(?=\.[a-z]+)/));
    }

    // リンクファイル名連結文
    const linkFileNameString = linkFileNameArray.join(",");
    
    // 正規表現オブジェクト
    var regExpObject;
    
    // 対象の画像フレーム
    var targetImageFrame;

    // 複製されたテキストフレーム
    var duplicateTextFrame;
    
    // 範囲の終わりの数値
    var itemByRangeToNumber = 0;
    
    // 移動先
    var destination;
    
    // 繰り返し数
    var repeatNumber;
    
    // 元の定規の単位
    const myRulerOrigin = app.activeDocument.viewPreferences.rulerOrigin;
    
    // 定規の単位をグリッドに（moveメソッドに影響）
    app.activeDocument.viewPreferences.rulerOrigin = RulerOrigin.SPREAD_ORIGIN;
    
    // 行の数だけ繰り返す
    for(var i = 0; excelRowCellFirstItemArray.length > i; i++){
        
        // 現在の行数表示用
        nowRowNumberText.text = i + 1; 

        // 検索文字
        regExpObject = new RegExp(excelRowCellFirstItemArray[i]);

        // 検索された場合
        if(regExpObject.test(linkFileNameString)){
            
            // リンクファイル名の数だけ繰り返す
            for(var j = 0; linkFileNameArray.length > j; j++){
            
                // エクセルの行の一列目の文字とリンクファイル名が同じ、かつ、エクセルの行の一列目の文字が有る場合
                if(excelRowCellFirstItemArray[i] == linkFileNameArray[j] && excelRowCellFirstItemArray[i] != null){
                        
                    // 対象画像のフレームに入れる
                    targetImageFrame = app.activeDocument.links.item(j).parent.parent;                     

                    // Spreadを取得
                    destination = getSpread(targetImageFrame);
                        
                    // Spreadが取得出来なかった場合
                    if(destination == undefined){
                            
                        // 警告
                        alert("Indesignの不具合（？）の為" + "\r" + (j + 1) + "つ目のリンクのSpreadが取得出来ませんでした。");
                        
                    // 以外の場合
                    }else{
                        
                        // 対象のテキストフレームを複製
                        duplicateTextFrame = templateTextFrame.duplicate();

                        // 対象画像のフレームのページに移動
                        duplicateTextFrame.move(destination);
                            
                        // 対象画像のフレームの座標（visibleBounds[ y1, x1, y2, x2 ]）に移動
                        duplicateTextFrame.move([targetImageFrame.visibleBounds[1],targetImageFrame.visibleBounds[0]]);
                            
                        // 最前面へ
                        duplicateTextFrame.bringToFront();
                        
                        // 段落の数が列の数より多い場合
                        if(duplicateTextFrame.paragraphs.count() >= excelPlaceTextFrame.tables.firstItem().columns.count()){
                            
                            // 列の数を入れる
                            repeatNumber = excelPlaceTextFrame.tables.firstItem().columns.count();

                        // 以外の場合
                        }else{
                            
                            // 段落の数を入れる
                            repeatNumber = duplicateTextFrame.paragraphs.count();
                        }
                            
                        // 繰り返しの数だけ逆に繰り返す
                        for(var k = repeatNumber - 1; k >= 0; k--){
                                
                            // 最後の場合
                            if(k == duplicateTextFrame.paragraphs.count() - 1){
                                    
                                // 最後から１つ目を入れる
                                itemByRangeToNumber = -1;
                                    
                            // 以外の場合
                            }else{
                                    
                                // 最後から２つ目を入れる（段落の終わりを残す為）
                                itemByRangeToNumber = -2;
                            }
                                    
                            // 段落にexcelの内容を入れる
                            duplicateTextFrame.paragraphs.item(k).characters.itemByRange(0,itemByRangeToNumber).contents = excelPlaceTextFrame.tables.firstItem().rows.item(i).cells.item(k).contents;
                        }
                    
                        // 結果数を増やす
                        resultNumber++;
                            
                        // 結果数表示用
                        resultNumberText.text = resultNumber;
                    
                        // ガーベージコレクション
                        $.gc();
                    }
                }
            }
        } 
    }

    // エクセルファイル配置用のテキストフレームの親ストーリーが持つテキストフレームの数だけ逆に繰り返す
    for(var i = excelPlaceTextFrame.parentStory.textContainers.length - 1; i >= 0; i--){
        
        // 削除
        excelPlaceTextFrame.parentStory.textContainers[i].remove();
    }
    
    // 定規の単位を戻す
    app.activeDocument.viewPreferences.rulerOrigin = myRulerOrigin;
    
    // 結果
    alert("配置数：" + resultNumber);
    
    // アクティブウィンドウの最大化
    app.activeWindow.maximize();
    
    // ガーベージコレクション
    $.gc();

// スクリプトの動作指定の続き
}, ScriptLanguage.JAVASCRIPT, [scriptName], UndoModes.ENTIRE_SCRIPT, scriptName);

// スプレッド取得関数（オブジェクト）
function getSpread(hierarchyObject){

    // Spread、または、MasterSpreadの場合
    if(hierarchyObject.constructor.name == "Spread" || hierarchyObject.constructor.name == "MasterSpread"){

        // 戻す
        return hierarchyObject;

    // 文字（アンカーオブジェクト）の場合
    }else if(hierarchyObject.constructor.name == "Character"){
        
        // 再帰処理（親のテキストフレーム）
        hierarchyObject = getSpread(hierarchyObject.parentTextFrames[0]);

    // 以外の場合
    }else{
        
        // 再帰処理（一つ上の階層のオブジェクト）
        hierarchyObject = getSpread(hierarchyObject.parent);
    }
    
    // 戻す
    return hierarchyObject;
}
~~~