I was trying to use this Microsoft tutorial Excel Chart Add-in - Javascript API
In the first example, it has the code
Excel.run(function (context) {
var sheet = context.workbook.worksheets.getItem("Sample");
var dataRange = sheet.getRange("A1:B13");
var chart = sheet.charts.add("Line", dataRange, "auto");
chart.title.text = "Sales Data";
chart.legend.position = "right"
chart.legend.format.fill.setSolidColor("white");
chart.dataLabels.format.font.size = 15;
chart.dataLabels.format.font.color = "black";
return context.sync();
}).catch(errorHandlerFunction);
If I run the code example I receive 2 errors. One that it cannot find excel from
Excel.run
And the errorhandler function is not defined, which appears to be correct.
Are these typos in new Microsoft documents? If not what have I got to change?
Version: excel 365 online build 16.0.13615.35052
2 things that you need to make sure you have in order to run this code succesfully.
Please add the errorHandlerFunction this could be be as easy as this:
function errorHandlerFunction(e ){
console.log("exception" + e );
}
Make sure you have a worksheet named "Sample". Make sure its exactly that name without trailing blank spaces.
Related
I have this script which works all except for the clearing of the B4:B120 area "// Clear the "Margin Updates" column." section which is greyed out for some reason):
function main(workbook: ExcelScript.Workbook): ReportImages {
// Recalculate the workbook to ensure all tables and charts are updated.
workbook.getApplication().calculate(ExcelScript.CalculationType.full);
// Get the data from the "Target Margins - FHM" table. (name of Excel tab, not name of table)
let sheet1 = workbook.getWorksheet("Sheet1");
const table = workbook.getWorksheet('Target Margins - FHM').getTables()[0];
const rows = table.getRange().getTexts();
// Get only the Product Type and "Margin Update" columns, then remove the "Total" row.
const selectColumns = rows.map((row) => {
return [row[0], row[1]];
});
// Delete the "ChartSheet" worksheet if it's present, then recreate it.
workbook.getWorksheet('ChartSheet')?.delete();
const chartSheet = workbook.addWorksheet('ChartSheet');
// Add the selected data to the new worksheet.
const targetRange = chartSheet.getRange('A1').getResizedRange(selectColumns.length - 1, selectColumns[0].length - 1);
targetRange.setValues(selectColumns);
// Get images of the chart and table, then return them for a Power Automate flow.
const tableImage = table.getRange().getImage();
return { tableImage };
// Clear the "Margin Updates" column.
const targetSheet = workbook.getActiveWorksheet();
const getRange = targetSheet.getRange("B4:B120");
getRange.clear(ExcelScript.ClearApplyTo.contents);`
}
// The interface for table and chart images.
interface ReportImages {
tableImage: string
}
The code copies the data in sections of the A and B columns (which constitute a table) and sends an email via Power Automate flow. Unfortunately, I need the section of the B column to be clear of values (not formatting or style) after which this flow is not doing.
I'd greatly appreciate help with this problem.
Thank you.
#cybernetic. nomad:
When I try using Range ("B4:B120").Clear I receive
unreachable code detected (7027)
and
and "cannot find name 'Range' (2304)
Office Script Range Clear Error
In JavaScript, the function exits as soon as the return keyword is evaluated. That's why it's saying your code is unreachable. So you have to restructure your code so that the return happens at the end. So you can update your code to look something like this:
// Clear the "Margin Updates" column.
const targetSheet = workbook.getActiveWorksheet();
const getRange = targetSheet.getRange("B4:B120");
getRange.clear(ExcelScript.ClearApplyTo.contents);
return { tableImage };
I cobbled together some JavaScript to label the last point of each series in a chart (see below). This is a simplified version of a much-used function in a VBA add-in.
I used let mychart = mysheet.charts.getItemAt(0); to specify that the code should run on the first chart object on the worksheet. It would be more useful to run the code on the chart selected by the user.
How do I identify which chart the user has selected (ActiveChart in VBA-speak)?
Similarly I used for (var iseries = 0; iseries < nseries; iseries++) to run the code on all series in the chart. It would be more useful to run the code on the specific series selected by the user.
How do I identify which series in the chart has been selected by the user (related to TypeName(Selection) in VBA)?
Here is my Office-JS code:
$("#run").click(() => tryCatch(labelLastPoint));
//$("#label-last-point").click(labelLastPoint);
async function labelLastPoint() {
await Excel.run(async (context) => {
let mysheet = context.workbook.worksheets.getActiveWorksheet();
let mychart = mysheet.charts.getItemAt(0);
let seriescollection = mychart.series;
seriescollection.load("count");
await context.sync();
console.log("Number of Series: " + seriescollection.count);
let nseries = seriescollection.count;
for (var iseries = 0; iseries < nseries; iseries++) {
console.log("- Series Number " + iseries);
let myseries = seriescollection.getItemAt(iseries);
let pointcollection = myseries.points;
pointcollection.load("count");
await context.sync();
let npoints = myseries.points.count;
let mypoint = myseries.points.getItemAt(npoints - 1);
mypoint.hasDataLabel = true;
mypoint.dataLabel.showSeriesName = true;
mypoint.dataLabel.showValue = false;
}
});
}
As I understand it you're looking for API methods that might be called "getSelectedChart" and "getSelectedSeries". I'm afraid that there are no APIs in Office JS that do that. But it is a good idea. Please suggest that at Office Developer User Voice.
There is a getSelectedDataAsync method in the Shared Office JS APIs, but it does not support charts or series.
In the meantime, would it be possible in your scenario to have a drop down in the task pane, in which the user can specify, by title, the chart/series that is of interest?
i am having difficulties with open xml sdk:
i am trying to generate excel file with several columns that have numbers and i want to have total sum at the end
i have tried to Generate Table Definition Part Content and inside define every column (id, name etC). If column has true for TotalColumn, it adds code (rough example)
var column = new TableColumn{
id = 1,
name = "example",
TotalsRowFunction = TotalsRowFunctionValues.Sum,
TotalsRowFormula = new TotalsRowFormula("=SUBTOTAL(109;[" + rowName + "])")
};
I can't get it to work, when i open excel it reports error, but it doesn't explicitly says what the problem is... I tried with microsoft validator but can't figure anything out...
I'd appreciate any help / example code since i can't google anything out
EDIT:
i use this at the end:
workbookPart.Workbook.CalculationProperties.ForceFullCalculation = true;
workbookPart.Workbook.CalculationProperties.FullCalculationOnLoad = true;
Why not use a cell formula?
E.g.
cell.DataType = new EnumValue<CellValues>(CellValues.Number);
cell.CellFormula = new CellFormula(string.Format("=SUBTOTAL({0};[{1}])", "109", rowName));
//This will force a full recalculation of all the cells
workbookPart.Workbook.CalculationProperties.ForceFullCalculation = true;
workbookPart.Workbook.CalculationProperties.FullCalculationOnLoad = true;
I ended using EPPlus for this as it seems to be working simple and efficient
I have a spreadsheet that has information entered by multiple people on multiple devices and different font settings. I would like a simple script to change all pages of the spreadsheet, (3 on test but actually 5 pages on original). Preferably on any edit, but when you switch from page to page within the sheet would be fine.
Here is link to spreadsheet:-
https://docs.google.com/spreadsheets/d/1hUSgX4Teg71sgI6AUlxgY7HCatUTAszP3M4f6o_eyMU/edit?usp=sharing
My script below:-
function onOpen() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets();
var cell = sheet.getRange("C6:P26");
cell.setFontSize(12);
cell.setHorizontalAlignment("center");
}
I have tried onEdit too but still not working but debugger is not throwing up errors just not running. Not sure if it is the Range option as it doesn't select the correct area in each sheet, should I make 1 per sheet?
Here is the working code after many tries.
function onEdit() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheets();
var cell = ss.getRange("C6:U39");
cell.setFontSize(12);
cell.setHorizontalAlignment("center");
}
Since there is no way to cancel the changes made by an add-in, we need to provide users with backup options.
The current version of JavaScript API for Excel doesn't have a method for copying a sheet with its data and formatting.
Does anyone know of any workarounds or plans for adding such method?
There are indeed currently no way easy way of duplicating a worksheet and so feel free to request it on the Office Extensibility Platform's UserVoice. While such an API may be coming in the future, you could in the meantime add a new worksheet using worksheetCollection.add(), grab a worksheet's used range using the worksheet.getUsedRange() method and copy its values to another sheet.
Your code would then look something like this :
function duplicateSheet(worksheetName) {
Excel.run(function(ctx) {
var worksheet = ctx.workbook.worksheets.getItem(worksheetName);
var range = worksheet.getUsedRange();
range.load("values", "address");
var newWorksheet = ctx.workbook.worksheets.add(worksheetName + " - Backup");
return ctx.sync().then(function() {
var newAddress = range.address.substring(range.address.indexof("!") + 1);
newWorksheet.getRange(newAddress).values = range.values;
}).then(ctx.sync);
});
}
Let me know how that works out for you.
Gabriel Royer - Developer on the Office Extensibility Team, MSFT