Reputation: 31
I am trying to build a custom function using an app script that can automatically copy formula to respective rows or columns.
Closest I could find is "Onedit" but it is not provided with a function like an array formula which does the same job for arrays. On edit copies any formula I put in the sheet to all rows... What if I want to copy that formula in specific ranges only? Cant it be done through a custom function?
A sample table is provided below. I need a formula that can copy formula in all rows below automatically using a custom function.
formula i use in cell above that gives 366,335 as as below. It super complex so do not support array formula. i expect formula to change cell references as it is copied to different cells.
=if(sumifs(indirect(Address(match($P$55,$P$1:$P$55,0)+1,match($B$6,$A$55:$AB$55,0))&":"&LEFT(Address(match($P$55,$P$1:$P$55,0)+1,match($B$6,$A$55:$AB$55,0)),2)),indirect(Address(match($P$55,$P$1:$P$55,0)+1,match($B$8,$A$55:$H$55,0),4)&":"&LEFT(Address(match($P$55,$P$1:$P$55,0)+1,match($B$8,$A$55:$H$55,0),4),1)),$B14,indirect(Address(match($P$55,$P$1:$P$55,0)+1,match($B$9,$A$55:$H$55,0),4)&":"&LEFT(Address(match($P$55,$P$1:$P$55,0)+1,match($B$9,$A$55:$H$55,0),4),1)),C$13,$B$56:$B,">"&$B$7,$B$56:$B,"="&$C$7)=0,"",sumifs(indirect(Address(match($P$55,$P$1:$P$55,0)+1,match($B$6,$A$55:$AB$55,0))&":"&LEFT(Address(match($P$55,$P$1:$P$55,0)+1,match($B$6,$A$55:$AB$55,0)),2)),indirect(Address(match($P$55,$P$1:$P$55,0)+1,match($B$8,$A$55:$H$55,0),4)&":"&LEFT(Address(match($P$55,$P$1:$P$55,0)+1,match($B$8,$A$55:$H$55,0),4),1)),$B14,indirect(Address(match($P$55,$P$1:$P$55,0)+1,match($B$9,$A$55:$H$55,0),4)&":"&LEFT(Address(match($P$55,$P$1:$P$55,0)+1,match($B$9,$A$55:$H$55,0),4),1)),C$13,$B$56:$B,">"&$B$7,$B$56:$B,"<="&$C$7))
Thanks
Upvotes: 0
Views: 98
Reputation: 5953
It is not possible to set cell value using custom formula. You might want to consider using custom menu with a custom dialog
CopyFormulaPage.html
<!DOCTYPE html>
<html>
<script>
function Submit(){
var src = document.getElementById("source").value;
var dst = document.getElementById("destination").value;
google.script.run.withSuccessHandler(onSuccess).CopyFormula(src,dst);
}
function onSuccess(){
var inDiv = document.getElementById('input');
var outDiv = document.getElementById('output');
outDiv.innerHTML = 'Formula copied successfully';
inDiv.innerHTML = '';
}
</script>
<body>
<div id="output"></div><br>
<div id="input">
<label for="source">Source Range:</label><br>
<input type="text" id="source" name="source"><br><br>
<label for="destination">Destination Range:</label><br>
<input type="text" id="destination" name="destination"><br><br>
<button onclick='Submit()'>Submit</button>
</div>
</body>
</html>
Code.gs
function onOpen() {
var ui = SpreadsheetApp.getUi();
// Or DocumentApp or FormApp.
ui.createMenu('Custom Menu')
.addItem('Copy Formula', 'ShowDialog')
.addToUi();
}
function ShowDialog(){
var html = HtmlService.createHtmlOutputFromFile('CopyFormulaPage')
.setWidth(300)
.setHeight(180);
SpreadsheetApp.getUi().showModalDialog(html, 'Copy Formula Dialog');
}
function CopyFormula(src,dst){
Logger.log(src+" "+dst);
var sheet = SpreadsheetApp.getActiveSheet();
var dstRange = sheet.getRange(dst);
sheet.getRange(src).copyTo(dstRange);
}
CopyFormula()
in the server with success handlers using google.script.run.withSuccessHandler()
$B14
. As shown in the output, the copied cell adjusts the unlocked reference to $B15
, $B16
, and so on..Upvotes: 1
Reputation: 5852
I think you should debug it yourself step by step.
Remove all $
before each row number except those act as header row or a constant cell.
To apply with Google Apps Script.
The simplest way is to create with setFormulas(formulas).
The second way would the using replace
to replace the row number of existing formula but the conditional is that you only added $
to those rows do not change.
You should be looking for ARRAYFORMULA.
It works by putting a single formula like this in B2
.
onEdit
is not needed in this case.
=ARRAYFORMULA(IF(A2:A="",,VLOOKUP(A2:A,Data!A:B,2,FALSE)))
Upvotes: 1