AS3 - sort arraycollection alpha numeric values - actionscript-3

i'm trying to sort an arraycollection that uses letters and numbers
Currently I'm getting "b12,c1,b1,b3,b4,b5,b6,b7,b8,b9,b10,b11,b0,b13,b14,b15" but want "b0,b1,b2,b3,b4,b5,b6,b7,b8,b9,b10,b11,b12,b13,b14,b15,c1"
Please can anyone suggest when're I have gone wrong?
var dataSortField:SortField = new SortField();
dataSortField.name = "order";
dataSortField.numeric = false;
dataSortField.compareFunction = sortAlphaNumeric;
var numericDataSort:Sort = new Sort();
numericDataSort.fields = [dataSortField];
pageArrCol.sort = numericDataSort;
private function sortAlphaNumeric(a:String, b:String):int {
var reA:RegExp = /[^a-zA-Z]/g;
var reN:RegExp = /[^0-9]/g;
var aA:String = a.replace(reA,"");
var bA:String = b.replace(reA,"");
if (aA === bA) {
var aN:int = parseInt(a.replace(reN,""),10);
var bN:int = parseInt(b.replace(reN,""),10);
return aN === bN ? 0 : aN > bN ? 1 : -1;
} else {
return aA > bA ? 1 : -1;
}
}

myArrayCollectionToSort.source.sortOn("order", sortAlphaNumeric);
private function sortAlphaNumeric(a:String, b:String):int {
var reA:RegExp = /[^a-zA-Z]+/g;
var reN:RegExp = /[^0-9]+/g;
var aA:String = a.match(reA)[0];
var bA:String = b.match(reA)[0];
if (aA == bA) {
var aN:int = parseInt(a.match(reN)[0],10);
var bN:int = parseInt(b.match(reN)[0],10);
return aN == bN ? 0 : aN > bN ? 1 : -1;
}
return aA > bA ? 1 : -1;
}
I don't test it but it should works, and array is way faster than an ArrayCollection. (arraycollection.source is an array). If the sorted ArrayCollection is binded you need to dispatch a refresh event if you want the bind to works:
myArrayCollectionToSort.dispatchEvent(new CollectionEvent(CollectionEvent.COLLECTION_CHANGE, false, false, CollectionEventKind.REFRESH));
or
myArrayCollectionToSort.refresh();

Assuming that b12,c1,b1 is your input format
You may have meant, a.match(regex)[0]
var reA:RegExp = /[a-zA-Z]+/g;
var reN:RegExp = /[0-9]+/g;
var aA:String = a.match(reA)[0];
var bA:String = b.match(reA)[0];
if (aA === bA) {
var aN:int = parseInt(a.match(reN)[0],10);
var bN:int = parseInt(b.match(reN)[0],10);
return aN === bN ? 0 : aN > bN ? 1 : -1;
}else {
return aA > bA ? 1 : -1;
}
I have not tested this, but you should not be using replace, use match instead. Also, the regular expression is wrong. You have to revisit the regular expression.

Related

Retrieve input values from dinamically genrated HTMLElement form?

