Automatic copy a row when a certain value is given - google-sheets

I need to automatically copy a row when a certain value is given.
With Moveto it works, but with copyto it does not.
Can someone help me? tx
function myFunction3() {
var sheetNameToWatch = "Planning";
var columnNumberToWatch = 12;
var valueToWatch = "Running";
var sheetNameCopyTheRowTo = "Facturatie";
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = SpreadsheetApp.getActiveSheet();
var rangeToCopy = sheet.getActiveCell();
if (sheet.getName() == sheetNameToWatch
&& range.getColumn() == columnNumberToWatch
&& range.getValue() == valueToWatch)
{
var targetSheet = ss.getSheetByName(sheetNameToMoveTheRowTo);
var targetRange = targetSheet.getRange(targetSheet.getLastRow() + 1, 1);
sheet.getRange(range.getRow(),1,1,sheet.getLastColumn()).copyTo(targetRange);
}
}

Related

Formating Copied to new Sheet Google Scripts (Google Sheets)

Trying to get the formatting copied over from the front sheet, but it takes the forumla which is a import range, is there any way to achieve this without showing the ref error.
function BrandSheets() {
var ss = SpreadsheetApp.getActive();
var Frontsheet = ss.getSheets()[0];
var Header_range = Frontsheet.getRange(1,1,1,13);
var CurrentBrand = Frontsheet.getRange(2,3).getValue();
var CurrentTopBrand = 2;
var CurrentBottomBrand = 2;
var CheckBrand = CurrentBrand;
Frontsheet.getRange(1,3).activate();
Frontsheet.getCurrentCell().getNextDataCell(SpreadsheetApp.Direction.DOWN).activate();
var FLastCell = Frontsheet.getActiveCell();
var FLastRow = FLastCell.getRow();
for(var i = 2;i<=FLastRow+1;i++){
var CheckBrand = Frontsheet.getRange(i,3).getValue();
if (CheckBrand == CurrentBrand){
var CurrentBottomBrand = i
}
else{
var CurrentBottomBrand = i
var BrandTable = Frontsheet.getRange(CurrentTopBrand,1,CurrentBottomBrand-CurrentTopBrand,13);
var NewSheet = SpreadsheetApp.getActiveSpreadsheet().insertSheet(CurrentBrand);
var NewHeader_range = NewSheet.getRange(1,1,1,13);
var NewBrandTable = NewSheet.getRange(2,1,CurrentBottomBrand-CurrentTopBrand,13);
Header_range.copyTo(NewHeader_range,{contentsOnly:true});
BrandTable.copyTo(NewBrandTable);
var CurrentTopBrand = i;
var CurrentBrand = Frontsheet.getRange(i,3).getValue();
SpreadsheetApp.getActiveSpreadsheet().getSheets().forEach( sheet => sheet.setTabColor("grey"));
}
}
}
I tried Header_range.copyTo(NewHeader_range,{contentsOnly:true,formatOnly:true});
But this is where the bug of ref comes up. Issue Ref
Many thanks,

The resulting array was too large in Google Sheets

I'm using the following formula, and I'm getting: The resulting array was too large.
Any ideas? I have over 20k rows.
UPDATE: If I can accomplish this formula with a script, that would be great. Thanks!
=UNIQUE(ARRAYFORMULA({IMPORTRANGE(Links!B2,"uno!A:AF");IMPORTRANGE(Links!B3,"dos!A:AF");IMPORTRANGE(Links!B4,"tres!A:AF");IMPORTRANGE(Links!B5,"cuatro!A:AF");IMPORTRANGE(Links!B6,"cinco!A:AF")}))
Try by script this way
function test() {
var dest = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet()
var ss = SpreadsheetApp.openById('id2')
var sh = ss.getSheetByName('uno')
var values = sh.getRange('A1:AF'+sh.getLastRow()).getValues()
dest.getRange(dest.getLastRow()+1,1,values.length,values[0].length).setValues(values)
SpreadsheetApp.flush();
var ss = SpreadsheetApp.openById('id2')
var sh = ss.getSheetByName('dos')
var values = sh.getRange('A1:AF'+sh.getLastRow()).getValues()
dest.getRange(dest.getLastRow()+1,1,values.length,values[0].length).setValues(values)
SpreadsheetApp.flush();
var ss = SpreadsheetApp.openById('id3')
var sh = ss.getSheetByName('tres')
var values = sh.getRange('A1:AF'+sh.getLastRow()).getValues()
dest.getRange(dest.getLastRow()+1,1,values.length,values[0].length).setValues(values)
SpreadsheetApp.flush();
var ss = SpreadsheetApp.openById('id4')
var sh = ss.getSheetByName('cuatro')
var values = sh.getRange('A1:AF'+sh.getLastRow()).getValues()
dest.getRange(dest.getLastRow()+1,1,values.length,values[0].length).setValues(values)
SpreadsheetApp.flush();
var ss = SpreadsheetApp.openById('id5')
var sh = ss.getSheetByName('cinco')
var values = sh.getRange('A1:AF'+sh.getLastRow()).getValues()
dest.getRange(dest.getLastRow()+1,1,values.length,values[0].length).setValues(values)
SpreadsheetApp.flush();
};

