web-dev-qa-db-ja.com

Googleシートは複数行のセルを新しい行に分割します(+周囲の行エントリを複製します)

各ビジネスの主要スタッフを含む、ビジネスの住所情報のデータベースを作成しています。このプロジェクトのために私が継承したGoogleスプレッドシートには、「キースタッフ」の列(列B)があり、改行で区切られた複数のキースタッフ名が同じセルにリストされています(つまり、CHAR(10))。行ごとに1つのビジネスがあります。 「キースタッフ」セルの行数は行ごとに異なります。最初のシートは次のようになります。

enter image description here

このシートを最適化するには、次のことを行う必要があります。

  1. 各複数行の「キースタッフ」セルを分割して、各キースタッフ名がそれぞれの行に表示されるようにします。これには、元の行の下に新しい行を挿入する必要があります。
  2. 元の行の他のすべてのセル(つまり、列AおよびC:E)のデータを複製し、各新しい行に各ビジネスの完全なデータが含まれるようにします
  3. 自動化されたプロセスが必要です-約1000のビジネスを処理する必要があるため、手動の手順ではこれを実行できません

シートは次のようになります。

enter image description here

=TRANSPOSE(SPLIT(B1,CHAR(10)))を使用することは明らかに道の一部に過ぎません-新しい行を挿入せず、周囲の列エントリを複製しません。すべてのヘルプがありがたく受け入れられました!

11
kirk tab

まず第一に、遅い回答を申し訳ありませんが、私はあなたと協力するための解決策を持っています。

コード

function result(range) {
  var output2 = [];
  for(var i=0, iLen=range.length; i<iLen; i++) {
    var s = range[i][1].split("\n");    
    for(var j=0, jLen=s.length; j<jLen; j++) {
      var output1 = []; 
      for(var k=0, kLen=range[0].length; k<kLen; k++) {
        if(k == 1) {
          output1.Push(s[j]);
        } else {
          output1.Push(range[i][k]);
        }
      }
      output2.Push(output1);
    }    
  }
  return output2;
}

説明した

スクリプトは各行、特に各行の2番目の列を評価します(JavaScript配列ではゼロベースなので、列2は配列のインデックス1に対応します)。そのセルの内容を複数の値に分割し、"\n"を区切り文字(改行)として使用します。その後、既存の情報を配列に追加し、インデックス1に達したときに個々の結果のみを追加します(k == 1)。次に、新しく準備された行が別の配列に追加され、結果を表示するために返されます。

スクリーンショット

データ
enter image description here

結果
enter image description here

サンプルファイルを作成しました:新しい行に複数行のセル
Tools> Script editorの下にスクリプトを追加し、保存ボタンを押します。

11

反復可能なソリューションにはスクリプトが必要です。

ただし、1回限りの作業では、=SPLIT(B3,CHAR(10))を使用できます。これにより、次のように、サイドバイサイドヘルパー列にすべての人の名前が表示されます。

enter image description here

コピー/貼り付け専用、ヘルパー列のコンテンツの値。

そして、使用される各ヘルパー列(多すぎないこと、「1つのビジネスにあまり人がいないことを願っています」)の行ブロックを現在のブロックの最後に手動でコピーアンドペーストします。 (これは素晴らしい説明ではありませんが、ドリフトは発生します。)

3
MaryC.fromNZ

受け入れられた答えで有用な機能を使用する方法をすぐに把握できないかもしれない人々のために:

  • 複数のシートが必要です。この例では、2つのシートはDATARESULTです。 RESULTシートは、クエリが実行されるまで空です。 JacobのスクリーンショットでDATAシートを参照するクエリを確認できます。

  • ほとんどの場合、8行目のkの比較値を変更する必要があります。これは、解析するデータが見つかる列を参照します。同じ番号を4行目の2番目の配列値に入力する必要があります。

  • 現在\nである4行目の区切り文字を変更する必要がある場合があります

このすべてを少しだけ簡単にするために、同じコードを使用して、区切り文字とターゲット列を関数の上部に設定された変数に抽出しました。 Jacobが言及しているように、ターゲットの列数は最初の数として0から始まります。