I'm currently on an Angular project (I'm a begineer) and I created a function to create a HTML form depending on the content of a JSON (the form then allows me to push new data in the JSON). It works, displays the form, but I didn't think ahead, and don't know how to retrieve the input values from the user.
createNewLineForm() {
if (this.allowForm) {
let indiceList = 0;
this.formOn = true;
for (let jsonCol of this.columnData) {
if (jsonCol.visible === true && jsonCol.type === "Boolean") {
var content = document.getElementById("formcontent");
var listTitle = document.createElement("header");
listTitle.textContent = jsonCol.name;
content.appendChild(listTitle);
var selectList = document.createElement("select");
selectList.id = "trueFalse";
content.appendChild(selectList);
var option = document.createElement("option");
option.value = "true";
option.text = "true";
selectList.appendChild(option);
var option2 = document.createElement("option");
option2.value = "false";
option2.text = "false";
selectList.appendChild(option2)
}
if (jsonCol.visible === true && jsonCol.type === "String" && jsonCol.dropdownList === null) {
var content = document.getElementById("formcontent");
var inputTitle = document.createElement("header");
inputTitle.textContent = jsonCol.name;
content.appendChild(inputTitle);
var formInput = document.createElement("input");
formInput.type = "text";
formInput.placeholder = jsonCol.name;
formInput.name = "text";
content.appendChild(formInput);
}
if (jsonCol.visible === true && jsonCol.type === "String" && jsonCol.dropdownList != null) {
var content = document.getElementById("formcontent");
var listTitle = document.createElement("header");
listTitle.textContent = jsonCol.name;
content.appendChild(listTitle);
var selectListLong = document.createElement("select");
selectListLong.name ="longList";
indiceList++;
content.appendChild(selectListLong);
for (const options of jsonCol.dropdownList) {
var option = document.createElement("option");
option.value = options;
option.text = options;
selectListLong.appendChild(option);
}
}
}
var submit = document.createElement("input");
submit.type = "submit";
content.appendChild(submit);
}
}
It's then conditionnally called in my HTML window with a simple <div id="formcontent"> </div>
I tried using document.getElementByName('...').value, doesn't seem to work.
Btw, if you have another idea on how to make that form, I'd like hearing it as well, this method seems a bit messy I think.
var content = document.getElementById("formcontent").value;
You can try it by ID

Google Charts - Hide series label too wide

