How to update the source data range for existing chart - excel

I'm trying to write a script that finds data in a sheet dynamically (the dimensions of the table need to be flexible in both axis) and then updates the source data range for an existing chart on another sheet (so that my users don't need to set up the styling themselves).
Below is my script so far. Everything works apart from the final line where Excel Online gives me the error:
"Line 10: Chart setData: You cannot perform the requested operation"
function main(workbook: ExcelScript.Workbook)
{
let selectedSheet = workbook.getWorksheet("Enter data in this sheet");
// Add a new table at used range on selectedSheet
let range = selectedSheet.getUsedRange();
if(selectedSheet.getTables().length == 0)
{
let newTable = workbook.addTable(range, true);
}
workbook.getWorksheet("The Chart").getChart("Chart 1").setData(range);
}
The worksheet names are correct and so is the chart name as far as I can see:
screenshot of excel online showing chart and worksheet names

Answer found; the chart was on a protected sheet which did not allow editing of objects. Updating the protection to allow all users to edit objects has resolved the issue.

Related

Excel Office Script not clearing cells. Getting unreachable code detected (7027) error

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 };

Excel typescript update chart data series

I have created an office script that does some operations on excel data and creates a table. The data of this table is the input for a chart. The chart is already existing in the Excel file.
Now I need to update the data range of the chart manually whenever new items are added to the table, but I want to do this automated ofcourse.
I was not able to find any documentation on this. In VBA I can update data ranges of a chart and I tried to port that to the office script, but with no luck.
in VBA it is like this:
ActiveChart.FullSeriesCollection(1).XValues = "='summary and graph'!$A$2:$A$42"
ActiveChart.FullSeriesCollection(1).Values = "='summary and graph'!$B$2:$B$42"
ActiveChart.FullSeriesCollection(2).Values = "='summary and graph'!$C$2:$C$42"
What would be a way to do this in excel office script? What would the syntax be?
Thanks, Joris
Here is the code you get when you do the recording to create a chart for the table
function main(workbook: ExcelScript.Workbook) {
let selectedSheet = workbook.getActiveWorksheet();
let table1 = workbook.getTable("Table1");
// Insert chart on sheet selectedSheet with source data from table1
let chart_5 = selectedSheet.addChart(ExcelScript.ChartType.columnClustered, table1.getRange());
}
You can change the chart source data using the setData method.
You can also get the chart series collection using the getSeries method, and set Values for each series using the setValues method. Example code could be -
let seriesCollection = chart_5.getSeries();
let range = workbook.getWorksheet("summary and graph").getRange("B2:B42");
seriesCollection[0].setValues(range);
range = workbook.getWorksheet("summary and graph").getRange("C2:C42");
seriesCollection[1].setValues(range);

How do you convert a dynamic range into a table using Excel Scripts?

I am new to using excel scripts with power automate. Trying to convert some data to a table. The thing is the number of rows will differ each time.
I've done this in excel desktop, but not sure how to do it using an excel script.
The problem is finding the used range in excel(Office Scripts). Once you have it, i assume you know how to convert it to table.
function main(workbook: ExcelScript.Workbook)
{
// Get the current, active worksheet.
let currentWorksheet = workbook.getActiveWorksheet();
// Get the range containing all the cells with data or formatting.
let usedRange = currentWorksheet.getUsedRange();
// Log the range's address to the console.
console.log(usedRange.getAddress());
}
Link for your reference
From:
https://learn.microsoft.com/en-us/office/dev/scripts/resources/samples/excel-samples
function main(workbook: ExcelScript.Workbook) {
// Get the current worksheet.
let selectedSheet = workbook.getActiveWorksheet();
// Create a table with the used cells.
let usedRange = selectedSheet.getUsedRange();
let newTable = selectedSheet.addTable(usedRange, true);
// Sort the table using the first column.
newTable.getSort().apply([{ key: 0, ascending: true }]);
}

get row from range in current worksheet?

I can not get tables name in active worksheet. I have a drop-down that will be populated with worksheets in workbook. I have another drop-down that should get all columns names(header) in selected worksheets. Somehow range.address has "sheet1!2:2" .
Here is code that I used:
function getRow(worksheetName) {
Excel.run(function (ctx) {
// Queue a command to write the sample data to the worksheet
// at moment i have only one worksheet named "Sheet1"
var range = ctx.workbook.worksheets.getItem(worksheetName).getRange().getRow(1);
range.load('address');
// Run the queued-up commands, and return a promise to indicate task
//completion
return ctx.sync().then(function () {
console.log(range.address); // prints Sheet1!2:2
})
})
.catch(errorHandler);
}
Here is a link to spreadsheet that I used for testing.
Any clue what i am doing wrong here?
I'd suggest that you replace getRange() with getUsedRange() instead, as shown here:
function getRow(worksheetName) {
Excel.run(function (ctx) {
var range = ctx.workbook.worksheets.getItem(worksheetName).getUsedRange().getRow(1);
range.load('address');
return ctx.sync().then(function () {
console.log(range.address);
})
})
.catch(errorHandler);
}
Rick Kirkham's comment above is correct. In the file that you've linked to, there is no table object -- although the worksheet does contain several rows/columns of data, that data is not explicitly contained inside a table.
Are you able to manually manipulate this file? If yes, then you can create a table object for the data by doing the following:
Select the data you want to be in the table.
With that data selected, choose the Table button (on the Insert tab).
Verify inputs in the Create Table prompt and choose OK.
If you are not able to manually manipulate this file, then you can create the table (from the range of data in your worksheet) by using the Office JavaScript API, as described here: https://dev.office.com/docs/add-ins/excel/excel-add-ins-tables#convert-a-range-to-a-table.

Hidden Cells still showing in an OfficeWriter Excel Spreadsheet

When my Office Writer Excel report opens, it randomly un-hides some of the hidden cells and columns. I have verified that it is not the data that causes the columns or cells to not be hidden. Has anyone experienced this before and is there a way to make sure that all columns or cells stay hidden when the excel file is opened?
I work for SoftArtisans. We have not had any other reports of programmatically hidden columns becoming visible in the output file. We also have not been able to reproduce the behavior you are reporting. It would be helpful to see a code snippet, as well as to know which version of OfficeWriter you are using and which version of Excel is being used to open the output file.
There are two ways to hide columns with our API, both using the ColumnProperties object. You can set the hidden property to true or set the width property to zero. You could do both if you like, although that shouldn't be necessary.
For example:
ExcelApplication xla = new ExcelApplication();
Workbook wb = xla.Create(ExcelApplication.FileFormat.Xlsx);
//or if opening an existing workbook
//Workbook wb = xla.Open(inputFilePath);
//Get a handle on the worksheet
Worksheet ws = wb.Worksheets[0];
//Write a value to a cell
ws.Cells[0, 9].Value = "Hidden Value";
//Get a handle on the column you want to hide
ColumnProperties colProps = ws.GetColumnProperties(9);
//set the column to hidden
colProps.Hidden = true;
//or set the column width to zero
colProps.Width = 0;
//Stream the output file to the response
xla.Save(wb, Page.Response, "HiddenColumnTest.xlsx", false);

Resources