How to sum values in rows in a table in Google Docs? - google-docs

i have a table of different prices in each rows. how do i make a sum of those rows in google docs and display it with "sum="?
Unit Name Description Price
<> <> <>
<> <> <>
sum=

I found this script and tested it.
function sumTable() {
var doc = DocumentApp.getActiveDocument();
var body = doc.getBody();
var tables = body.getTables();
var numRows = tables[0].getNumRows();//specify the table in [ ] that you're working with
var row;
var val;
var total = 0.0;
for(row = 1; row<numRows-1; row++) {
val = tables[0].getCell(row, 2).getText();
if(val) {
total += parseFloat(val);
}
}
tables[0].getCell(numRows -1,2).setText("$"+total.toString());
}
Now when you click “Run” in your Apps Script project it will execute and update the table, if you want to run the script from the Google Doc, you can run this other function and it will add an option under “Add-ons” from the Google Doc menu.
function onOpen(e) {
var menu = DocumentApp.getUi().createAddonMenu();
menu.addItem("Sum Table", "sumTable");
menu.addToUi();
}

Related

Time Stamp Script not working on Pasting/Dragging Cell Values

I have a script which records the time stamp on which an entry is made in a specific cell. It uses a onEdit trigger.
PROBLEM STATEMENT:
When I'm dragging/copy-pasting the data over a range of adjacent cells(in the same column), only the first entry is producing a time-stamp output.
CODE:
var s = SpreadsheetApp.getActiveSheet();
var sName = s.getName();
var r = s.getActiveCell();
if( r.getColumn() == 8 && sName == 'Processing') { //which column to watch on which sheet
var row = r.getRow();
var time = new Date();
SpreadsheetApp.getActiveSheet().getRange('CU' + row.toString()).setValue(time); //which column to put timestamp in
};
};
You are using onEdit to insert a timestamp when a field is edited. But when an edit is done by copy/paste or dragging a cell/range, the timestamp is applied only for the first cell in the new target range.
The reason that this is happening is that your script output recognises only the activecell and does not recognise the rest of the activerange
var r = s.getActiveCell();
var row = r.getRow();
There are several solutions to your problem.
ActiveRange:
Enable the script to process the number of rows in the active range.
function onEdit() {
var s = SpreadsheetApp.getActiveSheet();
var sName = s.getName();
var r = s.getActiveCell();
var row = r.getRow();
var ar = s.getActiveRange();
var arRows = ar.getNumRows()
// Logger.log("DEBUG: the active range = "+ar.getA1Notation()+", the number of rows = "+ar.getNumRows());
var time = new Date();
if( r.getColumn() == 8 && sName == 'Processing') { //which column to watch on which sheet
// loop through the number of rows
for (var i = 0;i<arRows;i++){
var rowstamp = row+i;
SpreadsheetApp.getActiveSheet().getRange('CU' + rowstamp.toString()).setValue(time); //which column to put timestamp in
}
}
}
Event Objects: Enable the script to take advantage of the event Objects generated by OnEdit.
In the following script, the edited range, the column, sheet name, the starting and ending row numbers are all obtained/determined by using Event Objects available to onEdit.
function onEdit(event) {
var s = SpreadsheetApp.getActiveSheet();
// Logger.log(JSON.stringify(event)); //DEBUG
var ecolumnStart = event.range.columnStart;
var erowStart = event.range.rowStart;
var erowEnd = event.range.rowEnd;
var ecolumnEnd = event.range.columnEnd;
// Logger.log("DEBUG: Range details - Column Start:"+ecolumnStart+", Column End:"+ecolumnEnd+", Row start:"+erowStart+", and Row End:"+erowEnd);
// Logger.log("DEBUG: the sheet is "+event.source.getName()+", the range = "+event.range.getA1Notation());
var sName = event.range.getSheet().getName();
// Logger.log("DEBUG: the sheet name is "+sName)
var time = new Date();
var numRows = event.range.rowEnd -event.range.rowStart+1;
if( event.range.columnStart == 8 && sName == 'Processing') { //which column to watch on which sheet
// loop though the number of rows
for (var i = 0;i<numRows;i++){
var row = event.range.rowStart+i;
SpreadsheetApp.getActiveSheet().getRange('B' + row.toString()).setValue(time); //which column to put timestamp in
}
}
}