With Google Apps Script I created a stacked bar chart. This is the result:
https://drive.google.com/file/d/1DZ2ZtSu2A81OAMc9ds9A4y-bS0l_oftL/view?usp=sharing
I would like to hide the labels on the bars when they are too wide compared to the available space. Following the instructions I found at this address https://developers.google.com/chart/interactive/docs/reference#DataView_setColumns I tried to use a custom function instead of "stringify" in the "annotationObj" object ( see the code) to create a label of zero length, but my function is not recognized when I try to create the chart (error message: Unknown function "getValueAt").
This is my code:
function CHARTS_002() { //
var ABCarray = ['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','AA','AB','AC','AD','AE','AF','AG','AH','AI','AJ','AK','AL','AM','AN','AO','AP','AQ','AR','AS','AT','AU','AV','AW','AX','AY','AZ','BA','BB','BC','BD','BE','BF','BG','BH','BI','BJ','BK','BL','BM','BN','BO','BP','BQ','BR','BS','BT','BU','BV','BW','BX','BY','BZ','CA','CB','CC','CD','CE','CF','CG','CH','CI','CJ','CK','CL','CM','CN','CO','CP','CQ','CR','CS','CT','CU','CV','CW','CX','CY','CZ'];
var ssId = '1KA2BnUsC-Lp64UhxjtN5Gtth2dOiHp3-pRwIQjAYOLI';
var shName = 'TopGrossingFilms';
var aScale = ["Poco d'accordo","Né d’accordo né in disaccordo","Abbastanza d'accordo","Totalmente d'accordo","Media"];
var aRange = [['B',2],['N',12]];
var sheet = SpreadsheetApp.openById(ssId).getSheetByName(shName);
var row = aRange[0][1];
var column = ABCarray.indexOf(aRange[0][0]) + 1;
var numRows = aRange[1][1] - aRange[0][1];
var numColumns = ABCarray.indexOf(aRange[1][0]) - ABCarray.indexOf(aRange[0][0]) + 1;
var sheetV = sheet.getRange(aRange[0][1], ABCarray.indexOf(aRange[0][0]) + 1, numRows, numColumns).getValues();
var sheetT1D = sheetV[0];
var aData = [];
for (var r in sheetV) {
aData.push(sheetV[r])
}
for (var r in aData) {
for (var c in aData[r]) {
if (!isNaN(aData[r][c])) {
aData[r][c] = round(aData[r][c],2);
if (aData[0][c] == 'Media') {
aData[r][c] = 13;
}
}
}
}
var data = Charts.newDataTable();
var annotationObj = { calc: "stringify",
//calc: "getValueAt",
//calc: "function(data, row) { var ret = data[row][§col§]; if (ret < 7) {return '';} else {return JSON.stringify(ret)} }",
sourceColumn: -1,
type: "string",
role: "annotation"
}
var aAnnotation = [];
for (var r in aData) {
if (r < 1) { continue; }
if (r == 1) {
for (var c in aData[r]) {
aAnnotation.push(c);
if (isNaN(aData[r][c])) {
data.addColumn(Charts.ColumnType.STRING, aData[0][c]);
} else {
data.addColumn(Charts.ColumnType.NUMBER, aData[0][c]);
if (aScale.indexOf(aData[0][c]) != -1) {
var myObj = JSON.parse(JSON.stringify(annotationObj));
var myCol = Number(c);
if (aData[0][c] == 'Media') {
myCol = Number(c) + 1;
}
myObj.sourceColumn = myCol;
myObj.calc = myObj.calc.replace("§col§",myCol)
aAnnotation.push(myObj);
}
}
}
}
data.addRow(aData[r]);
}
var dataViewDefinition = Charts.newDataViewDefinition().setColumns(aAnnotation);
var aTicks = [0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100];
var chartBuilder = Charts.newBarChart()
.setDimensions(1200, 700)
.setOption("hAxis", { ticks: aTicks})
.setOption('legend',{ position:'top', maxLines:3 })
.setOption('chartArea',{ left:650 })
.setOption('series',{
6: {type:'line', color:'00FF00', lineWidth:3, visibleInLegend: false}
})
.setDataTable(data)
.setDataViewDefinition(dataViewDefinition)
.setOption('bar', { groupWidth: "80%" })
.setStacked()
.setColors(['#C10000','#F1C12A','#BFBFBF','#0070C1','#244062','00FF00']);
var chart = chartBuilder.build();
var chartImage = chart.getAs('image/png').copyBlob();
DriveApp.createFile(chartImage).setName('NewBarChart.png');
}
function getValueAt(column, dataTable, row) {
var value = dataTable(row, column);
var ret = '';
if (value > 7) { ret = value.toString()}
return ret;
}
function round(value, exp) {
var funcName = 'round';
if (typeof exp === 'undefined' || +exp === 0)
return Math.round(value);
value = +value;
exp = +exp;
if (isNaN(value) || !(typeof exp === 'number' && exp % 1 === 0))
return NaN;
// Shift
value = value.toString().split('e');
value = Math.round(+(value[0] + 'e' + (value[1] ? (+value[1] + exp) : exp)));
// Shift back
value = value.toString().split('e');
return +(value[0] + 'e' + (value[1] ? (+value[1] - exp) : -exp));
}
The chart that is produced can be seen in this public folder: https://drive.google.com/file/d/1DZ2ZtSu2A81OAMc9ds9A4y-bS0l_oftL/view?usp=sharing
Does anyone know how to get the result I would like to get?
Thanks in advance.

"Invalid Argument" error with addLabel(label) method

For a while now, I've been trying to create an autolabeler for Gmail in Google Apps Script. This script parses through an email's body and looks for a line with the form "#DL:", extracts the text after that (which is a date), runs this string through a standardizer I have coded, calculates the date difference between that date and now, and if it's urgent, assigns a color to that. It gets all that information and labels that email. Here is the code I use:
var filters = [{
match: /[\n\r][ \t]*#DL:[ \t]*([^\n\r]*)/,
archive: false
}, ];
var from = [];
function labeler() {
var batchSize = 10;
var labelCache = {};
var query = "in:anywhere";
var threads = GmailApp.search(query, 0, batchSize);
GmailApp.getMessagesForThreads(threads);
var findOrCreateLabel = function(name) {
if (labelCache[name] === undefined) {
labelCache[name] = GmailApp.getUserLabelByName(name) || createLabelByGmailApi(name);
}
//GmailApp.createLabel(name);
//createLabelByGmailApi(name);
return labelCache[name];
}
var applyLabel = function(name, thread) {
var label = null;
var labelName = "";
name.split('&').forEach(function(labelPart, i) {
labelName = labelName + (i === 0 ? "" : "&") + labelPart.trim();
label = findOrCreateLabel(labelName);
});
thread.addLabel(label);
}
threads.forEach(function(thread) {
var messages = thread.getMessages();
if (messages == null) return;
var message = messages[messages.length - 1];
var body = message.getRawContent();
var archive = true;
filters.forEach(function(filter) {
var matches = filter.match.exec(body);
if (matches !== null) {
var label = filter.name || matches[1];
var data = datestd(label);
var cor = datecalc(data);
label = "Datas/" + data;
if (label !== undefined) applyLabel(label, thread);
if (filter.archive !== undefined && !filter.archive) archive = false;
}
});
if (archive) thread.moveToArchive();
});
}
function createLabelByGmailApi(name, color) {
var label = GmailApp.getUserLabelByName(name);
if (label) return label;
var textColor = "#ffffff";
if (color == 'red') {
var backgroundColor = "#ac2b16";
} else if (color == 'yellow') {
var backgroundColor = "#fad165";
} else if (color == 'green') {
var backgroundColor = "#076239";
} else {
var backgroundColor = "#41236d";
}
var userId = "me";
var resource = Gmail.newLabel();
resource.labelListVisibility = "labelShow";
resource.messageListVisibility = "show";
resource.name = name;
var labelColor = Gmail.newLabelColor();
labelColor.textColor = textColor;
labelColor.backgroundColor = backgroundColor;
resource.color = labelColor;
Gmail.Users.Labels.create(resource, userId);
return GmailApp.getUserLabelByName(name);
}
function datecalc(stringdata) {
var len = stringdata.length
var min = stringdata.slice(len - 2, len);
var hora = stringdata.slice(len - 5, len - 3);
var mes = stringdata.slice(len - 9, len - 7);
var dia = stringdata.slice(len - 12, len - 10);
min = Number(min);
hora = Number(hora);
mes = Number(mes);
dia = Number(dia);
var data = new Date(2019, mes - 1, dia, hora, min);
var data2 = Date.now();
var diff = data - data2;
diff = diff / 86400000
var color;
if (diff <= 1.5) {
color = 'red'
} else if (diff > 1.5 && diff <= 4) {
color = 'yellow'
} else {
color = 'green'
}
return color;
}
function mesnum(mon) {
var m = {
'jan': '01',
'fev': '02',
'mar': '03',
'abr': '04',
'mai': '05',
'jun': '06',
'jul': '07',
'ago': '08',
'set': '09',
'out': '10',
'nov': '11',
'dez': '12'
};
var s = mon.slice(0, 3)
var idc = String(m[s]);
if (idc.length < 2) {
idc = "0" + idc;
}
return idc;
}
function datestd(date) {
var ano = "2019";
var whitelistdias = ["terça-feira", "quarta-feira",
"quinta-feira", "sexta-feira", "sábado", "domingo",
"segunda", "terça", "quarta", "quinta", "sexta", "sabado",
"terca"
];
var whitelistmes = ["janeiro", "fevereiro", "março", "abril", "maio", "junho",
"julho", "agosto", "setembro", "outubro", "novembro",
"dezembro", "jan", "fev", "mar", "abr", "mai", "jun",
"jul", "ago", "set", "out", "nov", "dez"
];
var whitelistchar = ["/", "-", "."];
var idk = date.toLowerCase();
idk = idk.replace(/,/g, " ,");
idk = idk.split(" ");
var v;
var pos;
var dia;
var hora;
var mes;
var searchd;
var posfinal;
if (whitelistmes.some(function(v) {
return idk.indexOf(v) !== -1;
}) == true) {
idk = String(idk);
whitelistmes.forEach(function(strs) {
return idk.replace(strs, "");
});
whitelistdias.forEach(function(strq) {
return idk.replace(strq, "");
});
idk = String(idk);
idk = idk.replace("[", "");
idk = idk.replace(".", ":");
idk = idk.replace("]", "");
idk = idk.replace("de", "");
idk = idk.replace(" ", "");
idk = idk.replace("'", "");
idk = idk.replace("as", ",");
idk = idk.replace("at", ",");
idk = idk.replace("of", ",");
idk = idk.replace("às", ",");
idk = idk.replace("h", "");
idk = idk.replace(ano, "");
pos = idk.indexOf(",");
dia = idk.slice(0, pos);
idk = String(idk);
hora = idk.slice(idk.lastIndexOf(",") + 1, idk.length);
idk = idk.split(",");
mes = idk.filter(function(n) {
return whitelistmes.indexOf(n) !== -1;
});
mes = String(mes);
return dia + "/" + mesnum(mes) + ", " + hora;
} else {
idk = String(idk);
if (idk.includes("/") || idk.includes("-")) {
whitelistmes.forEach(function(strs) {
return idk.replace(strs, "");
});
whitelistdias.forEach(function(strq) {
return idk.replace(strq, "");
});
}
idk = String(idk);
idk = idk.replace(".", ":");
idk = idk.replace("[", "");
idk = idk.replace("]", "");
idk = idk.replace("de", "");
idk = idk.replace(/ /g, "");
idk = idk.replace("'", "");
idk = idk.replace("as", ",");
idk = idk.replace("às", ",");
idk = idk.replace(ano, "");
var hmm = new Array();
idk = idk.split('');
hmm = idk.reduce(function(matches, character, index) {
if (whitelistchar.includes(character)) hmm.push(index);
return hmm;
}, []);
hmm = String(hmm);
hmm = hmm.replace("[", "");
hmm = hmm.replace("]", "");
hmm = hmm.replace(" ", "");
var pos1 = hmm.indexOf(",");
if (pos1 !== -1) {
var prim = hmm.slice(0, pos1);
prim = Number(prim);
var seg = hmm.slice(pos1 + 1, hmm.length);
seg = Number(seg);
dia = idk.slice(0, prim);
mes = idk.slice(prim + 1, seg);
hora = idk.slice(seg + 1, idk.length);
} else {
hmm = Number(hmm);
pos1 = idk.indexOf(",");
dia = idk.slice(0, hmm);
mes = idk.slice(hmm + 1, pos1);
hora = idk.slice(pos1 + 1, idk.length);
}
hora = String(hora);
searchd = hora.match(/\d/);
posfinal = hora.indexOf(searchd);
hora = hora.slice(posfinal, hora.length);
idk = String(idk);
idk = idk.replace(/,/g, "");
dia = String(dia);
mes = String(mes);
hora = String(hora);
dia = dia.replace(/,/g, "");
mes = mes.replace(/,/g, "");
hora = hora.replace(/,/g, "");
hora = hora.replace(/h/g, "");
return dia + "/" + mes + ", " + hora;
}
}
To give some context to what's happening:
The labeler function gets the string from the email, sends it to the datestd function to get standardized, and that output is the name of the label. That output is also used to calculate the date difference between that date and now, through the function datecalc, which outputs a color. This color will be used by the createLabelByGmailApi function to create a label with that name and color. After this, the labeler function applies that label to the email in question.
There are 2 problems I am trying to fix, to no avail:
1. Invalid Argument Error
When running the code above, I get an "Invalid Argument" error in the thread.addLabel(label); line (the argument is label), and I don't know why.
2. Can't seem to fetch the color for the createLabelByGmailApi function
Due to the way the code is structured, I can't seem to fetch the color for the function, since this color depends on the date, which depends on the parsing of the email body, which happens later in the function. I can't seem to find a way to rearrange this so I am able to provide a color for the function, would be great if you could help.
I know this is a handful, and thanks so much for reading this, your help would be much appreciated.
How about this modification?
It seems that the reason of your issue is the crated label is not reflected soon when Gmail.Users.Labels.create() is run. By this, label became null. In order to remove this issue, I added the label using Gmail.Users.Threads.modify() when the label was created with Gmail.Users.Labels.create(). Please modify as follows.
Modified script:
Please modify applyLabel() of labeler() as follows.
From:
var applyLabel = function(name, thread) {
var label = null;
var labelName = "";
name.split('&').forEach(function(labelPart, i) {
labelName = labelName + (i === 0 ? "" : "&") + labelPart.trim();
label = findOrCreateLabel(labelName);
});
thread.addLabel(label);
}
To:
var applyLabel = function(name, thread) {
var label = null;
var labelName = "";
name.split('&').forEach(function(labelPart, i) {
labelName = labelName + (i === 0 ? "" : "&") + labelPart.trim();
label = findOrCreateLabel(labelName);
});
if (typeof label == "string") {
Gmail.Users.Threads.modify({addLabelIds: [label]}, "me", thread.getId());
} else {
thread.addLabel(label);
}
}
And, please modify createLabelByGmailApi() as follows.
From:
Gmail.Users.Labels.create(resource, userId);
return GmailApp.getUserLabelByName(name);
To:
return Gmail.Users.Labels.create(resource, userId).id;
Note:
At labelCache[name] = GmailApp.getUserLabelByName(name) || createLabelByGmailApi(name);, when createLabelByGmailApi(name) is called, name is used as the argument. But at the function of createLabelByGmailApi(name, color), name and color are used as the arguments. I think that in the current situation, #41236d is used as the default value. Please confirm this.
When I see the function of datestd(), I noticed that includes() is used. In the current stage, it cannot be used for Google Apps Script. So includes() is declared at elsewhere?
If I misunderstood your situation and this was not the direction you want, I apologize.

How to clear formatting on a selection in TLF?

I'm trying to remove the formatting of the selection and what I have so far only removes the formatting on a selection when the selection is inside a paragraph. If the selection extends to another paragraph the formatting is not removed.
Here is what I have so far:
var currentFormat:TextLayoutFormat;
var currentParagraphFormat:TextLayoutFormat;
var containerFormat:TextLayoutFormat;
var selectionStart:int;
var selectionEnd:int;
var operationState:SelectionState;
var editManager:IEditManager;
if (richEditableText.textFlow && richEditableText.textFlow.interactionManager is IEditManager) {
editManager = IEditManager(richEditableText.textFlow.interactionManager);
selectionStart = Math.min(richEditableText.selectionActivePosition, richEditableText.selectionAnchorPosition);
selectionEnd = Math.max(richEditableText.selectionActivePosition, richEditableText.selectionAnchorPosition);
if (operationState == null) {
operationState = new SelectionState(richEditableText.textFlow, selectionStart, selectionEnd);
}
currentFormat = editManager.getCommonCharacterFormat(operationState);
currentParagraphFormat = editManager.getCommonParagraphFormat(operationState);
containerFormat = editManager.getCommonContainerFormat(operationState);
editManager.clearFormat(currentFormat, currentParagraphFormat, containerFormat);
}
It seems that SelectionManager.getCommonCharacterFormat() doesn't quite do what I was thinking it was doing. I need to get the format of the characters that are selected and that function doesn't seem to do that.
If I get a ElementRange and then loop through it I can create a TextLayoutFormat that contains the formats on all the leaves in the element range.
var currentFormat:TextLayoutFormat;
var currentParagraphFormat:TextLayoutFormat;
var containerFormat:TextLayoutFormat;
var selectionStart:int;
var selectionEnd:int;
var operationState:SelectionState;
var editManager:IEditManager;
if (richEditableText.textFlow && richEditableText.textFlow.interactionManager is IEditManager) {
editManager = IEditManager(richEditableText.textFlow.interactionManager);
selectionStart = Math.min(richEditableText.selectionActivePosition, richEditableText.selectionAnchorPosition);
selectionEnd = Math.max(richEditableText.selectionActivePosition, richEditableText.selectionAnchorPosition);
if (operationState == null) {
operationState = new SelectionState(richEditableText.textFlow, selectionStart, selectionEnd);
}
// following lines were change
elementRange = ElementRange.createElementRange(richEditableText.textFlow, selectionStart, selectionEnd);
currentFormat = getElementRangeFormat(elementRange);
editManager.clearFormat(currentFormat, currentParagraphFormat, containerFormat);
}
// method to get format of the selected range
public static function getElementRangeFormat(elementRange:ElementRange):TextLayoutFormat {
var leaf:FlowLeafElement = elementRange.firstLeaf;
var attr:TextLayoutFormat = new TextLayoutFormat(leaf.computedFormat);
for (;;)
{
if (leaf == elementRange.lastLeaf)
break;
leaf = leaf.getNextLeaf();
attr.concatInheritOnly(leaf.computedFormat);
}
return Property.extractInCategory(TextLayoutFormat, TextLayoutFormat.description, attr, Category.CHARACTER, false) as TextLayoutFormat;
}

How can I check if a range is in a named range?

I need to check if the edited cell in an onEdit function is part of a named range. Something like this in Excel VBA:
If Not Intersect(Edited Cell, Range("NamedRange")) Is Nothing Then ...
Any ideas? Thanks in advance!
Something fairly rudimentary, at least, will give you ideas:
function _check_rows(range, namedRange) {
var _result = false,
_range_row_begin,
_range_row_end,
_namedRange_row_begin,
_namedRange_row_end;
if (range && namedRange) {
_range_row_begin = range.getRow(),
_range_row_end = range.getLastRow(),
_namedRange_row_begin = namedRange.getRow(),
_namedRange_row_end = namedRange.getLastRow(),
_result = _range_row_begin >= _namedRange_row_begin && _range_row_end <= _namedRange_row_end;
}
return _result;
}
function _check_columns(range, namedRange) {
var _result = false,
_range_column_begin,
_range_column_end,
_namedRange_column_begin,
_namedRange_column_end;
if (range && namedRange) {
_range_column_begin = range.getColumn(),
_range_column_end = range.getLastColumn(),
_namedRange_column_begin = namedRange.getColumn(),
_namedRange_column_end = namedRange.getLastColumn(),
_result = _range_column_begin >= _namedRange_column_begin && _range_column_end <= _namedRange_column_end;
}
return _result;
}
function _setNamedRange(name) {
var _ss = SpreadsheetApp.getActiveSpreadsheet();
_ss.setNamedRange(name, _ss.getRange('Sheet 1!C3:D6'));
}
function Intersect(range, namedRange) {
var _result = false,
_ss,
_sheet,
_range,
_namedRange;
if (range && namedRange) {
_ss = SpreadsheetApp.getActiveSpreadsheet(),
_sheet = _ss.getActiveSheet(),
_namedRange = _ss.getRangeByName([_sheet.getName(), '!', namedRange].join('')),
_range = _sheet.getRange(range),
_result = _check_rows(_range, _namedRange) && _check_columns(_range, _namedRange);
}
return _result;
}
function test_Intersect() {
var _currentCell = 'C4',
_namedRange = 'NamedRange'; // NamedRange = 'Sheet 1!C3:D6';
_setNamedRange(_namedRange);
if (!Intersect(_currentCell, _namedRange))
Logger.log('TRUE');
else
Logger.log('FALSE');
}
This function will return the indices of a cell in a named range or otherwise return -1s as the indices. Notice that it returns an array with two values representing the row and column indices in the named range.
const indexOfCellInNamedRange = (cell, range_name) => {
const namedRange = SpreadsheetApp.getActiveSpreadsheet().getRangeByName(range_name);
if(cell.getSheet().getName() !== namedRange.getSheet().getName()) return [-1, -1]
const start_row = namedRange.getRow();
const end_row = start_row + namedRange.getNumRows() - 1;
const start_col = namedRange.getColumn();
const end_col = start_col + namedRange.getNumColumns() - 1;
const row_index = Math.max( cell.getRow() - start_row, -1);
const col_index = Math.max(cell.getColumn() - start_col, -1);
if(row_index > end_row)return [-1, -1]
if(col_index > end_col)return [-1, -1]
return [row_index, col_index]
}