1

Google スプレッドシートで「ローマ数字から 10 進数へ」関数のスクリプトを作成しようとしています。これまでのところ、以下のコードを使用して機能させることができました。

function rom2num(inputRange) {
inputRange = inputRange.replace(/\bi\b/gi,1); //convert 'I' to '1'
  return inputRange;
}

これは、入力が 1 つのセルのみの場合に完全に機能します。ただし、範囲 (A1:B2) を入力しようとすると、「オブジェクト内の関数置換が見つかりません」というエラーが表示されます。

私が達成したいことのいくつかの例:

Column A      | Column with function
i, ii, iii    | 1, 2, 3
Godfather II  | Godfather 2
iv, v, vi     | 4, 5, 6
Star Wars V   | Star Wars 5

クレヨンが示唆したように、下のセルで関数を繰り返すことを選択することもできますが、再フォーマットする必要がある範囲は 50 行、または 100 行である可能性があり、関数の 50 の余分なインスタンスをスローしたくない場合それらは使用されません。なるべく自動でやりたい。:-)

次のコードを使用するだけで、セル範囲の情報を取得し、別のセル範囲にその情報を返すことができることを知っています。

function copyRange(inputRange) {
return inputRange;
}

したがって、範囲を入力して同じ範囲を出力しても問題ありません。問題は、置換機能を組み込むことです。「toString()」関数を使用して、範囲全体の情報を変更することができました。そして、「split(",")」を使用して出力を複数の列に分割することができましたが、行だけでなく、列全体に広げたくありません。

したがって、範囲/配列を文字列に変換してから、範囲/配列に戻すことができれば...

コードを肥大化させずにこれを達成することは可能ですか? (私は初心者のスクリプト作成者であり、上記の例のように短いスクリプトを好みます。)

わかりにくかったらすいません。私はこのようなフォーラムで回答を探すのに慣れていますが、自分で質問することはありません!

ありがとう!

編集:最終的に物事が少し複雑になりすぎていることに気付いたので、クレヨンのアドバイスに従い、「ドラッグ」方法を使用しました。たくさんのハズレを救ってくれました。助けてくれてありがとう!!

4

2 に答える 2

2

https://developers.google.com/apps-script/execution_custom_functionsによると、関数は関数が呼び出されたセル内のデータのみを変更できるため、とにかく複数のセルを変更しようとしないでください。関数でそのセルを置換してから、関数を複数のセルに適用する必要があります。

例えば

A  B
i  =rom2num(A1)
i
i
i

これにより、B1 は「1」に等しくなります。ここで、マウスを B1 の上に置き、右下にあるドット ポイントを B4 までドラッグすると、行 B2-4 に適用された関数が表示されます。

編集:

あなたのコメントとあなたの質問の追加情報に照らして、私はあなたが何をしようとしているのか知っていると思います. 基本的に、セルへの値のオーバーフローを利用して、複数のセルに効果的に作用する必要があります。ええ、これは double 配列を返すことで可能です。あなたの新しい例は、ローマ数字を実際の数字に変換することを示しています..まあ、単純に実行するよりも少し複雑です.replaceが、その方法を理解したら、それを自分がやろうとしていることに変換する方法を理解できるはずです.取り組む価値を手に入れよう!そのため、これを行う方法は次のとおりです。

function rom2num(inputRange) {
  var cells = [];
  for (var i=0;i<inputRange.length;i++) {
    cells[i] = [String(inputRange[i]).replace(/i/gi,1)];
  }
  return cells;
}

この例では、範囲内の各行を繰り返し処理し、単に "i" を "1" に置き換えます。次に、値の double 配列を返します。たとえば、

A              B
i, ii, iii     =rom2num(A1:A4)
Godfather II
iv, v, vi
Star Wars V

関数は次のように返され、セルをオーバーフローさせます。

A               B
i, ii, iii      1, 11, 111
Godfather II    Godfather 11
iv, v, vi       1v, v, v1
Star Wars V     Star Wars V

私が言ったように、.replace実際にローマ数字を数字に変換するには(私が提供したリンクに移動する)以上のことをする必要がありますが、実際の質問に関しては、これでうまくいくはずです。

編集2:

実際に見てみたかったので、ローマ数字変換機能を組み込んでみました。したがって、最終的なスクリプトを共有することもできます。

function rom2num(inputRange) {
  var cells = [];
  for (var i=0;i<inputRange.length;i++) {
    cells[i] = [
      String(inputRange[i]).replace(/\b([ivxcldm]+)\b/gi,function(p,p1) {
        return deromanize(p1); 
      })
    ];
  }
  return cells;
}

function deromanize (str) {
    var str = str.toUpperCase(),
        validator = /^M*(?:D?C{0,3}|C[MD])(?:L?X{0,3}|X[CL])(?:V?I{0,3}|I[XV])$/,
        token = /[MDLV]|C[MD]?|X[CL]?|I[XV]?/g,
        key = {M:1000,CM:900,D:500,CD:400,C:100,XC:90,L:50,XL:40,X:10,IX:9,V:5,IV:4,I:1},
        num = 0, m;
    if (!(str && validator.test(str)))
        return false;
    while (m = token.exec(str))
        num += key[m[0]];
    return num;
}

前と同じこと...列Aには操作したいものがあり=rom2num(A1:A4)、列Bの最初のセルに入れます。これにより、変換されたローマ数字が列Bの各セルに配置され、列Aのセルと並んでいます。ただし、実際には個々の An > Bn セルを変更するのではなく、指定した範囲を実際に取得し、結果を複数のセルにオーバーフローさせていることを覚えておいてください。それはあなたが望むことを効果的に行いますが、まったく同じではありません。

于 2013-04-11T02:52:56.510 に答える