簡體   English   中英

Google 表格腳本:如果 substring 在另一列中,則返回值

[英]Google Sheets script: return value if substring is within another column

一般來說,我是 Javascript/Sheets/scripts 的新手(閱讀:現在只是第一次看 JS),所以請原諒我這是多么基本。 我做了很多獨立的研究,但沒有運氣。

我有一個電子表格,其中有一列全名(全部大寫 - LAST、FIRST 格式),分成兩列 LAST 和 FIRST(全名通過逗號分隔),然后是一個包含全名的小寫列First Last 格式的人。

數據中存在一些錯誤 - 例如,LAST、FIRST 后面可能跟有完全不同的名稱的 First Last,或者前一列的拼寫錯誤。 我基本上是在內容不匹配時嘗試標記它,無論是拼寫還是整體名稱。

我編寫了這個簡單的腳本,它以 First Last 格式(F 列)提取名字(D 列)和全名,並檢查全名中是否包含名字。 假設它應該在 G 列中返回 search() 的值。這樣我可以使用條件格式來標記任何從失敗的搜索中出現的 #VALUE。 表示需要檢查該行。

不幸的是,腳本無限運行,我無法弄清楚為什么我無法打斷點並實際返回實際工作表中相應列中的值。 這是一個很小的項目,我正在努力證明從頭開始學習腳本和表格之間的界面是合理的,所以我非常感謝一些幫助! 謝謝!

   function checkName() {
      var s = SpreadsheetApp.getActiveSheet();
      var data = s.getDataRange().getValues();
      var data_len = data.length;
      for(var i=6; i<data_len; i++) {
        var fname = SpreadsheetApp.getActiveSheet().getRange(i, 4).getValue();
        var fullname = SpreadsheetApp.getActiveSheet().getRange(i, 6).getValue();
        s.getRange(i, 7).setValue(fullname.includes(fname));    
      }
    }

以下是我如何編寫 function 以滿足您的要求:

function checkName() {

  // these two will be used in an Array,
  // which is 0-indexed
  const FIRST_NAME_COLUMN = 3; 
  const FULL_NAME_COLUMN = 5;

  // these two will be used in a Sheets range,
  // which is 1-indexed
  const INCLUDES_COLUMN = 7;
  const FIRST_ROW = 6;

  const s = SpreadsheetApp.getActiveSheet();
  const sheetDataRange = s.getDataRange(); // this is just the whole shebang

  // get the dimensions of the main range
  const RANGE_HEIGHT = sheetDataRange.getHeight();
  const RANGE_WIDTH = sheetDataRange.getWidth();
  
  // use your first row number to constrain the actual data range
  // we'll use this reference to create an array we can easily iterate over
  const dataRange = s.getRange( FIRST_ROW, 1, RANGE_HEIGHT, RANGE_WIDTH );

  // data is a 2-dimensional Array,
  // so you could get values like data[row][column]
  // Also, Arrays are 0-indexed, so every number is 1 less than you had originally
  const data = dataRange.getValues(); 

  Logger.log( data ); // just to inspect

  const includesArray = [];

  for (const row of data) {
    // using a for ... of loop means we don't have to track the index,
    // and we can treat each row as a 1-D array inside the loop
    const firstName = row[FIRST_NAME_COLUMN];
    const fullName = row[FULL_NAME_COLUMN];
    const included = fullName.includes(firstName); // btw this will return a value of TRUE for ones that do include and FALSE for those that don't

    Logger.log( `${firstName}, ${fullName}, ${included}` );
    // debugger;
    includesArray.push( [included] ); // adding an Array that includes just the single element, since that represents a single data column
  }

  Logger.log( includesArray );
  debugger;

  s.getRange( FIRST_ROW, INCLUDES_COLUMN, RANGE_HEIGHT, 1 ).setValues( includesArray );

}

我盡可能使用const來確定范圍並表明我不會重新分配變量。 我還為 THESE_CONSTANTS 分配了幻數,因此它們在代碼中具有一些語義含義(這只是為了我的理智)。

此外,我根本沒有觸及循環內的“數據庫”——我在這里嚴格使用 JS Arrays。 我已經使用dataRange.getValues()從工作表中提取數據,然后在使用setValues()循環之后立即將所有包含值寫入工作表。 這是您可能會在性能方面看到最佳改進的地方。

試一試,並提出您需要的任何問題!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM