Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to tell if a cell value has passed validation

I am familiar with the Google Apps script DataValidation object. To get and set validation criteria. But how to tell programatically if a cell value is actually valid. So I can see the little red validation fail message in the spreadsheet but can the fact the cell is currently failing validation be picked up thru code?

I have tried to see if there is a cell property that tells you this but there is not. Also I looked for some sort of DataValidation "validate" method - i.e. test a value against validation rules, but nothing there either

Any ideas? Is this possible??

like image 790
kiwichris Avatar asked Dec 30 '14 22:12

kiwichris


People also ask

How do you validate data results?

Data Validation MethodsBe consistent and follow other data management best practices, such as data organization and documentation. Document any data inconsistencies you encounter. Check all datasets for duplicates and errors. Use data validation tools (such as those in Excel and other software) where possible.


2 Answers

I've created a workaround for this issue that works in a very ugly -technically said- and slightly undetermined way.

About the workaround: It works based on the experience that the web browser implementation of catch() function allows to access thrown errors from the Google's JS code parts. In case an invalid input into a cell is rejected by a validation rule then the system will display an error message that is catchable by the user written GAS. In order to make it work first the reject value has to be set on the specified cell then its vale has to be re-entered (modified) then -right after this- calling the getDataValidation() built in function allows the user to catch the necessary error. Only single cells can be tested with this method as setCellValues() ignores any data validation restriction (as of today).

Disadvantages:

  • The validity won't be necessarily re-checked for this function: it calls a cell validation function right after the value is inserted into the cell. Therefore the result of this function might be faulty.
  • The code messes up the history as cells will be changed - in case they are valid.

I've tested it successfully on both Firefox and Chromium.

function getCellValidity(cell) {
  var origValidRule = cell.getDataValidation();
  if (origValidRule == null || ! (cell.getNumRows() == cell.getNumColumns() == 1)) {
    return null;
  }
  var cell_value = cell.getValue();
  if (cell_value === '') return true; // empty cell is always valid
  var is_valid = true;
  var cell_formula = cell.getFormula();
  // Storing and checking if cell validation is set to allow invalid input with a warning or reject it
  var reject_invalid = ! origValidRule.getAllowInvalid();
  // If invalid value is allowed (just warning), then changing validation to reject it
  // IMPORTANT: this will not throw an error!
  if (! reject_invalid) {
    var rejectValidRule = origValidRule.copy().setAllowInvalid(false).build();
    cell.setDataValidation(rejectValidRule);
  }
  // Re-entering value or formula into the cell itself
  var cell_formula = cell.getFormula();
  if (cell_formula !== '') {
    cell.setFormula(cell_formula);
  } else {
    cell.setValue(cell_value);
  }
  try {
    var tempValidRule = cell.getDataValidation();
  } catch(e) {
    // Exception: The data that you entered in cell XY violates the data validation rules set on this cell.
    // where XY is the A1 style address of the cell
    is_valid = false;
  }
  // Restoring original rule
  if (rejectValidRule != null) {
    cell.setDataValidation(origValidRule.copy().setAllowInvalid(true).build());
  }
  return is_valid;
}

I still recommend starring the above Google bug report opened by Jonathon.

like image 159
Geck0 Avatar answered Oct 03 '22 00:10

Geck0


Specific answer to your question, there is no method within Google Apps Script that will return the validity of a Range such as .isValid(). As you state, you could reverse engineer a programatic one using Range.getDataValidations() and then parsing the results of that in order to validate again the values of a Range.getValues() call.

It's a good suggestion. I've added a feature request to the issue tracker -> Add a Star to vote it up.

like image 40
JSDBroughton Avatar answered Oct 03 '22 00:10

JSDBroughton