Append a new row to the end of sheets using Gspread - gspread

I have this code, I need to append the values to the columns in my google sheet and the values should be added at the end of the sheet in a new row without deleting existing datas
all_values = worksheet.get_all_values()
row_count = len(all_values)
sheet_range = "'{}'!{row}:{row}".format(worksheet.title, row=row_count+1+insert_count)
values = {
"Name": "Ford",
"Age": "34",
"Color": 'Blue'
}
worksheet.append_row(sheet_range, values)

I figured it out, it's actually quite simple.
body=[0, 4, 9,7,5] #the values should be a list
worksheet.append_row(body, table_range="A1:E1")
#table_range should be range of columns in the sheet, example from A1 to E1 (A1:E1)
other parameters are optional.
this will append the values in body to the last row in the sheet and it will not overwrite existing data.

have to tried to resize the sheet to the number of rows that are actualy present ? :
sheet.resize(1)

Related

Copy Data from one cell and insert them to another cell under a unique word or sentence

You will find two columns in the below link. Columns A and B. I want to insert the data in Columns A2 to Cell B2 under this line 'Critical Dates Meeting Comments:'
Dates
function myFunction() {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet102");
var targetSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Sheet102");
sheet.getRange("A2:A164").moveTo(targetSheet.getRange("B2:B164"));
}
I used the code but it only transfer the data from A to replace B.
Is there a way to alter this code or maybe use another one to insert data instead of replacing it?

Google Apps Script: Activate and sort rows when cells in given column are not blank

