:note

とりあえずから実用へ(プロンプト版セル幅調整スクリプト)

web系のスクリプトと違い、dtp系のスクリプトの場合とりあえず目の前の仕事をつぶすために動けばいいレベルのことが多いと思います。

例えばたくさんの表組のセル幅を不規則な値に設定しないといけない場合。

表パネルから数値入力していたら、セルを選択>数値入力>セル移動>数値入力…の繰り返し。

面倒なので簡単なスクリプトを書いて、後からいろいろと機能を追加してみる。

var selObj = app.selection[0];
var celObj = selObj.cells;
var currentW = celObj.everyItem().width;
var eachWPrompt = prompt(",で区切ったセル幅を入力",currentW);
if(eachWPrompt != undefined){
  for (var i=0, iL=celObj.length; i < iL ; i++) {
    celObj[i].width = eachWArr[i]*1;
  }
}

3分で書いて、こんなので乗り切ります。

とりあえずから実用へ(プロンプト版セル幅調整スクリプト) /images/2010/09/782-table_prompt.png

処理のイメージできれば書き捨てなものの書出しはいつもこんな感じです。 使い方を気をつければ実用的に使えますが、これじゃあんまりなのでいじっていきます。

エラー処理と機能追加をしていく

//ドキュメントを開いていない、選択していないならやめる
if(app.documents.length == 0 || app.selection.length == 0){exit();}
var selObj = app.selection[0];
//選択しているのが表組かどうか
switch(selObj.constructor.name){
  case "Table":
  case "Cell":
    if(selObj.rows.length == 1){
      main (selObj)//--条件がそろったここに処理をいれる
    }
    else{
      alert("一行のみ選択して下さい");
      exit();
    }
    break;
  default :// TableとCell以外は無視
    alert("セルを選択して下さい");
    break;
}
//switch文の中に式がずらずらあるとわかりにくくなるのでとっとと関数にする
function main (selObj) {
  var celObj = selObj.cells;
  var currentW = celObj.everyItem().width;
  var eachWPrompt = prompt(",で区切ったセル幅を入力",currentW);
  if(eachWPrompt != undefined){
    var eachWArr = eachWPrompt.split(",");
    for (var i=0, iL=celObj.length; i < iL ; i++) {
      if(eachWArr[i]*1 > 1){
        celObj[i].width = eachWArr[i]*1;
      }
    }
  }
}

これでまーまー動きます。

でも、自分が使わないと

  • プロンプトの内容とセルの数が不整合
  • プロンプトの内容が数値じゃない。全角数字とか
  • プロンプトの内容に計算式をいれてみる

人がいたりするわけでその辺をちょこちょこっと追加していく

セルの数と合っているか

if(eachWArr.length == celObj.length){
  //プロンプトの入力とセルの数が一致したら実行
}

入力された値が1以上の数値かのチェック

if(eachWArr[i]*1 > 1){
    //プロンプトの内容が1以上の数値なら実行
  }
  else{
    //数値以外が入力されたときの処理(処理しない=最初に取得したセル幅にする)
  }

計算式を反映させたいのでプロンプトの文字列を数値化する前にeval()で計算してみる

eval(eachWArr[i])*1

これらを追加、 さらに結合セルの場合(処理自体は可能だけど不都合があるときもある)はスキップしたいとかを追加するとこんな感じになります。

/**
* InDesignで選択したセルの幅をまとめて変える
* 実行するとプロンプトが出るのでカンマ区切りで数値を入力する。(計算式も可)
*
* 条件
* ・表組セルが1行だけ選ばれている
* ・結合セルが含まれていない
*/
if(app.documents.length == 0 || app.selection.length == 0){exit();}
var selObj = app.selection[0];
switch(selObj.constructor.name){
  case "Table":
  case "Cell":
    if(selObj.rows.length == 1){
      main(selObj);
    }
    else{
      alert("一行のみ選択して下さい");
      exit();
    }
    break;
  default :// TableとCell以外は無視
    alert("セルを選択して下さい");
    break;
}
function main (selObj) {
  var celObj = selObj.cells;
  if(cellMergedCheck(celObj) == true){
    alert("結合セルが含まれてます");
    exit();
  }
  var currentW = celObj.everyItem().width;
  var eachWPrompt = prompt(",で区切ったセル幅を入力",currentW);
  if(eachWPrompt != undefined){//prompt cancel => undefined
    var j = 0;
    var eachWArr = eachWPrompt.split(",");
    if(eachWArr.length == celObj.length){//セルとプロンプトの数が合っているか
      for (var i=0, iL=celObj.length; i < iL ; i++) {
        // alert(eval(eachWArr[i]));計算式でも
        if(eval(eachWArr[i])*1 > 1){
          celObj[i].width = eval(eachWArr[i])*1;
        }
        else{
          j++;
        }
      }
      if(j > 0){
        alert(j+"個のセルの値が不適切だったので処理しませんでした");
      }
    }
    else{
      alert("セル数と一致しません");
    }
  }
}
function cellMergedCheck (cellObj) {
  var mergeChecker = new Array();
  for(var i=0; i < cellObj.length; i++){
    mergeChecker.push(1);
  }
  if(cellObj.everyItem().columnSpan == mergeChecker.toString()){
    return false;
  }
  else{
    return true;
  }
}

後からダイアログをScript UIにしたいとか、パレットで常時出しておきたいとか、そういうのはスクリプトの汎用性とかもからんでくるので、また別の機会で…

 
comments powered by Disqus
back to top