IAmMoonie

r/sheets: Randomize a range of numbers in a column

Sep 15th, 2024
325
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
JavaScript 5.58 KB | Source Code | 0 0
  1. /**
  2.  * @fileoverview Randomiser Tool for Google Sheets.
  3.  * @author u/IAmMoonie
  4.  * @version 1.0
  5.  * @see https://www.reddit.com/r/sheets/comments/1fhgtb3/randomize_a_range_of_numbers_in_a_column/
  6.  */
  7.  
  8. /**
  9.  * Configuration object for the Randomiser Tool. You can modify this as necessary.
  10.  * @const {Object}
  11.  * @property {string} menuName - The name of the custom menu in Google Sheets.
  12.  * @property {number[]} defaultRange - The default range of numbers for randomisation, specified as [min, max].
  13.  */
  14. const config = {
  15.   menuName: "Randomiser Tool",
  16.   defaultRange: [0, 9]
  17. };
  18.  
  19. /**
  20.  * WARNING: Do not edit anything below this point unless you are familiar with Google Apps Script and the purpose of the code.
  21.  */
  22.  
  23. /**
  24.  * Creates the custom menu in Google Sheets UI when the document is opened.
  25.  * @function
  26.  */
  27. const onOpen = () => {
  28.   const ui = SpreadsheetApp.getUi();
  29.   ui.createMenu(config.menuName)
  30.     .addItem("Randomise Cell Values", "showPrompt_")
  31.     .addItem("Configuration", "openScriptPage_")
  32.     .addToUi();
  33. };
  34.  
  35. /**
  36.  * Opens a modal dialog that redirects to the script configuration page.
  37.  * @param {string} url - The URL of the script configuration page.
  38.  * @function
  39.  */
  40. const openURL_ = (url) => {
  41.   SpreadsheetApp.getUi().showModalDialog(
  42.     HtmlService.createHtmlOutput(`<script>
  43.         window.addEventListener('load', () => {
  44.           window.open('${url}');
  45.           google.script.host.close();
  46.         });
  47.       </script>`),
  48.     "Opening Script Config..."
  49.   );
  50. };
  51.  
  52. /**
  53.  * Opens the script configuration page in the script editor.
  54.  * @function
  55.  */
  56. const openScriptPage_ = () => {
  57.   try {
  58.     const scriptId = ScriptApp.getScriptId();
  59.     const scriptUrl = `https://script.google.com/d/${scriptId}/edit`;
  60.     openURL_(scriptUrl);
  61.   } catch (error) {
  62.     console.error("Failed to open script page: ", error);
  63.     SpreadsheetApp.getUi().alert("Error opening script configuration.");
  64.   }
  65. };
  66.  
  67. /**
  68.  * Prompts the user to input cell ranges and configure randomisation settings.
  69.  * @function
  70.  */
  71. const showPrompt_ = () => {
  72.   const ui = SpreadsheetApp.getUi();
  73.   const rangeResponse = ui.prompt(
  74.     "Randomiser Tool",
  75.     "Enter the range (e.g., A2:A11 or a list of comma-separated ranges like A2:A7, A9, A10:A11):",
  76.     ui.ButtonSet.OK_CANCEL
  77.   );
  78.   if (rangeResponse.getSelectedButton() !== ui.Button.OK) return;
  79.   const input = rangeResponse.getResponseText().trim();
  80.   const useDefaultRangeResponse = ui.alert(
  81.     "Randomiser Tool",
  82.     `Use Default Random Number Range [${config.defaultRange[0]}-${config.defaultRange[1]}]?`,
  83.     ui.ButtonSet.YES_NO
  84.   );
  85.   let min;
  86.   let max;
  87.   if (useDefaultRangeResponse === ui.Button.YES) {
  88.     [min, max] = config.defaultRange;
  89.   } else {
  90.     min = getNumberInput_(ui, "Enter the minimum value:");
  91.     max = getNumberInput_(ui, "Enter the maximum value:");
  92.     if (min === null || max === null || min > max) {
  93.       ui.alert("Invalid min/max values. Please try again.");
  94.       return;
  95.     }
  96.   }
  97.   try {
  98.     randomiseCellValues_(parseRanges_(input), min, max);
  99.     ui.alert("Randomisation Complete!");
  100.   } catch (error) {
  101.     console.error("Error randomising cell values: ", error);
  102.     ui.alert("Error", `Invalid input: ${error.message}`);
  103.   }
  104. };
  105.  
  106. /**
  107.  * Prompts the user to enter a number.
  108.  * @param {GoogleAppsScript.Base.Ui} ui - The Google Sheets UI instance.
  109.  * @param {string} message - The prompt message.
  110.  * @returns {number|null} The user-input number or null if the prompt was cancelled.
  111.  * @function
  112.  */
  113. const getNumberInput_ = (ui, message) => {
  114.   const response = ui.prompt(
  115.     "Randomiser Tool",
  116.     message,
  117.     ui.ButtonSet.OK_CANCEL
  118.   );
  119.   return response.getSelectedButton() === ui.Button.OK
  120.     ? parseInt(response.getResponseText().trim(), 10)
  121.     : null;
  122. };
  123.  
  124. /**
  125.  * Parses a comma-separated string of ranges into Google Sheets Range objects.
  126.  * @param {string} input - The comma-separated string of cell ranges.
  127.  * @returns {GoogleAppsScript.Spreadsheet.Range[]} An array of Google Sheets Range objects.
  128.  * @throws {Error} If the input format is invalid or ranges cannot be parsed.
  129.  * @function
  130.  */
  131. const parseRanges_ = (input) => {
  132.   const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  133.   try {
  134.     return input.split(",").map((r) => sheet.getRange(r.trim()));
  135.   } catch (error) {
  136.     console.error("Failed to parse ranges: ", error);
  137.     throw new Error("Invalid range format.");
  138.   }
  139. };
  140.  
  141. /**
  142.  * Randomises the values in the specified ranges within the given range of numbers.
  143.  * @param {GoogleAppsScript.Spreadsheet.Range[]} ranges - An array of Google Sheets Range objects to randomise.
  144.  * @param {number} min - The minimum value for randomisation.
  145.  * @param {number} max - The maximum value for randomisation.
  146.  * @function
  147.  */
  148. const randomiseCellValues_ = (ranges, min, max) => {
  149.   ranges.forEach((range) => {
  150.     const numRows = range.getNumRows();
  151.     const numCols = range.getNumColumns();
  152.     const values = Array.from(
  153.       {
  154.         length: numRows
  155.       },
  156.       () =>
  157.         Array.from(
  158.           {
  159.             length: numCols
  160.           },
  161.           () => getRandomInt_(min, max)
  162.         )
  163.     );
  164.     range.setValues(values);
  165.   });
  166.   SpreadsheetApp.flush();
  167. };
  168.  
  169. /**
  170.  * Generates a random integer between the specified minimum and maximum values, inclusive.
  171.  * @param {number} min - The minimum value.
  172.  * @param {number} max - The maximum value.
  173.  * @returns {number} A random integer between min and max, inclusive.
  174.  * @function
  175.  */
  176. const getRandomInt_ = (min, max) =>
  177.   Math.floor(Math.random() * (max - min + 1)) + min;
  178.  
Advertisement
Add Comment
Please, Sign In to add comment