I have this piece of code which has been working great for me, however, I need a minor alteration to it and don't know how to proceed.
I would like for 'Multiple Use' to be added as another condition, alongside 'Yes' for the onEdit() to work.
function numberToLetter(number){
// converts the column number to a letter
var temp = "";
var letter = "";
while (number > 0){
temp = (number - 1) % 26;
letter = String.fromCharCode(temp + 65) + letter;
number = (number - temp - 1) / 26;
}
return letter;
}
function obtainFirstBlankRow() {
var sheet = SpreadsheetApp.getActive().getSheetByName('Aug2019');
// search for first blank row
var col = sheet.getRange('A:A');
var vals = col.getValues();
var count = 0;
while (vals[count][0] != "") {
count++;
}
return count + 1;
}
function onEdit(e) {
var ss = SpreadsheetApp.getActiveSheet();
if (ss.getName() == 'ProspectiveSites' && e.range.getColumn() == 26) {
if (e.range.getValue() != 'Yes'){
Logger.log('test');
return;
}
var sourceSheet = SpreadsheetApp.getActive().getSheetByName('ProspectiveSites');
var targetSheet = SpreadsheetApp.getActive().getSheetByName('Aug2019');
//Logger.log('O' + e.getRow() + ':O' + e.getRow());
Logger.log(e);
Logger.log(e.range.getValue());
var cell15 = sourceSheet.getRange('O' + e.range.getRow() + ':O' + e.range.getRow()).getValue();
var cell24 = sourceSheet.getRange('X' + e.range.getRow() + ':X' + e.range.getRow()).getValue();
Logger.log(cell15);
Logger.log(cell24);
var row = obtainFirstBlankRow();
targetSheet.getRange(row, 1).setValue(cell15);
targetSheet.getRange(row, 2).setValue(cell24);
}
}
Solution
What stops you from adding another condition for the if statement? Please, take some time to research JS documentation, it will greatly help you in the long run (see useful links after the sample).
Modifications
This modification assumes that you need to exit if value is not equal to "Multiple use" and not equal to "Yes". Also, note that there are a few additional changes made for optimization purposes (I changed all comparison operators to strict as well).
Sample
/**
* onEdit simple trigger;
* #param {Object} event object;
*/
function onEdit(e) {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var actS = ss.getActiveSheet(); //active sheet === source sheet;
//access event object params;
var range = e.range;
var row = range.getRow();
var column = range.getColumn();
var value = range.getValue();
if (actS.getName()==='ProspectiveSites' && column===26) {
if (value!=='Yes'&&value!=='Multiple Use') {
Logger.log('test');
return;
}
var augS = ss.getSheetByName('Aug2019'); //target sheet;
var cell15val = actS.getRange('O'+row+':O'+row).getValue();
var cell24val = actS.getRange('X'+row+':X'+row).getValue();
var rowBlank = obtainFirstBlankRow();
var target = augS.getRange(rowBlank,1,1,2); //idx, first col, 1 row, 2 cols;
target.setValues([[ cell15val , cell24val ]]);
}
}
Useful links
if..else statement reference on MDN;
Comparison operators reference on MDN;
getRange() method reference;
setValues() method reference;
I got spreadsheet including annoying values and struggle to this. Required data is in each cell of column A. Value of a cell is {"p0":70,"u3":71,"s7110":40},t45,{"t78":60,"s3310":15},p37,p36,{"p29":44,"s8110":95},p85,p14,{"s2710":41},u47. Number of such values is about 1000. I have to parse these values. I need strings and objects from such values. I can ignore order of parsed value. I cannot parse manually. So I decided to use script.
I tried to parse using "split".
var sheet = SpreadsheetApp.getActiveSheet();
var values = sheet.getRange("A1:A" + sheet.getLastRow()).getValues();
var result = [];
for (var i = 0; i < values.length; i++)
{
result.push(values[i][0].split(","));
}
I got t45,p37,p36,p85,p14,u47 as string. But "split" also splits all objects. For example, {"p0":70,"u3":71,"s7110":40} is split to {"p0":70, "u3":71, "s7110":40}. Is there way to solve this?
Sample values are this. Each line is in cell A1, A2, A3, A4, A5.
{"p0":70,"u3":71,"s7110":40},t45,{"t78":60,"s3310":15},p37,p36,{"p29":44,"s8110":95},p85,p14,{"s2710":41},u47
s6610,{"t25":70,"u8":43,"p35":86},u85,u74,{"s7710":83},{"p70":70,"u67":84},{"u71":43,"s1210":73},{"u45":84,"s710":15},{"u14":79,"p22":45},p31
u73,u12,{"t51":98,"u57":96},u31,p41,s1110,s6610,p55,{"t57":71,"s7510":83,"u62":17},u73
t50,{"t83":22,"p18":76},{"p47":12,"s8710":18,"u11":35},{"t14":74,"u72":51},{"p74":21,"t77":77},{"u62":84,"s3010":11},p81,u36,p67,{"t79":12,"u2":70,"s6010":98}
{"u54":51,"t31":31},t56,s4110,{"s3110":84,"t25":92,"p80":19},s3210,{"p65":54,"s8510":45},{"t73":78,"s6210":11},{"s2110":98,"p11":16},{"p61":55,"t88":75},p38
Thank you so much for your time. And I'm sorry for my immature question.
B1:
=ARRAYFORMULA(REGEXEXTRACT(A1:A5&",",REGEXREPLACE(REGEXREPLACE(A1:A5&",","{.*?}","($0)"),"([A-Za-z]\d+),","($1),")))
We are enclosing all objects and strings except the commas , with () and then extracting them later.
EDIT:An easier anchor: The , commas to split by are NOT followed by "
=ARRAYFORMULA(SUBSTITUTE(SPLIT(SUBSTITUTE(A1:A5,","&CHAR(34),"😎"),","),"😎",","&CHAR(34)))
=ARRAYFORMULA(split(REGEXREPLACE(A1:A5,"(,)([^"&CHAR(34)&"])","😋$2"),"😋"))
You can use RegExp to replace characters with something unique that can be found without affecting anything else.
function myFunction() {
var L,newArray,thisElement;
var myStrng = '{"p0":70,"u3":71,"s7110":40},t45,{"t78":60,"s3310":15},p37,p36,{"p29":44,"s8110":95},p85,p14,{"s2710":41},u47 \
s6610,{"t25":70,"u8":43,"p35":86},u85,u74,{"s7710":83},{"p70":70,"u67":84},{"u71":43,"s1210":73},{"u45":84,"s710":15},{"u14":79,"p22":45},p31 \
u73,u12,{"t51":98,"u57":96},u31,p41,s1110,s6610,p55,{"t57":71,"s7510":83,"u62":17},u73 \
t50,{"t83":22,"p18":76},{"p47":12,"s8710":18,"u11":35},{"t14":74,"u72":51},{"p74":21,"t77":77},{"u62":84,"s3010":11},p81,u36,p67,{"t79":12,"u2":70,"s6010":98} \
{"u54":51,"t31":31},t56,s4110,{"s3110":84,"t25":92,"p80":19},s3210,{"p65":54,"s8510":45},{"t73":78,"s6210":11},{"s2110":98,"p11":16},{"p61":55,"t88":75},p38';
var re = new RegExp("\},","g");
var parsedObj = myStrng.replace(re,"}zq^");//Replace all }, characters with }zq^
//Logger.log(parsedObj)
parsedObj = parsedObj.replace(/,\{/g,"zq^{");//Replace all ,{ characters with zq^{
//Logger.log(parsedObj)
parsedObj = parsedObj.replace(/\}\{/g,"}zq^{");//Replace all back to back brackets
parsedObj = parsedObj.replace(/\} \{/g,"}zq^{");//Replace all back to back brackets with a space between
parsedObj = parsedObj.split("zq^");//split on zq^
L = parsedObj.length;
newArray = [];
for (var i=0;i<L;i++) {
thisElement = parsedObj[i];
//Logger.log('thisElement: ' + thisElement)
if (thisElement.indexOf("{") !== -1) {
newArray.push(thisElement);
continue;
}
if (thisElement.indexOf(",") !== -1) {
thisElement = thisElement.split(",");
for (var j =0;j<thisElement.length;j++) {
newArray.push(thisElement[j]);
}
continue;
}
if (thisElement.indexOf(" ") !== -1) {
thisElement = thisElement.split(" ");
for (var j =0;j<thisElement.length;j++) {
newArray.push(thisElement[j]);
}
continue;
}
newArray.push(thisElement);
}
L = newArray.length;
for (var i=0;i<L;i++) {
Logger.log(newArray[i])
}
}
I have the following code:
using (CPASEntities ctx = new CPASEntities())
{
IWorksheet ws = wb.Worksheets[0];
ws.Name = "Summary";
var tsm = (from x in ctx.tblTimesheetMasters
where x.TSID == TSID
select new
{
TimesheetID = x.TSID,
Comments = x.TSComments,
Vendor = x.tblVendor.Vendor_Name,
StartDate = x.TSStartDate,
Author = x.TSAuthor,
Approver = x.TSApprover,
Override_Approver = x.TSOverrideApprover,
Status = x.tblTimesheetStatu.TSStatusDesc
}
).ToList();
SpreadsheetGear.IRange range = ws.Cells["A1"];
// I want to copy the entire tsm list to this range, including headings.
}
As the comment states, I want to put that entire list into the ws worksheet starting at A1. I include the code in case it's easier to use a different construct. FWIW, there will be only one entry...TSID is the primary key. I can, of course, use the .FirstorDefault() construct if that is important. I thought it not important.
Your range is only one cell. You need a range big enough to contain all the cells the list would populate.
To populate your worksheet with the list, you could do something like this.
int iRow = 0;
int iCol = 0;
if (tsm.Count() > 0)
{
foreach (var prop in tsm[0].GetType().GetProperties())
{
ws.Cells[iRow, iCol].Value = prop.Name;
iCol++;
}
iRow++;
foreach (var t in tsm)
{
iCol = 0;
foreach (var prop in t.GetType().GetProperties())
{
ws.Cells[iRow, iCol].Value = prop.GetValue(t, null);
iCol++;
}
iRow++;
}
}
If you want a range, you could add this line.
SpreadsheetGear.IRange range = ws.Cells[0, 0, iRow - 1, iCol - 1];