/** Main function to add a new movement entry from the 'Schedule' tab
* to the appropriate table on the 'Movements' tab.
* Assign this function to your "Save" button.
*/
function addMovementEntry() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var scheduleSheet = ss.getSheetByName("Schedule");
// Assuming the entry line is on Row 2.
// A2 is the dropdown, B2:J2 are the 9 data points.
var entryRange = scheduleSheet.getRange("A2:J2");
var entryValues = entryRange.getValues()[0];
var targetRangeName = entryValues[0]; // The named range from the dropdown
var dataToLog = entryValues.slice(1); // The 9 data points
// Validation: Check if a movement is selected
if (!targetRangeName || targetRangeName === "") {
SpreadsheetApp.getUi().alert("Please select a Movement from the dropdown in column A.");
return;
}
// Validation: Check if at least a date is entered
if (dataToLog[0] === "") {
SpreadsheetApp.getUi().alert("Please enter at least a Date for the entry.");
return;
}
// Get the target named range
var targetRange = ss.getRangeByName(targetRangeName);
if (!targetRange) {
SpreadsheetApp.getUi().alert("Could not find the table named '" + targetRangeName + "'. Check your named ranges.");
return;
}
// Find the next empty row within this specific named range
var rangeValues = targetRange.getValues();
var nextEmptyRowIndex = -1;
// We start the loop at index 2 (which is the 3rd row of the named range)
// because index 0 is the Title, and index 1 is the Column Headers.
for (var i = 2; i < rangeValues.length; i++) {
if (rangeValues[i][0] === "") { // Checking the "Date" column to see if it's empty
nextEmptyRowIndex = i;
break;
}
}
if (nextEmptyRowIndex === -1) {
SpreadsheetApp.getUi().alert("The table for " + targetRangeName + " is full! Please expand the named range.");
return;
}
// Write the data to the correct row and columns
// targetRange.getRow() gets the absolute starting row (e.g., Row 2)
var writeRow = targetRange.getRow() + nextEmptyRowIndex;
var writeCol = targetRange.getColumn();
var writeSheet = targetRange.getSheet();
writeSheet.getRange(writeRow, writeCol, 1, 9).setValues([dataToLog]);
// Clear the input fields on the Schedule sheet (B2:J2), leaving the dropdown intact
scheduleSheet.getRange("B2:J2").clearContent();
// Show a success message
ss.toast("Entry added successfully to " + targetRangeName + "!", "Success", 3);
}
/** Bonus function: Recalls the most recent entry from the selected table
* and populates it back into the 'Schedule' tab.
* Assign this function to a "Recall Last" button.
*/
function recallLastEntry() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var scheduleSheet = ss.getSheetByName("Schedule");
// Get the selected movement from the dropdown in A2
var targetRangeName = scheduleSheet.getRange("A2").getValue();
if (!targetRangeName || targetRangeName === "") {
SpreadsheetApp.getUi().alert("Please select a Movement in column A to recall.");
return;
}
var targetRange = ss.getRangeByName(targetRangeName);
if (!targetRange) {
SpreadsheetApp.getUi().alert("Could not find the table named '" + targetRangeName + "'.");
return;
}
var rangeValues = targetRange.getValues();
var lastUsedRowIndex = -1;
// Find the last row that HAS data
for (var i = 2; i < rangeValues.length; i++) {
if (rangeValues[i][0] === "") {
lastUsedRowIndex = i - 1; // The row right before the empty one
break;
}
}
// If lastUsedRowIndex is 1, it means only the headers exist
if (lastUsedRowIndex <= 1) {
SpreadsheetApp.getUi().alert("There are no entries logged for " + targetRangeName + " yet.");
return;
}
// Extract the data from the last used row
var lastData = rangeValues[lastUsedRowIndex];
// Write the data back to the Schedule entry line (B2:J2)
scheduleSheet.getRange("B2:J2").setValues([lastData]);
ss.toast("Last entry for " + targetRangeName + " has been recalled.", "Success", 3);
}