how to make the last row in a UICollectionview to be sticky using swift 3 - swift3

I used multi directional scrolling with a custom flow layout in a UICollectionView to create a numeric table.
The structure of the table should be like this. A numeric table which has the sum up value in the last row:
Now the first column and the first row of the table is static i.e sticky. I want the last row also to get Sticked at the bottom of the view. Kindly help me.
This is my current view of the table:
Thank You in advance.

if section == sectionCount-1 {
for item in 0...rowCount-1 {
let indexPath = IndexPath(item: item, section: section)
if let attrs = cellAttrsDictionary[indexPath] {
var frame = attrs.frame
if item == 0 {
// Assigning the size of the first column as 200
frame.size.width = 200
frame.origin.x = xOffset
}
// Configuration for the last row in the last cell.
// Subtracting the Cell height from the entire Collection View height and assigning it as the frame for the last row of the Table i.e precisely on Y position.
frame.origin.y = (collectionView?.frame.size.height)! + yOffset - CGFloat(CELL_HEIGHT)
attrs.frame = frame
}
}
}

Related

Google Sheets Apps Script - How to add an Arrayformula and multiple associated IF functions within a script (Without showing the formula within UI)

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'.

how to solve concatenate issue with.cell()? row = row work, column = column gives error

I am looping through an excel sheet, looking for a specific name. When found, I print the position of the cell and the value.
I would like to find the position and value of a neighbouring cell, however I can't get .cell() to work by adding 2, indicating I would like the cell 2 columns away in the same row.
row= row works, but column= column gives error, and column + 2 gives error. Maybe this is due to me listing columns as 'ABCDEFGHIJ' earlier in my code? (For full code, see below)
print 'Cell position {} has value {}'.format(cell_name, currentSheet[cell_name].value)
print 'Cell position next door TEST {}'.format(currentSheet.cell(row=row, column=column +2))
Full code:
file = openpyxl.load_workbook('test6.xlsx', read_only = True)
allSheetNames = file.sheetnames
#print("All sheet names {}" .format(file.sheetnames))
for sheet in allSheetNames:
print('Current sheet name is {}'.format(sheet))
currentSheet = file[sheet]
for row in range(1, currentSheet.max_row + 1):
#print row
for column in 'ABCDEFGHIJ':
cell_name = '{}{}'.format(column,row)
if currentSheet[cell_name].value == 'sign_name':
print 'Cell position {} has value {}'.format(cell_name, currentSheet[cell_name].value)
print 'Cell position TEST {}'.format(currentSheet.cell(row=row, column=column +2))
I get this output:
Current sheet name is Sheet1
Current sheet name is Sheet2
Cell position D5 has value sign_name
and:
TypeError: cannot concatenate 'str' and 'int' objects
I get the same error if I try "column = column" as "column = column +2".
Why does row=row work, but column=column dosen't? And how to find the cell name of the cell to the right of my resulting D5 cell?
The reason row=row works and column=column doesn't is because your column value is a string (letter from A to J) while the column argument of a cell is expecting an int (A would be 1, B would be 2, Z would be 26, etc.)
There are a few changes I would make in order to more effectively iterate through the cells and find a neighbor. Firstly, OpenPyXl offers sheet.iter_rows(), which given no arguments, will provide a generator of all rows that are used in the sheet. So you can iterate with
for row in currentSheet.iter_rows():
for cell in row:
because each row is a generator of cells in that row.
Then in this new nested for loop, you can get the current column index with cell.column (D would give 4) and the cell to the right (increment by one column) would be currentSheet.cell(row=row, column=cell.column+1)
Note the difference between the two cell's: currentSheet.cell() is a request for a specific cell while cell.column+1 is the column index of the current cell incremented by 1.
Relevant OpenPyXl documentation:
https://openpyxl.readthedocs.io/en/stable/api/openpyxl.cell.cell.html
https://openpyxl.readthedocs.io/en/stable/api/openpyxl.worksheet.worksheet.html

Extract the digits and append it in a different cell?

