2016-04-23 34 views
0

列Aに「Condemnation」や「Income」のような長い単語の表があり、B列に「Con」や「Come」などの短い単語があります。Googleの検索で一致するテキストと一致するシートの列

「SHORTER WORD」列のテキストが含まれていて、それをペアとして印刷すると、「LONG WORD」列を検索するセルを右側に作成したいと考えています。

私は、最初のインスタンスが戻ってくるのを待つだけです。

私はさまざまなMATCHおよびLOOKUPコマンドを見てきましたが、まったく「完全な列から1つの一致するワードを戻す」ビットを実行できないようです。

おかげで

遅刻

+1

サンプルデータを含むサンプルスプレッドシートを含めることができれば助かります。好奇心のために、スクリプトベースのソリューションがあなたのために働くか、これをスプレッドシート機能にする必要がありますか? –

+0

@ douglasg14b申し訳ありませんが、私はここに返信できることを認識していませんでした!私はスクリプトベースのソリューションを試してみてうれしいです。私はROWとSORT、さらにはREGEXREPLACEを使いこなしてきましたが、無駄です! –

+0

起きたときにスクリプトベースのソリューションを一緒に投げることができるかどうかがわかります。パブリックシートに小さなデータサンプルを提供できればそれは素晴らしいものです。さもなければ、私はそれがどのように配置されているかについて仮定をしなければならないでしょう。 –

答えて

1

私はあなたのためのスクリプトベースのソリューションを一緒に投げた。部分的な部分がある可能性のある行ごとに式を必要とするその他のソリューションは、大量のデータセットではシートをかなりぶつけてしまいます。これにより、データが数万行になると数秒後に一致範囲が生成されるはずです。

注:サンプルデータセットを提供しないことを選択したので、私はそれがどのようにレイアウトされているかを想定しなければなりませんでした。ただし、Full Words,PartialsMatchesというタイトルが付いている場合は、列の位置に関係なく機能します。

Google Sheetはちょうどそれがマッチを生成させるGet Matchesボタンをクリックしてください:スプレッドシートに

リンク(ボタンを使用するには、Googleアカウントにログインする必要があり)。

ソースは必要以上に複雑な/動的なものですが、私は再利用したばかりの機能を既に用意していました。

出典:いくつかの決定に

//Retrieves all the necessary word matches 
function GetWordMatches() { 
    var spreadsheet = SpreadsheetApp.openById('1s0S2iJ7L0wEXgVsKrpuK-aLysaxfHYRDQgp3ShPR8Ns').getSheetByName('Matches'); 
    var dataRange = spreadsheet.getDataRange(); 
    var valuesRange = dataRange.getValues(); 
    var columns = GetColumns(valuesRange, dataRange.getNumColumns(), 0); 

    var fullWordsData = GetColumnAsArray(valuesRange, columns.columns['Full Words'].index, true, 1); 
    var partialsArray = GetColumnAsArray(valuesRange, columns.columns['Partials'].index, true, 1); 
    var partialsData = GeneratePartialsRegexArray(partialsArray); 

    var matches = GenerateMatches(fullWordsData, partialsData); 

    WriteMatchesToSheet(spreadsheet, columns.columns['Matches'].index, matches, partialsArray); 
} 

//Writes the matches to the sheet 
function WriteMatchesToSheet(spreadsheet, matchesColumnIndex, matches, partialsArray){ 
    var sortedMatches = SortByKeys(matches, partialsArray); 
    var dataRange = spreadsheet.getRange(2, matchesColumnIndex+1, sortedMatches.length); 
    dataRange.setValues(sortedMatches); 
} 

//Generates an array of matches for the full words and partials 
function GenerateMatches(fullwordsData, partialsData){ 
    var output = []; 
    var totalLoops = 0; 

    for(var i = 0; i < fullwordsData.length; i++){ 
    totalLoops++; 
    for(var ii = 0; ii < partialsData.length; ii++){ 
     totalLoops++; 
     var result = fullwordsData[i].match(partialsData[ii].regex) 
     if(result){ 
     output.push([fullwordsData[i], partialsData[ii].value]); 
     partialsData.splice(ii, 1); 
     break; 
     } 
    } 
    } 
    if(partialsData.length > 0){ 
    var missedData = GenerateMissedPartialsArray(partialsData); 
    output = output.concat(missedData); 
    } 
    return output; 
} 

//Generates a missed partials array based on the partials that found no match. 
function GenerateMissedPartialsArray(partialsData){ 
    var output = []; 
    for(var i = 0; i < partialsData.length; i++){ 
    output.push(['No Match', partialsData[i].value]) 
    } 
    return output; 
} 

//Generates the regex array for the partials 
function GeneratePartialsRegexArray(partialsArray){ 
    var output = []; 
    for(var i = 0; i < partialsArray.length; i++){ 
    output.push({regex: new RegExp(partialsArray[i], 'i'), value: partialsArray[i]}); 
    } 
    return output; 
} 

