1
votes

I'm trying to take a row of data in Google Sheets and transpose it into multiple rows in a new worksheet. See example spreadsheet. Each row should have the filenames for one product. The products can be distinguished by the unique hex product ID (which is the first four characters of the filename).

I assume that if this can be done it will be done with a combination of ARRAYFORMULA and TRANSPOSE, but I'm wondering if it can actually be done with standard Sheets formulas at all.

The list of filenames I would be pasting in could always have blank rows between products, so any formula/script could either use the blank rows or the 4-character ID to determine when to create a new row.

2

2 Answers

2
votes

As you say, this is very well suited to using the =TRANSPOSE function.

Using Range.getValues() will give a 2-dimensional array that is trivial to transpose in code. Like the answer here for example.

From there, set a write rage to match the dimensions of the transposed array and then Range.setValues()

edit

Custom function that repeats the desired result.

/**
 * Pivots the list of images by image key
 *
 * @param {Range} range The range of values. Assumes a column.
 * @return The range of results as array per image key
 * @customfunction
 */
function PIVOTIMAGES(range) {
  var imagesByKey = {};

  range
  .map(function(d){ return d[0]; }) // assumes single column
  .filter(function(d) { return d && d != ''; }) // filters out blank rows
  .forEach(function(d){   // arranges all images as an array per key
    var key = d.split('_')[0]; // assumes key is always XXX_
    if (!imagesByKey[key]) {
      imagesByKey[key] = [d];
    } else {
      imagesByKey[key].push(d);
    }
  });

  return Object.keys(imagesByKey).map(function(key) {
    return imagesByKey[key];
  }); 
}

This would need some work to deal with receiving multiple columns of information or information in a row not a column, but in principle, this is a simple solution.

I've added it to your example sheet. Use it as a formula =PIVOTIMAGES(A2:A10) for example.

2
votes

I found an indirect solution. It's not very elegant, but it's the best I can figure out. See it in the third tab of the updated example spreadsheet. I added explanatory comments, too.

In case that example spreadsheet is eventually lost to time, here's a quick overview of the formulas I used for posterity.

In column A of a new worksheet I used the =left(Input!A1,4) formula to reproduce the first four characters of each filename in the original list.

Then I used =UNIQUE(FILTER(A:A,A:A<>"")) to create a deduped list of the product IDs from column A of the new worksheet.

Finally, I used the list of product IDs to build a FILTER formula that I could then transpose to get my desired results: =IF(ISBLANK(A1),"",TRANSPOSE(FILTER(Input!A$1:A,REGEXMATCH(Input!A$1:A,"^"&B1))))

The RegEx formula matches anything that starts (^) with the product ID in cell B1. I added an ISBLANK formula to avoid getting errors in empty rows.