How to Clear Table Style in Office Scripts? - excel

How can I clear the styles on a table? I tried recording the macro but when I record it and run it, it will say failed (Table setPredefinedTableStyle: The argument is invalid or missing or has an incorrect format.).
function main(workbook: ExcelScript.Workbook) {
let selectedSheet = workbook.getActiveWorksheet();
let mainTable = selectedSheet.getTable("MainTable");
mainTable.setPredefinedTableStyle("undefined");
}
How can I clear the table style?
https://learn.microsoft.com/en-us/javascript/api/office-scripts/excelscript/excelscript.table?view=office-scripts#setpredefinedtablestyle-predefinedtablestyle-

Excel tables in web always has a style. There isn't a way to clear all styles.
There doesn't appear to be a way to assign the "none" style, which is the most basic style. I'll follow-up on that.
The closest I can get to was to use TableStyleLight1 style as shown below.
function main(workbook: ExcelScript.Workbook) {
let selectedSheet = workbook.getActiveWorksheet();
let mainTable = selectedSheet.getTable("MainTable");
mainTable.setPredefinedTableStyle('TableStyleLight1')
}

Related

OfficeScripts to delete visible rows after filtering

Good Day!!
Have a data dump that comes from one of my systems into excel. The size of the data can vary from 200 rows to 250,000 rows. So to avoid some load restrictions, I have found the best way to manipulate/clean this data is avoid creating a table, and to use Excel's built-in filters, and one by one, filter to make the data to be deleted visible...then delete it. Works perfectly!
However, this issue is, the row counts are always different. When I have true ranges defined, the script runs perfectly (A2:L20000). However, when I attempt to define a usedRange, it gives me an error noting the argument is invalid. I can not figure out how to overcome this.
this errors out on the 10th line selectedSheet.getRange(usedRange).delete(ExcelScript.DeleteShiftDirection.up); which is the same as the 16th line, so I am guessing that will error out also.
Here is the snippet of the code.
Any help or guidance would be appreciated!
function main(workbook: ExcelScript.Workbook) {
let selectedSheet = workbook.getActiveWorksheet();
let usedRange = selectedSheet.getUsedRange();
console.log(usedRange);
// Toggle auto filter on selectedSheet
selectedSheet.getAutoFilter().apply(selectedSheet.getRange("A1:L1"));
// Apply values filter on selectedSheet
selectedSheet.getAutoFilter().apply(selectedSheet.getAutoFilter().getRange(), 10, { filterOn: ExcelScript.FilterOn.values, values: ["0"] });
// Delete visable on selectedSheet
selectedSheet.getRange(usedRange).delete(ExcelScript.DeleteShiftDirection.up);
// Clear auto filter on selectedSheet
selectedSheet.getAutoFilter().clearCriteria();
// Apply values filter on selectedSheet
selectedSheet.getAutoFilter().apply(selectedSheet.getAutoFilter().getRange(), 6, { filterOn: ExcelScript.FilterOn.values, values: ["Expense", "Income"] });
// Delete range visable on selectedSheet
selectedSheet.getRange(usedRange).delete(ExcelScript.DeleteShiftDirection.up);
// Clear auto filter on selectedSheet
selectedSheet.getAutoFilter().clearCriteria();
To answer your question, the reason UsedRange doesn't work here is because selectedSheet.getRange() expects a string argument. The string argument is the range's address.
To get around this you could write something like selectedSheet.getRange(usedRange.getAddress()).delete(ExcelScript.DeleteShiftDirection.up); But the deletion won't work with the usedRange() this way.
I added a function I wrote to help with deletion. And I substituted your lines of code where you delete with function calls to this new functions. You can try the code below and see if it works:
function main(workbook: ExcelScript.Workbook) {
let selectedSheet = workbook.getActiveWorksheet();
let usedRange = selectedSheet.getUsedRange();
console.log(usedRange);
// Toggle auto filter on selectedSheet
selectedSheet.getAutoFilter().apply(selectedSheet.getRange("A1:L1"));
// Apply values filter on selectedSheet
selectedSheet.getAutoFilter().apply(selectedSheet.getAutoFilter().getRange(), 10, { filterOn: ExcelScript.FilterOn.values, values: ["0"] });
// Delete visable on selectedSheet
deleteFilteredRange(workbook)
// Clear auto filter on selectedSheet
selectedSheet.getAutoFilter().clearCriteria();
// Apply values filter on selectedSheet
selectedSheet.getAutoFilter().apply(selectedSheet.getAutoFilter().getRange(), 6, { filterOn: ExcelScript.FilterOn.values, values: ["Expense", "Income"] });
// Delete range visable on selectedSheet
deleteFilteredRange(workbook)
// Clear auto filter on selectedSheet
selectedSheet.getAutoFilter().clearCriteria();
}
function deleteFilteredRange(workbook: ExcelScript.Workbook) {
let selectedSheet = workbook.getActiveWorksheet();
let startRow = 2 //Two would be the second row after the header row range.
let lastRow = selectedSheet.getRange("A1048576").getExtendedRange(ExcelScript.KeyboardDirection.up).getRowIndex() + 1
selectedSheet.getRange(`${startRow}:${lastRow}`).delete(ExcelScript.DeleteShiftDirection.up)
}
This script may not work if your dataset is too large however.

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

addChart not working how "Record Actions" recorded it

I used the "Record Actions" in the Automate tab to record myself creating a chart. The Chart looks exactly how I want it to look after recording.
function main(workbook: ExcelScript.Workbook) {
let selectedSheet = workbook.getActiveWorksheet();
// Insert chart on sheet selectedSheet
let chart_24 = selectedSheet.addChart(ExcelScript.ChartType.pie, selectedSheet.getRange("A6:B7"));
}
I changed up the code a little bit so it could work when I call this Script from Power Automate.
function main(workbook: ExcelScript.Workbook) {
let sheet = workbook.getWorksheet("Dashboard");
let rng = sheet.getRange("A6:B7");
let chart_10 = sheet.addChart(ExcelScript.ChartType.pie, rng);
}
However, when I run either code above without having the data selected on the sheet, it is now giving me a bad chart like below.
This just started happening to me. I had the code working fine for me for about two months but now it is giving me the bad graph.
After testing the code, I noticed it only works when you have the data selected and the sheet open. When you run it in Power Automate ( where you can't use select() ) it will always give me the bad graph now. Ever since March 25, 2021, I have been getting the bad graph. Prior to this date, my code ran perfectly fine. How can I use a range without having to use select() so I can run it in Power Automate?
This is because the row and column used by pie chart are wrongly switched. You can try to click the "Switch Row/Column" button under "Chart" tab when selecting the chart to see the result.
As a workaround for Power Automate, you can use
function main(workbook: ExcelScript.Workbook) {
let sheet = workbook.getWorksheet("Sheet2");
let rng = sheet.getRange("A1:B2");
// 3rd parameter will help avoid this bug.
let chart_10 = sheet.addChart(ExcelScript.ChartType.pie, rng, ExcelScript.ChartSeriesBy.columns);
}

Protect Worksheet in Office Scripts with Options

How can I protect a worksheet but allow the user to format the columns in Office Scripts? I have tried a few things but haven't had any success.
function main(workbook: ExcelScript.Workbook) {
let sheet = workbook.getWorksheet("By Item");
sheet.getProtection().protect(ExcelScript.WorksheetProtectionOptions.allowFormatColumns);
}
Please see the attached link
https://learn.microsoft.com/en-us/javascript/api/office-scripts/excelscript/excelscript.worksheetprotection?view=office-scripts#protect-options--password-
The protect() method takes an object as argument for the 1st argument. See below.
I noticed that cell background/fill doesn't work even with this setting. All other formatting works such as font color, border, etc. That may be a bug that we'll follow-up on.
function main(workbook: ExcelScript.Workbook) {
let sheet = workbook.getWorksheet("By Item");
sheet.getProtection().unprotect();
sheet.getProtection().protect({
allowFormatCells: true
});
}

How to handle event on data change in excel sheet to refresh all pivot tables?

I have a VBA code applied to Worksheet and its change. So whenever there is new entry or deletion (any change) in the sheet, it refresh all the pivot tables attached to it -
Private Sub Worksheet_Change(ByVal Target As Range)
ThisWorkbook.RefreshAll
End Sub
( I am not very familiar with the VBA or office script code, so sorry for basic question.)
But this does not work on excel online. Hence i need a code to use in excel online code editor (or typescript). So Far, I am able to write this code -
async function main(workbook: ExcelScript.Workbook) {
await Excel.run(async (context) => {
console.log("Adding Sheet OnChange Handler");
let mysheet = context.workbook.worksheets.getItem("Attendance");
mysheet.onChanged.add(ref);
await context.sync();
console.log("Added a worksheet-level data-changed event handler.");
}
)};
function ref(workbook: ExcelScript.Workbook) {
let selectedsheet = workbook.getActiveWorksheet();
selectedsheet.refreshAllPivotTables();
console.log("Pivot Refreshed.");
};
I am getting an error Cannot find name 'Excel' and it should work whenever there is any change in the worksheet which is not the case. Please help me with this.
Thanks.
I think you are missing the () at the end of the refreshAllPivotTables method.
Please try this -
function main(workbook: ExcelScript.Workbook) {
workbook.refreshAllPivotTables(); // Refresh all pivot tables
}
As replied by #Daniel G. Wilson , it is not possible in script right now. So I used the Power Automate approach.
I wrote the script in my code editor and saved it-
function main(workbook: ExcelScript.Workbook) {
let selectedsheet = workbook.getWorksheet("Pivot");
selectedsheet.refreshAllPivotTables();
console.log("Pivot Refreshed");
};
Then I created a Scheduled flow in Power Automate. Steps are -
Create new Scheduled flow.
Give some name.
Set the starting time and the interval to run it automatically.
Select new step.
Select Excel Online Business.
Select Run a Script.
Choose file location and Script name.
Save and test the flow.
It works fine. Thanks.

Resources