//http://stackoverflow.com/a/13305008/3547347 
function SortByKeys(itemsArray, sortingArray){ 
    var itemsMap = CreateItemsMap(itemsArray), result = []; 
    for (var i = 0; i < sortingArray.length; ++i) { 
    var key = sortingArray[i]; 
    result.push([itemsMap[key].shift()]); 
    } 
    return result; 
} 

//http://stackoverflow.com/a/13305008/3547347 
function CreateItemsMap(itemsArray) { 
    var itemsMap = {}; 
    for (var i = 0, item; (item = itemsArray[i]); ++i) { 
    (itemsMap[item[1]] || (itemsMap[item[1]] = [])).push(item[0]); 
    } 
    return itemsMap; 
} 

//Gets a column of data as an array 
function GetColumnAsArray(valuesRange, columnIndex, ignoreBlank, startRowIndex){ 
    var output = []; 
    for(var i = startRowIndex; i < valuesRange.length; i++){ 
    if(ignoreBlank){ 
     if(valuesRange[i][columnIndex] !== ''){ 
     output.push(valuesRange[i][columnIndex]);   
     } 
     continue; 
    } 
    output.push(valuesRange[i][columnIndex]); 
    } 
    return output; 
} 

//Gets a columns object for the sheet for easy indexing 
function GetColumns(valuesRange, columnCount, rowIndex) 
{ 
    var columns = { 
    columns: {}, 
    length: 0 
    } 

    Logger.log("Populating columns..."); 
    for(var i = 0; i < columnCount; i++) 
    { 
    if(valuesRange[0][i] !== ''){ 
     columns.columns[valuesRange[0][i]] = {index: i ,value: valuesRange[0][i]}; 
     columns.length++;  
    } 
    } 
    return columns; 
} 

注:私は、パフォーマンスのためにmap、または他のより簡潔な配列関数を使用しないことにしました。

0

MATCHとLOOKUPは、部分一致のために動作しません。

代わりに、配列式でSEARCHまたはFINDを他の関数と共に使用することもできます。

例:

  • 列Aは、長い文字列のリストを含む
  • セルB1
  • 短い文字列を含むセルC1の短絡を含む列aの最初の長い文字列を返す式を含みますB1の文字列
 
=ArrayFormula(INDEX(A1:A,SORT(IF(search(B1,A1:A),ROW(A1:A),),1,TRUE))) 

データ

 
+---+--------------+-------+-------------+ 
| |  A  | B |  C  | 
+---+--------------+-------+-------------+ 
| 1 | Orange juice | apple | Apple cider | 
| 2 | Apple cider |  |    | 
| 3 | Apple pay |  |    | 
+---+--------------+-------+-------------+ 
+0

Rubenに感謝します。私はこの式の問題は、正しい種類のデータのように見えるものを出力しますが、単語の入ったセルに隣接する四角形ではできないと思います。単語の巨大なリスト、そしてもしそのリストのどこかが「概念」であれば、「con」という単語の隣のセルに「concept」を抽出し、「con」の隣に置きます。 –

+0

@ tardypigeonリストに 'concept'と' congregate'が含まれているとどうなりますか? 'con'を検索するときにどの単語を選択したいのか、または' con'の隣の単語をすべてリストにしたいのですか? –

+0

ハイダグラス。私は長い単語のリストをランダム化するつもりなので、最初のインスタンスを返すことが必要です。 –

0

OK、私は答えを見つけたと思います。他の誰かに使用されている場合に備えて、私はここに掲載します。

信用を与えるためにどこ信用の原因だ、私found it here

これは私が探していたものを行います。

=INDEX($D$1:$D$3,MATCH(1,COUNTIF(A1,"*"&$D$1:$D$3&"*"),0)) 

すべてが狂ったように相互参照されているため、それは多くのことをスローEVERYTHINGをダウンし(私が持っていました私のスプレッドシート上の3000行)、D1-3に単語のリストがあると、A1セルにそれらの単語の1つが含まれていて、一致する単語が印刷されているかどうかがわかります。

解決策を提供してくれた皆様、特に@ douglasg14bのおかげで、メモリの面で課税されることが少なくなった場合、これは素晴らしいことですが、これはやや遅いです!

おかげ

遅刻

+0

問題に関する詳細を追加する代わりに、質問に追加してください。 –

0

これはあまりにも動作します:

=QUERY(FILTER($D$1:$D$3,REGEXMATCH(A1,"(?i)"&$D$1:$D$3)),"limit 1") 

我々はREGEXMATCHを使用して(?i)は、検索、大文字と小文字を区別しないになります。クエリ内のlimit 1は、最初のオカレンスのみを返します。

+0

マックスありがとう、私はそれを後で試してみて、それがもっと効率的に働くかどうかを知らせます! –

関連する問題