0

Sorry for the confusing title, I'm not sure how to best describe it. I've attached screenshots to clarify. Please note that I have cut off the first column because of sensitive information. You can assume all values in the first column will be the same. Here's a dummy sheet to work with What I have is this:(starting table)

The result I'm looking for is as follows: (desired result)

So obviously in this case I did it manually to show the result I'm looking for, but what I want it to do is group by SKU where the species, form, and size are the same. This will mean that the total net weight and unit quantity columns will be summed. The issue is the "Date" column. I want this to show ALL dates from the grouped columns. I would also like it to do this with the "Case type" and "Location" columns.

For reference, here's the Query I've been using that does not reach this result (it just removes the date column). As I noted before, I have cut off the first column because of sensitive information. You can assume all values in the first column will be the same:

=QUERY({IMPORTRANGE("MY URL HERE", "'Finalized Inventory'!A3:K")}, "select Col1, Col3, Col4, Col5, Col6, SUM(Col8), Col9, Col10 where Col1<>'' GROUP BY Col1, Col3, Col4, Col5, Col6, Col8, Col9, Col10 label SUM(Col8)''")

I'm not particularly attached to this method. If there's a better way to do this, through a different query or an app script, which I'm comfortable using, that would be super helpful.

Edit: To clarify, the data is updated often and I'm seeking a solution that automatically updates as the data is updating. What I need is basically exactly the behavior of the Power Sheets "Merge and Combine" functionality, except I need it to auto-update as the data changes, where the power sheets functionality creates and static table.

Rubén
  • 34,714
  • 9
  • 70
  • 166
  • 1
    People are most likely to not help when there is a lot of data involved but only a screenshot is attached. It is like asking them to create a sheet which they need to fill in by themselves (copy the data of your screenshot) then find the solution. Please make it easy for people to help you. You can always create a sheet of dummy data that people can access and play with. By doing so, people will be more eager to help out. – Nabnub Apr 21 '21 at 07:41
  • 1
    I agree with @Nabnub, if you provide a spreadsheet with dummy data that people can use to work on a solution, you're more likely to get help. – Iamblichus Apr 21 '21 at 08:06
  • @Nabnub I have added a sheet like this – stuckinthecold Apr 21 '21 at 18:08

1 Answers1

1

Solution:

You could use Apps Script to do the following:

  • Get data from your source sheet (called Source in the sample below), using getValues().
  • Get the unique combinations of Customer, Species, Form, Size and SKU. This would require retrieving only these values from these rows, using map, and then removing all the duplicate arrays from the resulting 2D array (see this answer, for example). The resulting array (grups in the sample below) will contain all the unique combinations of Customer, Species, Form, Size and SKU.
  • Iterate through the unique combinations, and for each combination, retrieve which rows (groupRows in the sample below) from the original data match that combination, using filter.
  • Use reduce on the groupRows to sum Unit, Weight and add the different Dates, Case Types and Locations to the same value.
  • Remove duplicate Dates, Case Types and Locations from the resulting array (called groupedData). See this question for how to remove duplicate values from an array.
  • Write data to your destination sheet (called Destination in the sample below) using setValues(values), or use return groupedData; instead if you want this to be a custom function.

Code snippet:

// Copyright 2021 Google LLC.
// SPDX-License-Identifier: Apache-2.0

function myFunction() {
  const ss = SpreadsheetApp.getActive();
  const sourceSheet = ss.getSheetByName("Source");
  const sourceValues = sourceSheet.getRange(3,1,sourceSheet.getLastRow() - 2, sourceSheet.getLastColumn()).getValues(); // Get source data
  const groups = sourceValues.map(row => { // Get unique combinations
    return JSON.stringify([row[0]].concat(row.slice(2,5)).concat(row[8]));
  }).reverse().filter((e, i, a) => a.indexOf(e, i + 1) === -1)
    .reverse().map(JSON.parse);
  let groupedData = groups.map(group => {
    const groupRows = sourceValues.filter(row => { // Get matching rows
      return JSON.stringify([row[0]].concat(row.slice(2,5)).concat(row[8])) === JSON.stringify(group);
    });
    return groupRows.reduce((acc, current) => { // Adding the values from same combination
      const date = acc[1] === "" ? current[1] : acc[1] + "\n" + current[1];
      const caseType = acc[5] === current[5] ? acc[5] : acc[5] + "\n" + String(current[5]);
      const location = acc[11] === "" ? current[11] : acc[11] + "\n" + current[11];
      const unit = Number(acc[6]) + Number(current[6]);
      const weight = Number(acc[7]) + Number(current[7]);
      const comments = acc[10] + "\n" + current[10];
      return [group[0], date, ...group.slice(1,4), caseType, unit, weight, group[4], current[9], comments, location];
    }, Array(12).fill(""));
  });
  groupedData.forEach(row => { // Removing duplicate dates, case types, locations
    row[1] = [...new Set(row[1].split("\n"))].join("\n");
    row[5] = [...new Set(row[5].split("\n"))].join("\n");
    row[11] = [...new Set(row[11].split("\n"))].join("\n");
  });
  return groupedData;
}

