I'm trying to make a script that will find the width of an item and check if the selected item width is the same and then show an alert.
For some reason my if condition is not working even when all the conditions are met.
Here is my code:
var doc = app.activeDocument;
function mm(n) {return n / 2.83464566929134;}
function pt(n) {return n * 2.83464566929134;}
//=====================
// Calculate Prisa
//=====================
var prisa = doc.pathItems.getByName("prisa");
var prisawidth = mm(prisa.geometricBounds[2]-prisa.geometricBounds[0]);
//=========================
// Calculate Selection
//=========================
var sel = doc.selection[0];
var selwidth = mm(sel.geometricBounds[2]-sel.geometricBounds[0]);
if (selwidth == prisawidth) {alert("Same Width");}
You can try this:
if (Math.abs(selwidth - prisawidth) < .01) alert("About the same width");
I think the problem has to do with rounding of the numbers. Say, you can see '2 mm' and '2 mm', but actually there are '2.00001 mm' and '2.00002 mm' or something like this. So it's need either to round the fugures before compairing or check if the diffference is less than some minimal value.
Related
I was wondering if someone is able to assist?
I'm trying to add an Arrayformula consisting of two IF functions, so I'm wanting to merge the following two formulas into one cell:
=ARRAYFORMULA(IF(D13:D104="","",(IF(K13:K104,K13:K104*20,"$0"))))
=ARRAYFORMULA(IF(D105:D="","",(IF(K105:K,K105:K*C4,"$0"))))
So the first section of the sheet needs to be multiplied by 20, and then the figure has changed and needs to be multiplied by 25 (which is cell C4)
Is it possible to merge these into one cell containing an Arrayformula+the two IF functions (or is there another/easier way for this)
Is it possible to add this into Google Apps Script so that it works in the backend (so not just a script that applies the formula into a cell - but doesn't show in the frontend or sheet)
More of a general question - When using Arrayformula with IF; and for example the output is specific text e.g. "Test Complete" associated to the range F2:F (checking if E2:E contains a particular phrase e.g. "Done") - for the empty cells in between (due to setting the False outcome as "") is it possible to somehow randomly add data into these blank cells without interrupting the formula? (so I have to option for automated text if the cell to the left states a particular term/word, but still have the option to manually add random data into blank cells)
Any assistance would be greatly appreciated
As for 1st and 2nd questions: it looks like a task for a custom function. Something like this:
function MULTI() {
var sheet = SpreadsheetApp.getActiveSheet();
var cell = sheet.getActiveCell();
var row = cell.getRow();
var value = sheet.getRange('K'+row).getValue();
return (row < 105) ? value * 20 : value * 25;
}
It gets a value from column K and multiplies it by 20 if the row less than 105 and by 25 for the rest of rows.
Here is the variant of the same formula that uses the cell 'C4':
function MULTIC4() {
var sheet = SpreadsheetApp.getActiveSheet();
var cell = sheet.getActiveCell();
var row = cell.getRow();
var value = sheet.getRange('K'+row).getValue();
var c4 = sheet.getRange('C4').getValue();
return (row < 105) ? value * 20 : value * c4;
}
And it can be done with the trigger onEdit():
function onEdit(e) {
var col = e.range.columnStart;
if (col != 11) return; // 11 = K
var sheet = e.source.getActiveSheet();
if (sheet.getName() != 'Sheet1') return;
var c4 = sheet.getRange('C4').getValue();
var row = e.range.rowStart;
var dest_cell = sheet.getRange('D'+row);
var value = sheet.getRange(row,col).getValue();
var result = (row < 105) ? value * 20 : value * c4;
dest_cell.setValue(result);
}
It recalculates automatically the value in the cell of column 'D' (current row) every time when you're changing value in the cell of column 'K'. On the sheet 'Sheet1'.
I am wondering if something that i would like to achieve is possible, please look at the picture and read description below:
I would like to add a column to the right, where if a cell table[ActionType] = "TERMINATING", it calculates a difference between timestamps (timestamp for TERMINATING - timestamp for STARTING in below row). If the result is positive (>0) then store it in a column in a corresponding row (eg next to timestapm for terminating), if result is negative don't store it. And all of that applied to whole table.
I tried conditional column and i guess it cannot be done with this or at least I couldn't make it.
Will be very thankful for responses and tips!
Pre-requisite :- Add an Index Column using the query editor. Make sure they are in the next row to each other.
It is advisable to keep TimeStamp column as a DateTime Column itself.
So, if you can change your TimeStamp column to a DateTime column then try this :-
Difference =
Var Get_Action_Type = Table1[ActionType]
Var required_Index_1 = Table1[Index] + 1
Var required_Index = IF(required_Index_1 > MAX(Table1[Index]),required_Index_1-1, required_Index_1)
Var Current_Action_TimeStamp = Table1[TimeStamp]
Var next_Action_TimeStamp = CALCULATE(MAX(Table1[TimeStamp]),FILTER(Table1, Table1[Index] = required_Index))
Var pre_result = IF(Get_Action_Type = "TERMINATING", DATEDIFF(Current_Action_TimeStamp, next_Action_TimeStamp,SECOND), BLANK())
Var result = IF(pre_result > 0, pre_result, BLANK())
return result
And if you cannot change it to a Date Time, then try this calculated column,
Difference_2 =
Var Get_Action_Type = Table1[ActionType]
Var required_Index_1 = Table1[Index] + 1
Var required_Index = IF(required_Index_1 > MAX(Table1[Index]),required_Index_1-1, required_Index_1)
Var Current_Action_TimeStamp = Table1[Time_Stamp_Number]
Var next_Action_TimeStamp = CALCULATE(MAX(Table1[Time_Stamp_Number]),FILTER(Table1, Table1[Index] = required_Index))
Var pre_result = IF(Get_Action_Type = "TERMINATING", next_Action_TimeStamp - Current_Action_TimeStamp, BLANK())
Var result = IF(pre_result > 0, pre_result, BLANK())
return result
The Output looks as below :-
Kindly accept the answer if it helps and do let me know, how it works for you.
I need a formula that will help me calculate the $ expense amount for my milage rates.
Here is my sheet https://docs.google.com/spreadsheets/d/1PPFuFWbxWi9iIdtYBJvnSNB1j1cjjQutepF3hnpGoFM/edit?usp=sharing
On the tab that's expenses, I need to check the year of my date in Col A (because different years have different rates), then check Col D to see if it says Milage, then check Col E for what type of milage (there are 4 types), then return the number input in Col I times the appropriate rate for that year and type of milage. I have a table set up with the rates in another tab.
I'm thinking it will be a long IF and AND formula. Any help would be great!
In 'Essentials Log', I've changed the format of your year start-end dates to state the year you're referencing. I've added a column for "Milage".
Expense Reference Screenshot
In 'Expenses'!M2, I tried this and it seems to work:
=ARRAYFORMULA(iferror(if(isblank(A2:A),"",I2:I*vlookup(D2:D&year(A2:A)&E2:E,query({'Essentials Log'!Y2:Y&'Essentials Log'!Z2:Z&'Essentials Log'!AA2:AA,'Essentials Log'!AB2:AB},"Select *"),2,false))))
Working Example Screenshot
Have a look (I copied your example sheet): Milage expense
I solved this with creating an app script.
I realized I didn't want to use a formula because in my $ col most entries will be keyed in and so I didn't want to copy and paste a formula every time.
Here is the code if anyone might need it. I added it to the menu so the calculation is done with a click.
function expenseMilageCalculation() {
var auditionsSheet = SpreadsheetApp.getActiveSpreadsheet();
var expensesTab = auditionsSheet.getActiveSheet();
var activeCell = expensesTab.getActiveCell();
var activeRow = activeCell.getRow();
var expenseDate = expensesTab.getRange(activeRow, 1).getValue();
var expenseYear = expenseDate.getFullYear();
var expenseType = expensesTab.getRange(activeRow, 4).getValue();
var expenseDetails = expensesTab.getRange(activeRow, 5).getValue();
var numMiles = expensesTab.getRange(activeRow, 9).getValue();
var essentialsLogTab = auditionsSheet.getSheetByName("Essentials Log")
//2018 Business Milage
if (expenseYear == 2018 && expenseType == "Milage" && expenseDetails == "Business") {
var milageBusinessRate2018 = essentialsLogTab.getRange(3, 27).getValue();
var dollarMilesDeduction = numMiles * milageBusinessRate2018
expensesTab.getRange(activeRow, 8).setValue(dollarMilesDeduction)
}
//2019 Business Milage
if (expenseYear == 2019 && expenseType == "Milage" && expenseDetails == "Business") {
var milageBusinessRate2019 = essentialsLogTab.getRange(8, 27).getValue();
var dollarMilesDeduction = numMiles * milageBusinessRate2019
expensesTab.getRange(activeRow, 8).setValue(dollarMilesDeduction)
}
I have a map reduce view:
.....
emit( diffYears, doc.xyz );
reduced with _sum.
xyz is then a number which is summed per integer(diffYears).
The output looks roughly like this:
4 1204.9
5 796.19
6 1124.8
7 1112.6
8 1993.62
9 159.26
10 395.41
11 456.05
12 457.97
13 39.80
14 483.68
15 269.469
etc..
What I would like to do is group the results as follows:
Grouping Total per group
0-4 1959.2 i.e add up the xyz's for years 0,1,2,3,4
5-9 3998.5 same for 5,6,7,8,9 ...etc.
10-14 3566.3
I saw a suggestion where a list was used on a view output here: Using a CouchDB view, can I count groups and filter by key range at the same time?
but have been unable to adapt it to get any kind of result.
The code given is:
{
_id: "_design/authors",
views: {
authors_by_date: {
map: function(doc) {
emit(doc.date, doc.author);
}
}
},
lists: {
count_occurrences: function(head, req) {
start({ headers: { "Content-Type": "application/json" }});
var result = {};
var row;
while(row = getRow()) {
var val = row.value;
if(result[val]) result[val]++;
else result[val] = 1;
}
return result;
}
}
}
I substituted var val = row.key in this section:
while(row = getRow()) {
var val = row.value;
if(result[val]) result[val]++;
else result[val] = 1;
}
(although in this case the result is a count.)
This seems to be the way to do it.
(It is like having a startkey and endkey for each grouping which I can do manually, naturally, but not inside a process. Or is there a way of entering multiple start- and endkeys into one GET command???? )
This must be a fairly normal thing to do especially for researchers using statistical analysis.
I assume therefore that it does get done but I cannot locate examples
as far as CouchDB is concerned.
I would appreciate some help with this please or a pointer in the right direction.
Many thanks.
EDIT:
Perhaps the answer lies in a process in 'reduce' to group the output??
You can accomplish what you want using a complex key. The limitation is that the group size is static and needs to be defined in the view.
You'll need a simple step function to create your groups within map like:
var size = 5;
var group = ( doc.diffYears - (doc.diffYears % size)) / size;
emit( [group, doc.diffYears], doc.xyz);
The reduce function can remain _sum.
Now when you query the view use group_level to control the grouping. At group_level=0, everything will be summed and one value will be returned. At group_level=1 you'll receive your desired sums of 0-4, 5-9 etc. At group_level=2 you'll get your original output.
I'm trying to retrieve a value from an array, based on an index parsed from a string of digits. I'm stuck on this error, and the other answers to similar questions in this forum appear to be for more advanced developers (this is my first iOS app).
The app will eventually look up weather reports ("MAFOR" groupings of 5 digits each) from a web site, parse each group and lookup values from arrays for wind direction, speed, forecast period etc using each character.
The playground code is below, appreciate any help on where I am going wrong (look for ***)
//: Playground - noun: a place where people can play
import UIKit
var str = "Hello, playground"
// create array for Forecast Period
let forecastPeriodArray = ["Existing conditions at beginning","3 hours","6 hours","9 hours","12 hours","18 hours","24 hours","48 hours","72 hours","Occasionally"]
// create array for Wind Direction
let windDirectionArray = ["Calm","Northeast","East","Southeast","South","Southwest","West","Northwest","North","Variable"]
// create array for Wind Velocity
let windVelocityArray = ["0-10 knots","11-16 knots","17-21 knots","22-27 knots","28-33 knots","34-40 knots","41-47 knots","48-55 knots","56-63 knots","64-71 knots"]
// create array for Forecast Weather
let forecastWeatherArray = ["Moderate or good visibility (> 3 nm.","Risk of ice accumulation (temp 0C to -5C","Strong risk of ice accumulkation (air temp < -5C)","Mist (visibility 1/2 to 3 nm.)","Fog (visibility less than 1/2 nm.)","Drizzle","Rain","Snow, or rain and snow","Squally weather with or without showers","Thunderstorms"]
// retrieve full MAFOR line of several information groups (this will be pulled from a web site)
var myMaforLineString = "11747 19741 13757 19751 11730 19731 11730 13900 11630 13637"
// split into array components wherever " " is encountered
var myMaforArray = myMaforLineString.components(separatedBy: " ")
let count = myMaforArray.count
print("There are \(count) items in the array")
// Go through each group and parse out the needed digits
for maforGroup in myMaforArray {
print("MAFOR group \(maforGroup)")
// get Forecast Period
var idx = maforGroup.index(maforGroup.startIndex, offsetBy: 1)
var periodInt = maforGroup[idx]
print("periodInt is \(periodInt)")
// *** here is where I am stuck... trying to use the periodInt index value to retrieve the description from the ForecastPeriodArray
var periodDescription = forecastPeriodArray(periodInt)
print("Forecast period = (forecastPeriodArray(periodInt)")
// get Wind Direction
idx = maforGroup.index(maforGroup.startIndex, offsetBy: 2)
var directionInt = maforGroup[idx]
print("directionInt is \(directionInt)")
// get Wind Velocity
idx = maforGroup.index(maforGroup.startIndex, offsetBy: 3)
var velocityInt = maforGroup[idx]
print("velocityInt is \(velocityInt)")
// get Weather Forecast
idx = maforGroup.index(maforGroup.startIndex, offsetBy: 4)
var weatherInt = maforGroup[idx]
print("weatherInt is \(weatherInt)")
}
#shallowThought was close.
You are trying to access an array by its index, therefore use the array[index] notation. But your index has to be of the correct type. forecastPeriodArray[periodInt] therefore does not work since periodInt is not an Int as the name would suggest. Currently it is of type Character which does not make much sense.
What you are probably trying to achieve is convert the character to an integer and use that to access the array:
var periodInt = Int(String(maforGroup[idx]))!
You might want to add error handling for the case when the character does not actually represent an integer.