programmatically print out cell and comments contents from spreadsheet

I have a spreadsheet with worksheets (originally in Google Sheets, but I can export to .xlsx or .ods) and I would like to programmatically print out the cell values of the first line along with the comments in each cell. E.g. see screenshot below of worksheet (https://docs.google.com/spreadsheets/d/1DGsrEKrxfQm8sRzfLyqu4z6Hx8eDdkVDiYlN3Rwve6A/edit?usp=sharing):
There are 3 cells in row1 each with a comment in them.
I would like to programmatically print out the contents of this worksheet so that they look something like:
Cell:"field1",Comment:"key=foobar"
Cell:"field2",Comment:"key=bar"
Cell:"field3",Comment:"key=foobar"
Any ideas?
google-spreadsheets
function getNotes_(fileId, sheetName, rangeA1)
{
var data = [];
var file = SpreadsheetApp.openById(fileId);
var sheet = file.getSheetByName(sheetName);
var range = sheet.getRange(rangeA1);
var values = range.getValues();
var notes = range.getNotes();
var getResult_ = function(value, i) { data.push( 'Cell:"' + value + '",Comment:"' + rowNotes[i] +'"') };
var rowNotes = [];
for (var i = 0, l = values.length; i < l; i++)
{
rowNotes = notes[i];
values[i].forEach(getResult_);
}
return data;
}

How can I change the format of the ColumnField column headings in EPPlus?

I create a column field in EPPlus like so:
// Column field[s]
var monthYrColField = pivotTable.Fields["MonthYr"];
pivotTable.ColumnFields.Add(monthYrColField);
...that displays like so (the "201509" and "201510" columns):
I want those values to display instead as "Sep 15" and "Oct 15"
In Excel Interop it's done like this:
var monthField = pvt.PivotFields("MonthYr");
monthField.Orientation = XlPivotFieldOrientation.xlColumnField;
monthField.NumberFormat = "MMM yy";
...but in EPPlus the corresponding variable (monthYrColField) has no "NumberFormat" (or "Style") member.
I tried this:
pivotTableWorksheet.Column(2).Style.Numberformat.Format = "MMM yy";
...but, while it didn't complain or wreak havoc, also did not change the vals from "201509" and "201510"
How can I change the format of my ColumnField column headings in EPPlus from "untransformed" to "MMM yy" format?
UPDATE
For VDWWD:
As you can see by the comments, there are many things related to PivotTables which don't work or are hard to get to work in EPPlus; Excel Interop is a bear (and not a teddy or a Koala, but more like a grizzly) compared to EPPlus, but as to PivotTables, it seems that EPPlus is kind of half-baked to compared to Exterop's fried-to-a-crispness.
private void PopulatePivotTableSheet()
{
string NORTHWEST_CORNER_OF_PIVOT_TABLE = "A6";
AddPrePivotTableDataToPivotTableSheet();
var dataRange = pivotDataWorksheet.Cells[pivotDataWorksheet.Dimension.Address];
dataRange.AutoFitColumns();
var pivotTable = pivotTableWorksheet.PivotTables.Add(
pivotTableWorksheet.Cells[NORTHWEST_CORNER_OF_PIVOT_TABLE],
dataRange,
"PivotTable");
pivotTable.MultipleFieldFilters = true;
pivotTable.GridDropZones = false;
pivotTable.Outline = false;
pivotTable.OutlineData = false;
pivotTable.ShowError = true;
pivotTable.ErrorCaption = "[error]";
pivotTable.ShowHeaders = true;
pivotTable.UseAutoFormatting = true;
pivotTable.ApplyWidthHeightFormats = true;
pivotTable.ShowDrill = true;
// Row field[s]
var descRowField = pivotTable.Fields["Description"];
pivotTable.RowFields.Add(descRowField);
// Column field[s]
var monthYrColField = pivotTable.Fields["MonthYr"];
pivotTable.ColumnFields.Add(monthYrColField);
// Data field[s]
var totQtyField = pivotTable.Fields["TotalQty"];
pivotTable.DataFields.Add(totQtyField);
var totPriceField = pivotTable.Fields["TotalPrice"];
pivotTable.DataFields.Add(totPriceField);
// Don't know how to calc these vals here, so had to put them on the data sheet
var avgPriceField = pivotTable.Fields["AvgPrice"];
pivotTable.DataFields.Add(avgPriceField);
var prcntgOfTotalField = pivotTable.Fields["PrcntgOfTotal"];
pivotTable.DataFields.Add(prcntgOfTotalField);
// TODO: Get the sorting (by sales, descending) working:
// These two lines don't seem that they would do so, but they do result in the items
// being sorted by (grand) total purchases descending
//var fld = ((PivotField)pvt.PivotFields("Description"));
//fld.AutoSort(2, "Total Purchases");
//int dataCnt = pivotTable.ra //DataBodyRange.Columns.Count + 1;
FormatPivotTable();
}
private void FormatPivotTable()
{
int HEADER_ROW = 7;
if (DateTimeFormatInfo.CurrentInfo != null)
pivotTableWorksheet.Column(2).Style.Numberformat.Format =
DateTimeFormatInfo.CurrentInfo.YearMonthPattern;
// Pivot Table Header Row - bold and increase height
using (var headerRowFirstCell = pivotTableWorksheet.Cells[HEADER_ROW, 1])
{
headerRowFirstCell.Style.VerticalAlignment = ExcelVerticalAlignment.Center;
headerRowFirstCell.Style.Font.Bold = true;
headerRowFirstCell.Style.Font.Size = 12;
pivotTableWorksheet.Row(HEADER_ROW).Height = 25;
}
ColorizeContractItemBlocks(contractItemDescs);
// TODO: Why is the hiding not working?
HideItemsWithFewerThan1PercentOfSales();
}
You can use the build-in Date format YearMonthPattern. which would give september 2016 as format.
pivotTableWorksheet.Column(2).Style.Numberformat.Format = DateTimeFormatInfo.CurrentInfo.YearMonthPattern;
If you really want MMM yy as pattern, you need to overwrite the culture format:
Thread.CurrentThread.CurrentCulture = new CultureInfo("nl-NL")
{
DateTimeFormat = { YearMonthPattern = "MMM yy" }
};
pivotTableWorksheet.Column(2).Style.Numberformat.Format = DateTimeFormatInfo.CurrentInfo.YearMonthPattern;
It doesn't seem that you can set the format on the field itself. You have to access through the pivot table object:
pivotTable.DataFields[0].Format = "MMM yy";
Any formatting applied to the underlying worksheet seems to be completely ignored.

How can I incorporate a PivotTable right into the source data on the sheet (using EPPlus)?

I've been able to create a PivotTable separate from the raw/source data, but now I want to combine the two, with the PivotTable allowing filtering of the spreadsheet data by providing filters on the column heading row, like this:
I tried this code:
private void AddPivotTable()
{
// The commented-out code below placess the PivotTable below the actual data, separate from it:
//string colAlphaRowNum = string.Format("A{0}", locationWorksheet.Dimension.End.Row+5);
// Here I am attempting to incorporate the PivotTable within the data itself (one row above it, actually)
string colAlphaRowNum = "A5";
ExcelAddressBase eab = locationWorksheet.Cells[colAlphaRowNum];
ExcelRangeBase erb = locationWorksheet.Cells[6, 1, locationWorksheet.Dimension.End.Row, locationWorksheet.Dimension.End.Column];
var pt = locationWorksheet.PivotTables.Add(eab, erb, "Pivotous");
pt.RowFields.Add(pt.Fields[0]);
pt.RowFields.Add(pt.Fields[1]);
pt.RowFields.Add(pt.Fields[2]);
pt.RowFields.Add(pt.Fields[3]);
pt.RowFields.Add(pt.Fields[4]);
pt.RowFields.Add(pt.Fields[5]);
pt.MultipleFieldFilters = true;
pt.RowGrandTotals = true;
pt.ColumGrandTotals = true;
pt.Compact = true;
pt.CompactData = true;
pt.GridDropZones = false;
pt.Outline = false;
pt.OutlineData = false;
pt.ShowError = true;
pt.ErrorCaption = "[error]";
pt.ShowHeaders = true;
pt.UseAutoFormatting = true;
pt.ApplyWidthHeightFormats = true;
pt.ShowDrill = true;
pt.DataOnRows = false;
pt.FirstHeaderRow = 1; // first row has headers
pt.FirstDataCol = 1; // first col of data
pt.FirstDataRow = 2; // first row of data
pt.TableStyle = TableStyles.Medium6; // There is a "custom" and several Dark, Light, and Medium options
}
...but this does not work. I get this dialog when I open the generated sheet:
If I select "Yes" this is what I see:
If I select "No", I see this:
...which is promising, but if I then drop down the "Row Labels", deselect the "(Select All)" and then select the first item ("Stern"), I see this:
This is not what I want; in the model (hand-crafted) sheet, deselecting "Select All" and then selecting a single item filters the data to just include that data ("Foster" in this case), like so:
...rather than replacing the first part of the data with a restricted PivotTable.
What do I need to do to make this work as intended?
Perhaps my nomenclature was faulty, because I think what I really want is not necessarily a PivotTable, but the ability to filter.
And, although attempting to do it this way, which seems logical and is even theoretically correct:
using (var shortNameCell = locationWorksheet.Cells[rowToPop, SHORTNAME_BYDCBYLOC_COL])
{
shortNameCell.Value = "Short Name";
shortNameCell.Style.WrapText = false;
shortNameCell.Style.Font.Size = 12;
shortNameCell.AutoFilter = true;
}
using (var companyNameCell = locationWorksheet.Cells[rowToPop, COMPANYNAME_BYDCBYLOC_COL])
{
. . .
companyNameCell.AutoFilter = true;
}
using (var reasonDescCell = locationWorksheet.Cells[rowToPop, REASONDESC_BYDCBYLOC_COL])
{
. . .
reasonDescCell.AutoFilter = true;
}
using (var transTypeCell = locationWorksheet.Cells[rowToPop, TRANSTYPE_BYDCBYLOC_COL])
{
. . .
transTypeCell.AutoFilter = true;
}
...results in only the final column thus appointed to sport filtration abilities, the following works for all four:
locationWorksheet.Cells["A6:D6"].AutoFilter = true;
Using the last, I get the following:
UPDATE
It was a Pivot Table that I needed after all, and what I did to get a start on how to accomplish what I need is shown in my auto-answer here.

export HTML input type "text" to a specific excel speadsheat starting on the next available line

I have an HTML code that I would like to use to send text data to a specific excel spread sheet starting on the next available line and starting with column B. I have a code that opens a new excel spreadseet every time and sends data like it should. I want to modify the code to go to a specific spread sheet and keep adding additional data to the same sheet.
Here is the code that I have so far:
<script>
function ToExcel(){
if (window.ActiveXObject){
var xlApp = new ActiveXObject("Excel.Application");
var xlBook = xlApp.Workbooks.Add();
var table=document.getElementById('inner_table')
//var tableCells=document.getElementById('inner_table').cells
var tableRows=document.getElementById('inner_table').rows
xlBook.worksheets("Sheet1").activate;
var XlSheet = xlBook.activeSheet;
xlApp.visible = true;
var xlRow = 1;
var xlCol = 1;
var R=0;
while(tableRows[R] != null)
{
var tableCells =tableRows[R].cells
var C = 0;
xlCol=1;
while(tableCells[C] != null)
{
XlSheet.cells(xlRow, xlCol).value = tableCells[C].childNodes[1].value;
xlCol++;
C++;
}
xlRow++;
R++;
}
XlSheet.rows.autofit;
XlSheet.columns.autofit;
}
}
</script>
Thanks for any help
You can get the row number for the first empty row on the sheet (looking from the bottom of the sheet up) using something like:
var xlRow = XlSheet.cells(XlSheet.Rows.Count, 1).End(-4162).Row+1 // -4162==xlUp

Resources