Potential Issues:
-
Configuration Sheet Read Issues:
- Ensure the 'Config' sheet exists and has the correct structure:
- Column A: Form Question Title
- Column B: Google Sheet ID
- Column C: Google Sheet Name
- If any of these values are missing or incorrect, the script may fail.
-
Incorrect Handling of getQuestionValues() Return Values:
- If getQuestionValues() returns null, attempting to process it leads to errors.
- Add additional checks to prevent breaking on missing data.
-
Mismatch Between Form Items & Sheet Data:
- Ensure form question titles exactly match the headers in the sheets.
- Trim whitespace and check for case sensitivity issues.
Fixed Code with Improved Debugging
This version includes better error handling, logging, and ensures compatibility with multiple sheets.
/** * Opens and populates Google Form dropdowns from multiple Google Sheets. */
function openForm(e) {
populateQuestions();
} /** * Populates Google Form questions using multiple sheets defined in the 'Config' sheet. */
function populateQuestions() {
var form = FormApp.getActiveForm();
var configSheet = getConfigurationSheet();
if (configSheet.length === 0) {
Logger.log("No configuration found. Ensure the 'Config' sheet exists and is correctly formatted.");
return;
}
var itemsArray = form.getItems();
configSheet.forEach(function(configRow) {
var formItemTitle = configRow[0].trim(); // Trim to avoid spaces
var sheetId = configRow[1].trim();
var sheetName = configRow[2].trim();
Logger.log("Processing question: " + formItemTitle + " from Sheet ID: " + sheetId + ", Name: " + sheetName);
var googleSheetsQuestions = getQuestionValues(sheetId, sheetName);
if (!googleSheetsQuestions || googleSheetsQuestions.length < 2) {
Logger.log("Warning: No valid data found in sheet '" + sheetName + "' for question '" + formItemTitle + "'");
return;
}
itemsArray.forEach(function(item) {
if (item.getTitle().trim() === formItemTitle) {
var choiceArray = [];
for (var j = 1; j < googleSheetsQuestions.length; j++) {
var choice = googleSheetsQuestions[j][0]; // Adjust index if multiple columns exist
if (choice && choice.toString().trim() !== '') {
choiceArray.push(choice.toString().trim());
}
}
try {
if (item.getType() == FormApp.ItemType.LIST) {
item.asListItem().setChoiceValues(choiceArray);
} else if (item.getType() == FormApp.ItemType.MULTIPLE_CHOICE) {
item.asMultipleChoiceItem().setChoiceValues(choiceArray);
} else {
Logger.log("Warning: Item type " + item.getType() + " not supported for " + formItemTitle);
}
} catch (error) {
Logger.log("Error setting choices for " + formItemTitle + ": " + error);
}
}
});
});
}
/**
* Retrieves the configuration sheet data from the active spreadsheet.
* @returns {Array<Array<string>>} Configuration rows without headers.
*/
function getConfigurationSheet() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var configSheet = ss.getSheetByName('Config');
if (!configSheet) {
Logger.log("Error: 'Config' sheet not found in the spreadsheet.");
return [];
}
var returnData = configSheet.getDataRange().getValues();
returnData.shift(); // Remove header row return returnData; }
/**
* Retrieves question values from a specified Google Sheet by ID and sheet name.
* @param {string} sheetId - The ID of the Google Sheet.
* @param {string} sheetName - The name of the sheet within the Google Sheet.
* @returns {Array<Array<string>>|null} The question data, or null if an error occurs.
*/
function getQuestionValues(sheetId, sheetName) {
try {
var ss = SpreadsheetApp.openById(sheetId);
var questionSheet = ss.getSheetByName(sheetName);
if (!questionSheet) {
Logger.log("Error: Sheet '" + sheetName + "' not found in spreadsheet ID: " + sheetId);
return null;
}
var returnData = questionSheet.getDataRange().getValues();
if (returnData.length === 0) {
Logger.log("Warning: Sheet '" + sheetName + "' is empty.");
return null;
}
return returnData;
} catch (error) {
Logger.log("Error retrieving data from sheet '" + sheetName + "': " + error);
return null;
}
}
Key Improvements
✅ Trims extra spaces: Prevents errors from accidental spaces in sheet names or titles.
✅ Prevents overwriting empty fields: Avoids blank values being mistakenly added.
✅ Better logging & debugging: Logger.log() messages help track which sheets & questions are processed.
✅ Handles missing/empty sheets gracefully: Instead of crashing, it logs errors and skips the issue.
✅ Flexible for multiple sheets: Works with any number of sheets, as long as 'Config' is correctly set up.