function result(range) {
  delimiter = ", "
  targetColumn = 10

  var output2 = [];
  for(var i=0, iLen=range.length; i<iLen; i++) {
    var s = range[i][targetColumn].split(delimiter);    
    for(var j=0, jLen=s.length; j<jLen; j++) {
      var output1 = []; 
      for(var k=0, kLen=range[0].length; k<kLen; k++) {
        if(k == targetColumn) {
          output1.Push(s[j]);
        } else {
          output1.Push(range[i][k]);
        }
      }
      output2.Push(output1);
    }    
  }
  return output2;
}
2
jfunk

単一の式

=ARRAYFORMULA(substitute(IFERROR(
  REGEXEXTRACT(
    "_"&transpose(split(join(" ",query(substitute(
      IFERROR(transpose(FILTER(A:A,LEN(A:A)))&
      "_"&REGEXEXTRACT(CHAR(10)&transpose(FILTER(B:B,LEN(A:A))),
        "^"&REPT(CHAR(10)&"[^"&CHAR(10)&"]*",row(OFFSET(A1,,,6,1))-1)&CHAR(10)&"([^"&CHAR(10)&"]*)")&
      "_"&transpose(FILTER(C:C,LEN(A:A)))&
      "_"&transpose(FIlTER(D:D,LEN(A:A)))&
      "_"&transpose(filter(E:E,LEN(A:A))),),
      " ","|"),,1000))," ")),
    "^"&REPT("_[^_]*",COLUMN(OFFSET(A2,,,1,4))-1)&"_([^_]*)"
   )
),"|"," "))

回答 by Markus Jarderot to googleスプレッドシート内のarrayformula内で分割しようとする

使い方

パート1.リンクされた回答のソリューション

問題は、配列式を使用してドットで区切られた値の列を分割する方法についてでした。

提案された式は次のとおりです。

=ARRAYFORMULA(IFERROR(REGEXEXTRACT("."&A2:A;
    "^"&REPT("\.[^.]*";COLUMN(OFFSET(A2;;;1;4))-1)&"\.([^.]*)")))
  • OFFSET(A2 ;;; 1; 4)は1 x 4配列を返しますが、値は関係ありません。
  • COLUMNは{1,2,3,4}を返します
  • REPTは= {""、 "。[^。]"、 "。[^。]"。[^。] "、"を返します。 [^。] "。[^。]"、 "。[^。]"}
  • 「。」&A2:Aは、ドットをA2:Aの各セル値に連結します。結果は配列です。
  • REGEXEXTRACTは、前の配列の各セルに一致する部分文字列を抽出し、一致しない場合は対応する配列要素に#N/Aを返します。
  • IFERRORは、エラーを空白セルに置き換えます。
  • ARRAYFORMULAは、結果の配列によって必要な領域に結果を展開します。

パート2、適応

「単一式」セクションの式では、2回使用されました。

列Bの値を分割する

REGEXEXTRACT(
CHAR(10)&transpose(FILTER(B:B,LEN(A:A))),
"^"&REPT(CHAR(10)&"[^"&CHAR(10)&"]*",row(OFFSET(A1,,,6,1))-1)&CHAR(10)&"([^"&CHAR(10)&"]*)"
)&

正規表現では、区切り記号\.は、OPで使用されるものであるため、CHAR(10)に置き換えられました。また、値を列ではなく行に分割するために、COLUMN(OFFSET(A1,,,1,6)row(OFFSET(A1,,,6,1))に置き換えられました。これは、行を埋められるようにするために行われました。

行を埋める

行を埋めるために、最初に次の方法で、各列の転置が前の式の結果に連結されました。

transpose(FILTER(A:A,LEN(A:A)))&"_"&

前のセクションの式

&
"_"&transpose(FILTER(C:C,LEN(A:A)))&
"_"&transpose(FILTER(D:D,LEN(A:A)))&
"_"&transpose(FILTER(E:E,LEN(A:A)))

後でこの文字列を区切るために「_」が含まれていました

値を連結する

QUERYはスペースを区切り文字として使用して行を連結するため、最初に元のスペースが|に置き換えられ、次に2番目の引数なしでQUERYを3番目の引数として多数使用しました。 Googleスプレッドシートには、小さな数と大きな数の両方に制限があるため、1列のスプレッドシートに含めることができる最大行数である2E6が使用されました。

転置列を結合および分割する

転置された列は、最初にスペースを区切り文字として使用して結合され、次に結果がで分割されました。

元の形状に戻す

もう一度転置して元の形状を取得し、パート1で説明したパターンを使用して、文字列を_で分割します。

最後のタッチ

|をスペースで置き換えます。

1
Rubén