Forum Discussion
Adjust Excel Office Script for Other Sheets / Variable Data
- Apr 12, 2024
Not sure I understood correctly the logic of what you do, as variant
function main(workbook: ExcelScript.Workbook) { const sheets = workbook .getWorksheets() for( let sheet of sheets) { sheet .getRange("A:A") .insert(ExcelScript.InsertShiftDirection.right) sheet .getRange("A3") .setValue("New Col Header") sheet .getRange("A4") .copyFrom(sheet.getRange("B1"), ExcelScript.RangeCopyType.all, false, false) let range = sheet .getRange("B3:B10000") .getUsedRange() let nRows = range.getRowCount() let target = sheet.getRange("A4") target .getOffsetRange(1,0) .getResizedRange(nRows-3,0) .copyFrom(target, ExcelScript.RangeCopyType.values) workbook .addTable( sheet .getRange("A3:D3") .getResizedRange(nRows-1,0) , true) .setPredefinedTableStyle("TableStyleLight8") } }
Sorry. I just meant a script that could be used on other sheets, and those sheets would have a variable amount of data in what became the table at the end.
Mainly, it was these two lines that I needed help with:
selectedSheet.getRange("A4").autoFill("A4:A8", ExcelScript.AutoFillType.fillCopy);
let table1 = workbook.addTable(selectedSheet.getRange("A3:D8"), true);
Instead of A4:A8 and A3:D8, I need both of those to go to the bottom of the data, which will be anywhere from 1-n rows long.
I didn't really need the loop, but it was good to learn. I also very much appreciate the effort you put into this. I think I understand most of it, and will continue to study it, but I don't think this is what I need because it appears to assume that every future sheet has at least 3 rows.
Also curious if it is really necessary to get 10,000 rows like you did?
Funny I think the script is exactly what you need?
I assume your original data looks like below:
That is, header is in A3:C3; table name is in A1. Data is from Row4 to the bottom right.
After running the script, I got below. that is not what you are looking for???
- Scott4850Apr 13, 2024Copper Contributor
Actually, you are correct, it does work. My misunderstanding (and yes, I should have run it before responding!!!).
I still don't understand the seemingly arbitrary (and prone to breaking?) selection of 10,000 rows. And, well, I'm surprised that changing something like A3:D8 to A3:D<end of data> requires so much code.
Lots more to learn, I guess. Thanks!
- SergeiBaklanApr 13, 2024Diamond Contributor
As for the size of the code. Changing of
.getRange("A3:D8")on
.getRange("A3:D3") .getResizedRange(nRows-1,0)adds not a lot of code. However, we need some additional code to calculate number of rows in target range.
- Scott4850Apr 13, 2024Copper ContributorThanks so much for all your help!
- SergeiBaklanApr 13, 2024Diamond Contributor
10000 rows are taken with the gap, we may take entire range starting from A3 till end of the column, doesn't matter. Size shall be more than possible range with actual data. Since on next step we use .getUsedRange() and it is cut initial range with 10000 rows to the range with actual data only. Other words from A3 till last not-blank cell.
Next into nRows we return the number of the rows in the range with actual data. Instead of taking A3:D8 we take only the range with headers A3:D3 and resize it down on number of rows in actual data.
Here is the script with comments
function main(workbook: ExcelScript.Workbook) { // get array of all worksheets in the workbook const sheets = workbook.getWorksheets() for( let sheet of sheets) { // iterate sheets // insert empty first column moving all data to the right sheet .getRange("A:A") .insert(ExcelScript.InsertShiftDirection.right) // set value into A3 of new column // we assume headers are always in third row sheet .getRange("A3") .setValue("New Col Header") // define first cell for the data in first column let target = sheet.getRange("A4") // set value into the first data cell in first column of future table target .copyFrom(sheet.getRange("B1"), ExcelScript.RangeCopyType.all, false, false) let range = sheet .getRange("B3:B10000") // Initial data starts from B3 and we take // the range with the gap, assuming // it's not more than 100000 rows in source data. // Could be change on any other value .getUsedRange() // from above get range only with actual data, // thus blank cells are cut. // Resulting range has the size of actual data // in source // get number of rows in source data let nRows = range.getRowCount() // fill value in A4 till end of the first column target .getOffsetRange(1,0) // shift the range down on one cell // actulally that's A5 .getResizedRange(nRows-3,0) // resize the range, // now it starts from A5 till end of data .copyFrom(target, ExcelScript.RangeCopyType.values) // copy data from A4 to every cell of // first colmn range workbook .addTable( sheet .getRange("A3:D3") // set range with headers // we assume number of columns is fixed and // the same for all sheets // if not that shall be adjusted .getResizedRange(nRows-1,0) // expand range till end of data , true) .setPredefinedTableStyle("TableStyleLight8") // set table style } }Thanks rachel for the sample and test.