Google Sheets - Horizontal merge identical cells in single row

后端 未结 1 1753
清歌不尽
清歌不尽 2021-01-07 02:49

I am working towards updating a sample of code seen at: Merge cells with same words Provided by @Tanaike

I am essentially trying to do the same thing as the sample c

相关标签:
1条回答
  • 2021-01-07 03:26

    If I understand correctly you want to transform a row of cells that looks like this:

    Jan | Jan | Feb | Feb | Feb | Mar | Apr | Apr | Apr |

    into this:

    Jan | Feb | Mar | Apr |

    If so, I can help!

    Step 1. Getting Data

    I think part of your issue comes from your call to getRange(row, column, numRows, numColumns).

    In a comment you say var start = 6 is the start row, but you put it in the column spot. Not sure what you intended, but it might be more clear to have a startRow and a startCol variable. Eg,

    var startRow = 1;
    var startCol = 1;
    
    // Later...
    ss.getRange(startRow, startCol, 1, ss.getLastColumn())
    

    Calling Range.getValues() in a Google Script returns a two dimensional "array-of-arrays." With the example cells I provided you would get something like:

    data = [['Jan', 'Jan', 'Feb', 'Feb', 'Feb', 'Mar', 'Apr', 'Apr', 'Apr']]
    

    Since we're just dealing with one row, we can take the first item of this outer array and call that data, simplifying things a bit. So I would do:

    var data = ss
     .getRange(startRow, startCol, 1, ss.getLastColumn())
     .getValues()
     .filter(String)[0];
    

    Which gives you:

    data = ['Jan', 'Jan', 'Feb', 'Feb', 'Feb', 'Mar', 'Apr', 'Apr', 'Apr']
    

    Step 2. Counting duplicate values

    The next bit of code deals with counting how many times each month is duplicated. With our nice, one-dimensional array we can make the code a little simpler:

    data.forEach(function(e) {
      c[e] = c[e] ? c[e] + 1 : 1;
    });
    

    Here we're looping over the array data, dealing with each entry "e" in turn. (e will be "Jan", then "Jan" again, then "Feb"). We're storing the counts in an object, c which starts off blank and will look like this when we're finished:

    c = {Feb: 3.0, Apr: 3.0, Jan: 2.0, Mar: 1.0}
    

    The ? and : stuff is fancy JavaScript ternary syntax, which is basically saying:

        c[e] = c[e] ? c[e] + 1 : 1;
       [-----] [-----][-------][---]
          |       |       |      |
          |       v       |      |
    (1) "have we already created an entry in c for this month e (eg, "Jan")?
          |               |      |
          |               v      |
    (2) "if so, COUNT is the current value (look it up) plus 1
          |                      |
          |                      v
    (3)   |            "if not, COUNT is 1"
          |
          v
    (4) "store the COUNT we found in c"
    

    Step 3. Merge duplicate values

    The final step could look like this:

    data.forEach(function(e) {
      if (e != k) {
        ss.getRange(startRow, startCol + offset, 1, c[e]).merge();
        offset += c[e];
      }
      k = e;
    });
    

    Again, things are a tiny bit simpler because data is now a 1d array instead of a 2d array.

    Complete Code

    function mergeMonths() {
    
      var startRow = 1;
      var startCol = 1;
      var c = {};
      var k = "";
      var offset = 0;
    
      var ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("BlockingChart1");
    
      // Get data from sheet
      var data = ss
      .getRange(startRow, startCol, 1, ss.getLastColumn())
      .getValues()
      .filter(String)[0];
    
      // Count duplicates
      data.forEach(function(e) {
        c[e] = c[e] ? c[e] + 1 : 1;
      });
    
      // Merge duplicate cells
      data.forEach(function(e) {
        if (e != k) {
          ss.getRange(startRow, startCol + offset, 1, c[e]).merge();
          offset += c[e];
        }
        k = e;
      });
    
    }
    

    Quick Tip

    One final tip: The logger is super helpful for seeing what's going on in your code. When you're testing your code I would stick lines like:

    Logger.log("data: %s", data);
    

    and

    Logger.log("e: %s", e);
    

    All over the place, then check the Google Scripts log (view > logs) to understand what your variables are at different points.

    0 讨论(0)
提交回复
热议问题