I'm extremely new to Apps Script and trying to make my first thing. It's a shopping list.
I want to create a function that will activate and then sort (by Column 1, 'Aisle #') all rows where there are values in a given other column (Column 3, 'Qty'). The idea is to sort the items on the list for that week (i.e., with a value filled in for Qty) by aisle to give me the order I should be looking for things. I do not want to sort items which are in the spreadsheet but without
a value for Qty.
Here is what I've got so far:
var sheet = ss.getActiveSheet()
var range = sheet.getDataRange();
var rangeVals = range.getValues()
function orderList2(){
if(rangeVals[3] != ""){
sheet.activate().sort(1, ascending=true);
};
};
I'm trying to use "if" to define which rows to activate before doing the sort (as I don't want to sort the entire sheet—I only want to sort the items I will be buying that week, i.e., the items with a value in Column 3). The script runs but ends up sorting the entire sheet.
The closest thing I could find was an iteration, but when I did it, it ended up only activating the top-left cell.
Any help you can provide would be greatly appreciated!
Cheers,
Nick
Answer:
Use Range.sort() instead of Sheet.sort() if you don't want to sort the entire sheet.
Explanation:
You want to sort the data according to the value in column A (Aisle #), if the corresponding value in C (Qty) is not empty.
If my assumption is correct, the rows where Qty is empty should go below the rest of data, and they should not be sorted according to their Aisle #.
In this case, I'd suggest the following:
Sort the full range of data (headers excluded) according to Qty, so that the rows without a Qty are placed at the bottom, using Range.sort() (if you don't need to exclude the headers, you can use Sheet.sort() instead).
Use SpreadsheetApp.flush() to apply the sort to the spreadsheet.
Use getValues(), filter() and length to know how many rows in the initial range have their column C populated (variable QtyElements in the sample below).
Using QtyElements, retrieve the range of rows with a non-empty column C, and sort it according to column 1, using Range.sort().
Code sample:
function orderList2() {
var sheet = SpreadsheetApp.getActiveSheet();
var firstRow = 2; // Range starts at row 2, header row excluded
var fullRange = sheet.getRange(firstRow, 1, sheet.getLastRow() - firstRow + 1, sheet.getLastColumn());
fullRange.sort(3); // Sort full range according to Qty
SpreadsheetApp.flush(); // Refresh spreadsheet
var QtyElements = fullRange.getValues().filter(row => row[2] !== "").length;
sheet.getRange(firstRow, 1, QtyElements, sheet.getLastColumn())
.sort(1); // If not specified, default ascending: true
//.sort({column: 1, ascending: false}); // Uncomment if you want descending sort
}
Reference:
Range.sort(sortSpecObj)

Remove all columns to the right of a specific column

I have an Excel template file with a dynamic number of columns that represent work week dates. Some users have decided to add their own subtotal columns to the right of those columns. I need a way to identify the first blank column, and then truncate that column and all columns following it.
I had previously been using the following script to remove all columns that begin with the word "Column":
// Create a list of columns that start with "Column" and remove them.
Removed_ColumnNum_Columns = Table.RemoveColumns(PreviousStepName, List.Select(Table.ColumnNames(PreviousStepName), each Text.StartsWith(_, "Column") )),
Based on being able to find the first ColumnXX column, I want to remove it and all columns after it
You can use List.PositionOf to get your ColumnIndex instead of parsing text.
I'd put it together like this:
// [...]
ColumnList = Table.ColumnNames(#"Promoted Headers"),
ColumnXX = List.Select(ColumnList, each Text.StartsWith(_, "Column")){0},
ColumnIndex = List.PositionOf(ColumnList, ColumnXX),
ColumnsToKeep = List.FirstN(ColumnList, ColumnIndex),
FinalTable = Table.SelectColumns(#"Promoted Headers", ColumnsToKeep)
Remove Columns after ColumnXX
Find the first column that begins with the name "Column" and delete that column and all columns following it. This parses the XX as the column index so you need to make sure you haven't deleted columns prior to this step. i.e. "Column35" needs to be the 35th column at this step in the code.
// Find the first ColumnXX column and remove it and all columns to the right.
ColumnXX = List.Select(Table.ColumnNames(#"Promoted Headers"), each Text.StartsWith(_, "Column")){0},
ColumnIndex = Number.FromText(Text.Middle(ColumnXX, 6,4)),
ColumnListToRemove = List.Range(Table.ColumnNames(#"Promoted Headers"),ColumnIndex-1),
RemovedTrailingColumns = Table.RemoveColumns(#"Promoted Headers", ColumnListToRemove),
To make this more robust I would prefer to have a way to identify the column index of columnXX without parsing the digits from it.

Dynamically expand ALL lists and records from json

I want to expand all lists and records in a json response.
Columns are like e.g. (this is dynamically, it also can be 10 records and 5 lists):
Text, Text, [List], [List], Text, [Record], [Record], String, [Record]
I wrote a function for getting all columns with the specific type
Cn.GetAllColumnsWithType = (table as table, typ as type) as list =>
let
ColumnNames = Table.ColumnNames(table),
ColumnsOfType = List.Select(ColumnNames, (name) =>
List.AllTrue(List.Transform(Table.Column(table, name), (cell) => Type.Is(Value.Type(cell), typ))))
in
ColumnsOfType;
and a function to expand all lists from a table
Cn.ExpandAllListsFromTable = (table as table, columns as list) =>
let
expandedListTable = List.Accumulate(columns, table, (state, columnToExpand) =>
Table.ExpandListColumn(state, columnToExpand))
in
expandedListTable;
all lists are now records and i want to dynamically expand all these records.
I think i need a foreach to iterate through the list (which are only records cause of Cn.GetAllColumnsWithType),
Table.ExpandRecordColumn each element with it's Table.ColumnNames and add it to the table but i don't know how to do it.
Maybe you can help me out cause it's driving me crazy.
Cheers
Edit:
I recently opened a thread but there i wanted to expand a specific one like
#"SelectItems" = Table.SelectColumns(records,{"$items"}),
#"$items1" = #"SelectItems"{0}[#"$items"],
but now i want to do it all dynamically.
Chris Webb wrote a function to do this for Table-type columns:
http://blog.crossjoin.co.uk/2014/05/21/expanding-all-columns-in-a-table-in-power-query/
I've shared a tweaked version of that that I made for Record-type columns:
https://gist.github.com/Mike-Honey/0a252edf66c3c486b69b
You do not need a function for that. Assuming that the previous step in M was named Removed Other Columns, and that the column to expand is named Data, then make regular Expand step and replace its code of #"Expanded Data" with the following code:
#"Expanded Data"
= Table.ExpandTableColumn(
#"Removed Other Columns",
"Data",
List.Union(List.Transform(#"Removed Other Columns"[Data], each Table.ColumnNames(_)))
)
It expands all columns without referencing their names.

How do I add data in a new column on each row within a CSV?

So I have a method that looks like this:
csvs = Dir["#{#dir_name}/#{#state}/*.csv"]
csvs.each do |csv|
city = csv.split(/[\/]|.csv-updated|.csv/).last
CSV.foreach(csv, headers: true) do |row|
temp = extract_email(row['Website'])
# add result from temp above to existing row
end
end
Basically what I want to do is, on each row that I process within the CSV, I want to do something with the data in row['Website'] (as represented as temp in the snippet above), and then I want to take the result and add it as new columns to that row.
So basically I want to append to a each row. How do I do that?
I figured this out.
Basically, I can't edit an existing CSV like that, so I just have to read all the rows from the old_csv and create a new_csv. From that old_csv, I then pass the corresponding data from the old_csv to the method I want (i.e. extract_email(row['Website']) and then I process that info and collect the emails in an array.
From there, all I have to do is iterate over the collection of temp and add it to the row object:
temp.each { |t| row << t }
Then I just add row to the new CSV, which will include the old row + the newly added columns. So in essence I am expanding each row.

Resources