I am trying to automatically RegExp(extract) the digits(AREA number) in Column 3 combined with the Text 'A' to append in Column 1 Date INDEX.
The problem is I'm not yet familiar in using google sheets app-scripts.
Tried looking for solutions with similar situation as me, but to no avail.
I don't know to put VBA to app-scripts.
Tried using some codes.
I still can't seem to make it work.
Can anyone point me in the right direction?
Thank you if you can help me out. Thanks.
EDIT:
The scenarios is in the office i cant make column for the formula.
It must be "behind the scene".
My googlesheets
//NOT WORKING code
function onEdit(e) {
var rg=e.range;
var sh=e.range.getSheet();
var area=sh.getName();
var regExp = new RegExp("\d*"); // Extract the digits
var dataIndex = regExp.exec(area)[1];
if(rg.columnStart==3) { // Observe column 3
var vA=rg.getValues();
for(var i=0;i<vA.length;i++){
if(vA[i][0]) {
sh.getRange(rg.rowStart + i,1).appendText((dataIndex) +'A'); // append to column 1 with 'A' and extracted digits
}
}
}
}
This answer extends your approach of using a script with an OnEdit trigger. But there are a number of differences between the two sets of code.
The most significant difference is that I have used the Javascript split method (var fields = value.split(' ');) to get distinct values from the data entry.
Most of the other differences are error checking:
if(rg.columnStart === 3 && area === "work") {: test for sheet="work" as well as an edit on Column C
var value = e.value.toUpperCase();: anticipate that the test might be in lower case.
if (fields.length !=2){: test that there are two elements in the data entry.
if (fields[0] != "AREA"){: test that the first elment of the entry is the word 'area'
if (num !=0 && numtype ==="number"){; test that the second element is a number, and that it is NOT zero.
if (colA.length !=0){: test that Column A is not empty
var newColA = colA+"A"+num;: construct the new value for Column A by using unary operator '+'.
function onEdit(e){
// so5911459101
// test for edit in column C and sheet = work
var ss = SpreadsheetApp.getActiveSpreadsheet;
// get Event Objects
var rg=e.range;
var sh=e.range.getSheet();
var area=sh.getName();
var row = rg.getRow();
// test if the edit is in Column C of sheet = work
if(rg.columnStart === 3 && area === "work") { // Observe column 3 and sheet = work
//Logger.log("DEBUG: the edit is in Column C of 'Work'")
// get the edited value
var value = e.value.toUpperCase();
//Logger.log("DEBUG: the value = "+value+", length = "+value.length+", uppercase = "+value.toUpperCase());
// use Javascript split on the value
var fields = value.split(' ');
//Logger.log(fields);//DEBUG
// Logger.log("DEBUG: number of fields = "+fields.length)
// test if there are two fields in the value
if (fields.length !=2){
// Logger.log("DEBUG: the value doesn't have two fields")
}
else{
// Logger.log("DEBUG: the value has two fields")
// test if the first field = 'AREA'
if (fields[0] != "AREA"){
// Logger.log("DEBUG: do nothing because the value doesn't include area")
}
else{
// Logger.log("DEBUG: do something because the value does include area")
// get the second field - it should be a value
var num = fields[1];
num =+num
var numtype = typeof num;
// Logger.log("DEBUG: num= "+num+" type = "+numtype); //number
// test type of second field
if (num !=0 && numtype ==="number"){
// Logger.log("DEBUG: the second field IS a number")
// get the range for the cell in Column A
var colARange = sh.getRange(row,1);
// Logger.log("DEBUG: the ColA range = "+colARange.getA1Notation());
// get the value of Column A
var colA = colARange.getValue();
// Logger.log("DEBUG: Col A = "+colA+", length = "+colA.length);
// test if Column A is empty
if (colA.length !=0){
var newColA = colA+"A"+num;
// Logger.log("DEBUG: the new cola = "+newColA);
// update the value in Column A
colARange.setValue(newColA);
}
else{
// Logger.log("DEBUG: do nothing because column A is empty")
}
}
else{
// Logger.log("DEBUG: the second field isn't a number")
}
}
}
}
else{
//Logger.log("DEBUG: the edit is NOT in Column C of 'Work'")
}
}
REVISION
If the value in Column C is sourced from data validation, then no need for and testing except that the edit was in Column C and the sheet = "work".
Included two additional lines of code:
var colAfields = colA.split('-');
var colAdate = colAfields[0];
This has the effect of excluding any existing characters after the hyphen, and re-establishing the hyphen, row number plus "A" and the AREA numeral.
function onEdit(e){
// so5911459101 revised
// only one test - check for ColumnC and sheet="work"
// test for edit in column C and sheet = work
var ss = SpreadsheetApp.getActiveSpreadsheet;
// get Event Objects
var rg=e.range;
var sh=e.range.getSheet();
var area=sh.getName();
var row = rg.getRow();
// test if the edit is in Column C of sheet = work
if(rg.columnStart === 3 && area === "work") { // Observe column 3 and sheet = work
Logger.log("DEBUG: the edit is in Column C of 'Work'")
// get the edited value
var value = e.value
//Logger.log("DEBUG: the value = "+value+", length = "+value.length);
// use Javascript split on the value
var fields = value.split(' ');
//Logger.log(fields);//DEBUG
// get the second field - it should be a value
var num = fields[1];
// get the range for the cell in Column A
var colARange = sh.getRange(row,1);
// Logger.log("DEBUG: the ColA range = "+colARange.getA1Notation());
// get the value of Column A
var colA = colARange.getValue();
// Logger.log("DEBUG: Col A = "+colA+", length = "+colA.length);
// use Javascript split on Column A in case of existing value
var colAfields = colA.split('-');
var colAdate = colAfields[0];
// build new value
var newColA = colAdate+"-"+row+"A"+num;
// Logger.log("DEBUG: the new cola = "+newColA);
// update the value in Column A
colARange.setValue(newColA);
}
else{
Logger.log("DEBUG: the edit is NOT in Column C of 'Work'")
}
}

Is there a way to check over a column range for a certain data?

I have 2 workbooks,
Spreadsheet A has multiple sheets of the same form.
Spreadsheet B records contain cells from Spreadsheet A sheets into a single row per sheet (log).
The first column in Spreadsheet B contains hyperlinks of all sheets in Spreadsheet A. I need to check the hyperlinks column in Spread B as follows:
if hyperlink exist in column A,
check for the next sheet in Spreadsheet A index++
else
record the new data in a row after the last row,,,,
my code used to have clear() function to start submission from scratch to Spreadsheet B, but it's not efficient, execution time wise.
I am trying to manipulate my current code to check manually on existing records and i++/submit new row based on this logic.
you can ignore all missing lines of code because i have it working, i just need the logic of the idea of doing this, since I am not advanced in Apps Script. Thanks in advance for your help.
Spreadsheet A - Sheet1
Spreadsheet A - Sheet2
Spreadsheet B
I want the if statement to run on the Sheet link column in Workbook B.... in case of adding Sheet #3 to Workbook A (picture 1&2), upon submission, I want to check on Sheet links in Workbook B log (because it's unique) if it exists, i++.... if doesn't exist, add 3rd record in log.
for(var index = 2; index < WBA.length; index++)
{
var Sheet = "https://docs.google.com/spreadsheets/d/WBA ID/edit#gid=";
var SID = WBA[index].getSheetId();
var SheetID = Sheet + SID;
var Data = WBB.getDataRange().getValues();
for(var i = 0; i < Data.length; i++)
{
if(Data[i][1] == SheetID)
i++
else
{
var lastRow = WBB.getLastRow() + 1;
var Sheets_ID = new Array()
Sheets_ID.push( [WBA[index].getSheetId()] )
WBB.getRange(lastRow,1).setFormula('=hyperlink("https://docs.google.com/spreadsheets/d/WBA ID/edit#gid=' + Sheets_ID +'")');
var PN_Source = WBA[index].getRange(6,3,1,1).getValues(); //getRange(row number, column number, number of rows, number of columns)
var SC_Source = WBA[index].getRange(8,3,1,1).getValues();
Try this:
function checkForLink() {
var ssB=SpreadsheetApp.getActive();
var sh1=ssB.getActiveSheet();
var rg1=sh1.getRange(1,1,1,4);
var vA1=rg1.getValues()[0];
var hObj={};
vA1.forEach(function(el,i){if(el){hObj[el]=i;}});
var linkA=sh1.getRange(2,hObj['Sheet Link']+1,sh1.getLastRow(),1).getValues().map(function(r){return r[0];});
var ssA=SpreadsheetApp.openById('SSA ID');
var shts=ssA.getSheets();
shts.forEach(function(sh,i){
var vA=sh.getRange(1,1,2,sh.getLastColumn()).getValues();
var sObj={};
vA[0].forEach(function(e,i){sObj[e]=i;});
var shlink=Utilities.formatString('https://docs.google.com/spreadsheets/d/%s//edit#gid=%s',ssA.getId(),sh.getSheetId());
if(linkA.indexOf(shlink)==-1) {
sh1.appendRow([vA[1][sObj.date],vA[1][sObj.age],vA[1][sObj.name],shlink]);
}
});
}

Apply Tooltip to diffrent datasets or pass an array to tooltip in Chart.js?

I am trying to show multi line graph for showing profit/loss . I am able to plot graph.
var niftyProfit = [];
var niftyProfitChartData = [];
var sum = 0;
data.forEach(function(obj) {
niftyProfit.push(obj.profit);
});
for (var i in niftyProfit) {
sum = sum + niftyProfit[i];
niftyProfitChartData.push(sum);
}
obj.profit is the p/l column data. I want to populate the value, which I did in for loop for eg. consider profit = [4,2,-3,-5], then my final array to populate in chart would become [4,6,3,-2]. I ploted data on chart which is array niftyProfitChartData , now In tooltip on hover its showing data from niftyProfitChartData .But I want to show data from niftyProfit array in tooltip . Here is Fiddle Link of what i tried till now .
http://jsfiddle.net/zkrh7/159/