Google Sheets Auto Time Stamp

My script quit working for google sheets. I can't see why line 7 is hanging up.
Here is the script
function onEdit(event)
{
var timezone = "GMT-7";
var timestamp_format = "MM-dd-yyyy HH:mm:ss";
var updateColName = "Narrative";
var timeStampColName = "Time Stamp";
var sheet = event.source.getSheetByName('Narrative');
var actRng = event.source.getActiveRange();
var editColumn = actRng.getColumn();
var index = actRng.getRowIndex();
var headers = sheet.getRange(2, 2, 2, sheet.getLastColumn()).getValues();
var dateCol = headers[0].indexOf(timeStampColName);
var updateCol = headers[0].indexOf(updateColName); updateCol = updateCol+1;
if (dateCol > -1 && index > 1 && editColumn == updateCol) {
var cell = sheet.getRange(index, dateCol + 1);
var date = Utilities.formatDate(new Date(), timezone, timestamp_format);
cell.setValue(date);
}
}
Any help would be appreciated!
Has the name of the sheet changed?
var sheet = event.source.getSheetByName('Narrative');

Array empty when it should clearly contain elements

I keep getting a fatal error: Index out of range error. My array should clearly contain elements from the images below but it is empty. Been Trying to debug it for hours, I am not too sure what's causing. Please see the images and code below.
var topTest = [t2, t4, t8, t7, t2, t5, t8, t6 ]
for (index, point) in topTest.enumerate() {
spritesPath.append(point)
if index < topTest.count - 1 {
var previousArrayIndex = (index - 1)%topTest.count
if previousArrayIndex == -1 {
previousArrayIndex += topTest.count
}
var nextArrayIndex = (index + 1)%topTest.count
var firstIndex = topPositions.indexOf(point)
var secondIndex = topPositions.indexOf(topTest[nextArrayIndex])
var firstArray = top[firstIndex!]
var secondArray = top[secondIndex!]
var middleIndex1 = 0
var middleArray1 = [CGPoint]()
var middleRandomArrayLength1 : UInt32 = 0
var middleRandomPointIndex1 = 0
var middleIndex2 = 0
var middleArray2 = [CGPoint]()
var middleRandomArrayLength2 : UInt32 = 0
var middleRandomPointIndex2 = 0
if point.x > topTest[nextArrayIndex].x {
if point.x > topTest[previousArrayIndex].x {
let rightPositionsX = rightPositions.map({ $0.x })
middleArray1 = firstArray.filter({rightPositionsX.contains($0.x)})
middleRandomArrayLength1 = UInt32(middleArray1.count)
middleRandomPointIndex1 = Int(arc4random_uniform(middleRandomArrayLength1))
spritesPath.append(middleArray1[middleRandomPointIndex1])
middleIndex1 = rightPositions.indexOf(middleArray1[middleRandomPointIndex1])!
middleArray1 = right[middleIndex1]
let middleArray1X = middleArray1.map({ $0.x })
var midArray2 = secondArray.filter({middleArray1X.contains($0.x)})
midArray2 = midArray2.filter({element in point.x > element.x && topTest[nextArrayIndex].x < element.x })
middleRandomArrayLength2 = UInt32(midArray2.count)
middleRandomPointIndex2 = Int(arc4random_uniform(middleRandomArrayLength2))
spritesPath.append(middleArray2[middleRandomPointIndex2])
}
else{
let secondArrayX = secondArray.map({ $0.x })
middleArray1 = firstArray.filter({secondArrayX.contains($0.x)})
middleArray1 = middleArray1.filter({element in point.x > element.x && topTest[nextArrayIndex].x < element.x })
middleRandomArrayLength1 = UInt32(middleArray1.count)
middleRandomPointIndex1 = Int(arc4random_uniform(middleRandomArrayLength1))
spritesPath.append(middleArray1[middleRandomPointIndex1])
}
}
else
{
if point.x < topTest[previousArrayIndex].x {
let leftPositionsX = leftPositions.map({ $0.x })
middleArray1 = firstArray.filter({leftPositionsX.contains($0.x)})
middleRandomArrayLength1 = UInt32(middleArray1.count)
middleRandomPointIndex1 = Int(arc4random_uniform(middleRandomArrayLength1))
spritesPath.append(middleArray1[middleRandomPointIndex1])
middleIndex1 = leftPositions.indexOf(middleArray1[middleRandomPointIndex1])!
middleArray1 = left[middleIndex1]
let middleArray1X = middleArray1.map({ $0.x })
var midArray2 = secondArray.filter({middleArray1X.contains($0.x)})
midArray2 = midArray2.filter({element in point.x < element.x && topTest[nextArrayIndex].x > element.x })
middleRandomArrayLength2 = UInt32(midArray2.count)
middleRandomPointIndex2 = Int(arc4random_uniform(middleRandomArrayLength2))
spritesPath.append(midArray2[middleRandomPointIndex2])
}
else {
let secondArrayX = secondArray.map({ $0.x })
middleArray1 = firstArray.filter({secondArrayX.contains($0.x)})
middleArray1 = middleArray1.filter({element in point.x < element.x && topTest[nextArrayIndex].x > element.x })
middleRandomArrayLength1 = UInt32(middleArray1.count)
middleRandomPointIndex1 = Int(arc4random_uniform(middleRandomArrayLength1))
spritesPath.append(middleArray1[middleRandomPointIndex1])
}
}
}
}
The images below show that secondArray and middleArray contain similar elements and should not be empty
I think I can see an issue. The line that's crashing is:
spritesPath.append(middleArray2[middleRandomPointIndex2]) right?
So my theory is that if middleArray2 is empty then the index returned by arc4random_uniform is zero. But the array doesn't have a zeroeth element.
If so, check for this condition before getting the array element. Might be a good time to factor the random index code out into its own function, you're using it quite a bit and it would simplify your design.
Maybe:
func randomElement(fromArray array:[T]) -> T? {
let upperBound = UInt32(array.count)
guard upperBound > 0 else { return nil }
let index = Int(arc4random_uniform(upperBound))
return array[index]
}
let a = randomElement(fromArray: [1, 2, 3, 4, 5, 6, 7]) // 4
let b = randomElement(fromArray: ["red", "green", "blue"]) // "red"
let c = randomElement(fromArray: [Double]()) // nil
This function returns an optional because the array may not have any elements to return!

SWIFT : Basic Loops and Arrays

Can I put this in a loop instead of having to manually code it in for each chapter?
var chp1 = Array(Chapters[0].componentsSeparatedByString("\n"))
var chp2 = Array(Chapters[1].componentsSeparatedByString("\n"))
var chp3 = Array(Chapters[2].componentsSeparatedByString("\n"))
var chp4 = Array(Chapters[3].componentsSeparatedByString("\n"))
var chp5 = Array(Chapters[4].componentsSeparatedByString("\n"))
var chp6 = Array(Chapters[5].componentsSeparatedByString("\n"))
var chp7 = Array(Chapters[6].componentsSeparatedByString("\n"))
var chp8 = Array(Chapters[7].componentsSeparatedByString("\n"))
Yes you can use
var chp = []
for chapter in Chapters
{
chp.append(chapter.componentsSeparatedByString("\n")))
}
now you can access to the chapters like
chp[0]
chp[1]
chp[2]
Also you don't need to cast return value to Array.
for range in 0...8 {
var chp = Chapters[range]
let result = chp.componentsSeparatedByString("\n"))
}
Or
for (_, chapter) in Chapters.enumerate() {
let result = chapter.componentsSeparatedByString("\n"))
}

Resources