-2

I have a google sheet with values that is getting populated

  A              B                 C           D            E             F        G      H
Top scorers   Date            Player l    Player 2      Player 3     Player 4
            13 Jan 2019            1        1            1
            20 Jan 2019            2        1                         1 

the idea is: each match day I will enter the date of the match and number of goals that each player scored, if new player score I will just put his name in new column and number of goal on that date. If any player not score that day, I will just leave that cell blank. Then I want to populate first column "Top scorers" with ranking of Player scored. Expected result will look like this:

     A         B                C            D            E            F        G        H
Top scorers   Date            Player l    Player 2      Player 3     Player 4
Player 1: 3   13 Jan 2019         1         1            1
Player 2: 2   20 Jan 2019         2         1                         1 
Player 3: 1
Player 4: 1

It will automatically updated with new data input. How could I make this? I have a look at Pivot Table but looks like it is hard to archive this result.

Sample sheet.

CalamitousCode
  • 1,324
  • 1
  • 14
  • 21
user1314404
  • 1,253
  • 3
  • 22
  • 51
  • Have updated the question to have column name. This question is very specific and it is not too broad! – user1314404 Jan 22 '19 at 05:53
  • Would you mind sharing a Google Sheet containing the data structure and showing what you've tried already? – bartinmader Jan 23 '19 at 09:33
  • I only tried pivot table but it doen;t work so I deleted it but I can share the google sheet , can you leave your email adress please? – user1314404 Jan 23 '19 at 09:37
  • In order to keep Stack Overflow public and accessible to other users, please just create a Google Document specifically for this purpose, create a viewable link and include it in your initial post. There are people much more knowledgeable than myself, let's give them the opportunity to contribute and keep the conversation going. – bartinmader Jan 23 '19 at 09:39
  • yes, done updating. – user1314404 Jan 23 '19 at 09:42

1 Answers1

1

According to the description of what you're trying to accomplish and the Google Sheet shared.

You need to break your problem down into several subtasks:

  • Selecting all the ranges you'll later need (Players, Dates, Range where you'll write your scores, range where your top scorers will be displayed)
  • Adding up each player's goals from all the games to get their total score
  • Sorting the players according to their total score
  • Create strings to write into your topscorer column
  • Write these strings into the topscorer column

My solution is pretty verbose but it seems to work. Please don't hesitate to ask if you have any questions or if clarifications are needed.

    function testMe() {

    var ID = ''; // ID of your Document
    var name = ''; // Name of your sheet
    var sourceSheet = SpreadsheetApp.openById(ID); // Selects your Source Spreadsheet by its id
    var ssheet = sourceSheet.getSheetByName(name); // Selects your Source Sheet by its name

    var scoreRange = ssheet.getRange(2, 3, (sourceSheet.getLastRow() -1), (sourceSheet.getLastColumn() -2)); // Selects the range in which you will enter your scores
    var dateRange = ssheet.getRange(2,2,(sourceSheet.getLastRow() -1)); // Selects the range for which player names in row 1
    var playerRange = ssheet.getRange(1,3,1,(sourceSheet.getLastColumn() -2)); // selects the range for which dates were entered in column
    var topScorerRange = ssheet.getRange(2,1,scoreRange.getNumColumns()); // selects the range where your topscorer output will end up

    var numberOfPlayers = playerRange.getNumColumns(); // Gets the number of players you've already entered in row 1
    var numberOfGames = playerRange.getNumRows(); // Gets the number of games whose dates you've already entered in Column B


    function sortAndUpdateTopScorers() {
        var array = scoreRange.getValues();
        var totalPlayers = scoreRange.getNumColumns();
        var totalGames = scoreRange.getNumRows();
        var playerScores = [];

      // iterate through the scoreRange and count up each players total score

           for (var i = 0; i < totalPlayers; i++) {
               var currentPlayer = 0;
               for (var j = 0; j < totalGames; j++) {
                  currentPlayer += array[j][i];
               }
             playerScores.push([currentPlayer]);
           }

      // Combine the names of the players and their total score in order to create the strings for your topscorers column

      for (var v = 0; v < numberOfPlayers; v++) {
        playerScores[v].push(playerRange.getValues()[0][v] + ": " + playerScores[v]);
      };

      // Sort those strings according to their score

      playerScores.sort(function(a,b) {
      return b[0]-a[0]
      });

      // Remove the score value so only the string remains in the array

      for (var x = 0; x < playerScores.length; x++) {
       playerScores[x].shift(); 
      }

      // Write the content of the array into your topscorers column

      topScorerRange.setValues(playerScores);

     };
sortAndUpdateTopScorers();
};
bartinmader
  • 266
  • 3
  • 10
  • I think the sum of the cells in column have some problems. If I add date: "27 Jan 2019" and one more player score on that day (player 5). Then the result start to get some strange values. Please check the sheet for the details. And 2nd question is: could we make this script run on changes of cell values, so we no need to run it from time to time ? – user1314404 Jan 28 '19 at 03:08
  • do you have any comment on this ? – user1314404 Jan 29 '19 at 03:17
  • Sorry, I've been travelling for work. I'll look into it in the upcoming days. – bartinmader Jan 29 '19 at 03:51
  • Sorry, I've been travelling for work. I'll look into it in the upcoming days. – bartinmader Jan 29 '19 at 03:51
  • It's ok, I have found out the issues and makes 4 changes: 1) instead of "getLastRow" I write a function to get number of rows in 2nd column (date column), this helps to avoid error when there are many players and the ranking column will be the one that have most row numbers, not date column as in the initial example. 2) force array[j][i] to be number instead of string which also causes error in calculation 3) instead of "sourceSheet" I use "ssheet" for all getLastColumn() and getLastRow() to avoid getting wrong index from other sheet. 4) Live run: event trigger on Edit\Current project trigger – user1314404 Jan 29 '19 at 09:33
  • However I can only make this working solution base on your proposed script which is great help and excellent work. I would accept your script as my final answer. Thank you very much for your willing to help ! – user1314404 Jan 29 '19 at 09:34