Output:

enter image description here

Iamblichus
  • 18,540
  • 2
  • 11
  • 27
  • @CarolineRaiford This means first column values are not dates but strings, so there's no need to use `Utilities.formatDate`. Also, you could make this a custom function by adding the line `return groupedData;` at the end of the code, remove the lines regarding `Destination` sheet and `setValues`, and call `=myFunction()` in the sheet as a [custom function](https://developers.google.com/apps-script/guides/sheets/functions). I edited my code snippet to reflect all these changes. – Iamblichus Apr 21 '21 at 18:59
  • @CarolineRaiford I saw in the sample sheet you now provided there are an additional row and column in the source data. You should modify the indexes according to this when retrieving the source values at the beginning of this code. I guess indexes should be `getRange(3,2,sourceSheet.getLastRow() - 2, sourceSheet.getLastColumn() - 1`. I hope that was not the reason for the error you got before, since I'll have to rollback part of my last edit if that's the case :) – Iamblichus Apr 21 '21 at 19:06
  • Hi, I tried making those changes in the sheet but now its not working properly - not grouping dates, case type column comes up with an error, and location data doesn't show up. Do you mind taking another look in the sheet I attached? This is super close, I appreciate your help. I apologize that I'm not a bit more versed and able to adjust it better myself but I'm working on it! – stuckinthecold Apr 21 '21 at 19:53
  • @lamblicious Hi! This is super helpful. When I run it, I get the following error: Exception: The parameters (String,String,String) don't match the method signature for Utilities.formatDate. Can you help? Also, will this only work when I run it? The data updates constantly, and I need the master sheet to keep up with it. – stuckinthecold Apr 21 '21 at 20:05
  • Hi @CarolineRaiford, considering you accepted this answer, could you solve the issues raised in your last comments? – Iamblichus Apr 21 '21 at 20:13
  • @lamblicious No, sorry, I'm new to Stack exchange and I had thought it was working and then realized it wasn't. I apologize. – stuckinthecold Apr 21 '21 at 22:07
  • @CarolineRaiford I'll take a look at it tomorrow using a copy of the spreadsheet you provided. – Iamblichus Apr 21 '21 at 22:14
  • @lambliciouos much appreciated – stuckinthecold Apr 21 '21 at 22:37
  • @CarolineRaiford In the sheet you provided, you didn't fix the second index according to my suggestion `getRange(3,2,sourceSheet.getLastRow() - 2, sourceSheet.getLastColumn() - 1`, which should be `2` instead of `1` (since the column `Customer` is not part of the destination data). Because of this, all columns are shifted an you're getting problems. When you change that, it returns data successfully (see my updated answer). – Iamblichus Apr 22 '21 at 09:07
  • @lamblicious Hi, I'm going to preface this by saying I promise to be way more specific and clear in the future when I post questions on here, and always will post a sample sheet right off the bat, I'm so sorry about asking you to adjust it so many times. I'm messing around trying to get it to return the customer as well, in the first column, and as another unique identifier (i.e. "Customer 1 Blackcod 1lb portions" is not the same as "Customer 2 Blackcod 1 lb portions") does that make sense? So close. Thank you for your help. – stuckinthecold Apr 22 '21 at 18:10
  • @CarolineRaiford You just need to add the first row as part of the unique `groups`, and then fix the rest of the indexes (adding one to all). See my updated answer. – Iamblichus Apr 23 '21 at 08:03
  • @lamblicious Perfect, thank you. Looks like I need to go in and run the script in script editor to get the custom function to update as the source info updates, but that's still way better than what I was dealing with. Thanks again. – stuckinthecold Apr 23 '21 at 20:02
  • @CarolineRaiford You can edit the custom function so that it accepts the source values as a parameter, instead of getting them via `getValues()`. This way, when the source values change, the function will recalculate the output. See [custom functions arguments](https://developers.google.com/apps-script/guides/sheets/functions#arguments). – Iamblichus Apr 26 '21 at 07:07
  • @lamblichus Hi, this script has been working great, I've adjusted it a bit to accommodate new columns, but recently I've run into an issue where is returns the date format like "Tue May 03 2022 00:00:00 GMT-0800 (GMT-08:00) - 381.1 Wed May 04 2022 00:00:00 GMT-0800 (GMT-08:00) - 70.7" instead of "5/3/22 - 381.1 5/4/22 - 70.7" like it used to. Any ideas for how to change this? – stuckinthecold May 23 '22 at 03:55
  • Hi @CarolineRaiford, consider posting a new question explaining this a bit more and including a sample spreadsheet. – Iamblichus May 23 '22 at 07:04
  • @lambichus [link](https://stackoverflow.com/questions/72352872/changing-date-format-returned-in-custom-function-google-sheets-appscript?noredirect=1#comment127821907_72352872) Here is the new question, thanks! – stuckinthecold May 23 '22 at 22:23