How to change DefaultFontSize for a gembox spreadsheet? - gembox-spreadsheet

Can anyone give me an example on how to change the font size for a sheet using Gembox software? I was able to change for a cell though but I want to change in entire sheet.
GemBoxHelp

UPDATE 2020-03-27
In latest versions of GemBox.Spreadsheet there are some additional API that simplify this task.
For instance, to set a default font size for the whole Excel file, you can use the following:
var file = ExcelFile.Load("In.xlsx");
file.Styles.Normal.Font.Size = 18 * 20;
file.Save("Out.xlsx");
Or if you want to explicitly specify the font size on each cell in the sheet, you can use the following:
var file = ExcelFile.Load("In.xlsx");
var sheet = file.Worksheets[0];
sheet.Cells.Style.Font.Size = 18 * 20;
file.Save("Out.xlsx");
ORIGINAL
If you have cells that do not have any font related settings (like color, name, size, etc.) applied to them directly then you can just change the cell style's font size, for example:
var file = ExcelFile.Load("In.xlsx");
int size = (int)LengthUnitConverter.Convert(18, LengthUnit.Point, LengthUnit.Twip);
file.Styles[BuiltInCellStyleName.Normal].Font.Size = size;
file.Save("Out.xlsx");
But in a case you do have some directly applied font settings then you will need to iterate through all the allocated cells and apply new size on them:
var file = ExcelFile.Load("In.xlsx");
var sheet = file.Worksheets.ActiveWorksheet;
int size = (int)LengthUnitConverter.Convert(18, LengthUnit.Point, LengthUnit.Twip);
foreach (var row in sheet.Rows)
foreach (var cell in row.AllocatedCells)
cell.Style.Font.Size = size;
file.Save("Out.xlsx");
The above refers to the current latest version 3.7, but in the next version 3.9, which we are currently working on, this task is simplified like the following:
sheet.Cells.Style.Font.Size = size;

Related

How to extract few cells from a Google Sheet and copy to another sheet using a single statement

using JavaScript to access google sheets via google API.
I am copying the entire content of a "google spreadsheet" "Parent sheet" into a two dimension array vaParent
var ssParent = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Parent");
var vaParent = ssParent.getRange(2, 1, ssParent.getLastRow(), ssParent.getLastColumn() ).getValues();
I am extracting 6 array elements
var vaNewParent01 = vaParent[i].slice(3, 9);
Now, I would like to copy vaNewParent01 to a new google "spreadsheet" "company sheet"
ssCompany.getRange( 2, 1 ).setValues( vaNewParent01 );
above code does not work??
I've found that vaNewParent01 is a single dimension array with 6 elements
however, ssCompany.getRange( 2, 1 ).setValues( vaNewParent01
only works if vaNewParent01 is an array of array
question:
a/ how to extract few cells from a sheet and copy to another using a single statement.
thanks in advance for any help
cheers
From your showing script, if your script is like the following script,
var ssParent = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Parent");
var vaParent = ssParent.getRange(2, 1, ssParent.getLastRow(), ssParent.getLastColumn()).getValues();
for (var i = 0; i < vaParent.length; i++) {
var vaNewParent01 = vaParent[i].slice(3, 9);
ssCompany.getRange(2, 1).setValues(vaNewParent01);
}
vaNewParent01 is 1 dimensional array. In order to use setValues(values), values is required to be 2 dimensional array. And about ssCompany.getRange( 2, 1 ).setValues( vaNewParent01 );, in this case, please include the numbers of rows and columns of the values you want to put. If my understanding of your situation is correct, I think that the reason for your issue is due to this.
About how to extract few cells from a sheet and copy to another using a single statement., in this case, how about the following sample script?
Sample script 1:
This script is modified from your showing script by guessing your tested script.
var ss = SpreadsheetApp.getActiveSpreadsheet();
var ssParent = ss.getSheetByName("Parent");
var ssCompany = ss.getSheetByName("sample"); // Please set the destination sheet name.
var vaParent = ssParent.getRange(2, 1, ssParent.getLastRow(), ssParent.getLastColumn()).getValues();
var values = [];
for (var i = 0; i < vaParent.length; i++) {
var vaNewParent01 = vaParent[i].slice(3, 9);
values.push(vaNewParent01);
}
ssCompany.getRange(2, 1, values.length, values[0].length).setValues(values);
Sample script 2:
As other sample script, how about the following script? In this sample script, copyTo of Class Range is used. From your showing script, I thought that you wanted to copy the values from D2:I of the source sheet to A2 of the destination sheet.
var ss = SpreadsheetApp.getActiveSpreadsheet();
var ssParent = ss.getSheetByName("Parent");
var ssCompany = ss.getSheetByName("sample"); // Please set the destination sheet name.
var src = ssParent.getRange("D2:I" + ssParent.getLastRow());
src.copyTo(ssCompany.getRange(2, 1), { contentsOnly: true });
References:
setValues(values)
copyTo(destination, options)
arr is single dimension array
let vs = arr.map(e => [e]); //for a column;
let vs = [arr]; //for a row
Sheet.getRange(1,1,vs.length, vs[0].length).setValues(vs);

How to build multi-dimensional arrays in the appropriate orientation. (Rows/Cols in correct places)

I'm working on building a Google Sheets-based tool to calculate the cost of making various machined and fabricated parts. As it currently sits, there are about 60 different variables that I modify each time I build an estimate. Things like "number of parts," "length of bar to cut each part from," "cost/bar," "machining time," "machining rate," etc. All of these values I have populated on one sheet, and laid out in a way like. I want to make a button that takes a "snapshot" of all of these values, and stores them on another sheet for later reference. I'd then, ideally create another button, that allows me to re-populate all of the cells based off of a unique ID (such as Part #). This would let me tweak an estimate, or even refer back to material sizes etc in a meaningful way.
So far, I've created a "Named Range" for each of the values, so that as I change the layout, or add values, my script code should update accordingly, instead of using direct cell references.
I've built a few functions to get and set the value's of these named ranges. They're working as expected(i think) for what I'm trying to do. But when I try to place the array of Named Ranges inside of a multi-dimensional array of the named ranges WITH their respective values, I'm running into an issue where each named range is a ROW and their respective value is a second Column. And I need it swapped
I'm not super comfortable with multi-dimensional arrays and am thinking myself in circles trying to figure out how to transpose this logically. My gut says the way I'm attempting to build the arrays is my problem, not just how I'm iterating through them.
function saveCurrentValues(){
//set master spreadhseet
var ss = SpreadsheetApp.getActiveSpreadsheet();
//set calc and save sheets to vars
var calcSheet = ss.getSheetByName('Part Cost Calculator')
var saveSheet = ss.getSheetByName('Saved Parts');
//set named ranges from calcSheet to array
var namedRanges = calcSheet.getNamedRanges();
var savedValues = new Array();
//find next available row for save data (currently troubleshooting)
var nextAvailSaveRange = saveSheet.getRange(1, 1, 60, 2);
//iterate through array and call getNamedRange() function to return name and current value
for(i = 0; i < namedRanges.length; i++){
savedValues[i] = getNamedRange(namedRanges[i].getName());
}
nextAvailSaveRange.setValues(savedValues);
}
function getNamedRange(name){
var ss = SpreadsheetApp.getActiveSheet();
var value = ss.getRange(name).getValue();
Logger.log([name,value]);
return [name, value];
}
As you can see by how I had to temporarily format the nextAvailSaveRange, it needs 60 ROWS, and only two columns, because of how the array is constructed. I'd like to better understand how I'm creating this multi-dimensional array vertically instead of horizontally, and how to fix it!
Once this is done, I'd like to create headers that match the Named Ranges on my save sheet, to allow me to iterate through functions and look for a match to the appropriate column by name. That way if I add more values or change their order, or the order of the array, it wont matter. I think I'll be able to figure that out pretty easily if I can control these damn arrays better!
I agree with the OP. Array building AND iteration are the immediate problems and they are the stumbling block to the development of the spreadsheet.
The OP has a raised number of issues, however the most immediate, and the one to be resolved under this answer, is the copying of a list of parts from one sheet to another. In the OP's code, named ranges were retrieved and used as a basis for creating the copy of the list of parts. However, this also creates a duplicate set of named ranges on the target sheet. In my view this was unnecessarily complicating the duplication of the parts list since it is easy to programmatically create/update a list of named ranges.
The following code consists of three functions:
so_5466573501() - Copies the list of parts from one sheet to another.
Named Ranges are ignored; the OP's stumbling block is the iteration of the raw data and management of arrays. This code deals only with that aspect as a means of simplifying this issue.
createnamedranges() - Programmatically creates/updates Named ranges.
This code is included to assure the OP that it is not important to make named ranges the focus of the duplication by showing how easy it is to programmatically turn a list of parts into a series of Named Ranges (for development, I created 60 Parts and the entire code executes in under a 1 second). The code assumes a list in two columns (Column A = Parameter Name, Column B = Parameter value). The code loops through the list creating/updating a set of named ranges - the range name is the Parameter Name in Column A, and the range itself is the the corresponding row in Column B. The name of the sheet is set in a variable, so this function can be easily adapted.
deletenamedranges() - Programmatically deletes Named ranges.
This code deletes all the Named Ranges from a given sheet. This function is included because the OP's existing code creates duplicate named ranges, and it might be necessary to quickly delete them from a sheet. The sheet name is stored as a variable, so the function can be easily adapted.
function so_5466573501() {
//set master spreadsheet
var ss = SpreadsheetApp.getActiveSpreadsheet();
//create variables for calc and save sheets
var calcSheet = ss.getSheetByName('Part Cost Calculator')
var saveSheet = ss.getSheetByName('Saved Parts');
//get the Parts Parameters from Part Cost Calculator
//var namedRanges = calcSheet.getNamedRanges();
//Logger.log("DEBUG: Number of named ranges on Parts Cost Calculator = "+namedRanges.length);
// get the number of parts in the list on Parts Cost Calculator
var Avals = calcSheet.getRange("A1:A").getValues();
var Alast = Avals.filter(String).length;
//Logger.log("DEBUG: Number of parts in the list: "+Alast); //DEBUG
// get the parts list
var partsRange = calcSheet.getRange(1, 1, Alast, 2);
var partsRangeValues = partsRange.getValues();
//Logger.log("DEBUG: The parts range is: "+partsRange.getA1Notation());//DEBUG
//Logger.log("DEBUG: Parts List Row #1: Name: "+partsRangeValues[0][0]+", Value: "+partsRangeValues[0][1]);//DEBUG
// create an array to use for saving results and updating new Saved Parts sheet
var savedValues = new Array();
// Loop through the Parts List, row by row
for (i = 0; i < Alast; i++) {
// push the part name and part value onto the array
savedValues.push([partsRangeValues[i][0], partsRangeValues[i][1]]);
//Logger.log("DEBUG: Parts List: i = "+i+", Name: "+partsRangeValues[i][0]+", Value: "+partsRangeValues[i][1]);//DEBUG
}
// identify the range on the Saved Parts sheet to copy the parts list array.
var saveRange = saveSheet.getRange(1, 1, Alast, 2);
saveRange.setValues(savedValues);
}
function createnamedranges() {
//set master spreadhseet
var ss = SpreadsheetApp.getActiveSpreadsheet();
//create variables for calc and save sheets
var calcSheetName = "Part Cost Calculator";
var calcSheet = ss.getSheetByName(calcSheetName);
// get the number of parts in the list on Parts Cost Calculator
var AVals = calcSheet.getRange("A1:A").getValues();
var ALast = AVals.filter(String).length;
// get the parts range and values
var partsRange = calcSheet.getRange(1, 1, ALast, 2);
//Logger.log("DEBUG: The Parts range is "+partsRange.getA1Notation());//DEBUG
var partsRangeValues = partsRange.getValues();
// Loop through the parts list row by row
for (var i = 0; i < ALast; i++) {
// get the Part name and assign as the range name
var nrpartname = partsRangeValues[i][0];
//Logger.log("DEBUG: PartName = "+nrpartname+", value: "+partsRangeValues[i][1]);//DEBUG
// get the range to be named -note (i+1) because the loop starts at 0 (zero) but `getrange` starts at 1 (one)
var rng_to_name = ss.getSheetByName(calcSheetName).getRange((i + 1), 2);
//Logger.log("DEBUG: rng_to_name: "+rng_to_name+", range details: "+rng_to_name.getA1Notation());
// set (and/or update) the named range
ss.setNamedRange(nrpartname, rng_to_name);
// DEBUG: check that the range was created //DEBUG
// var rangeCheck = ss.getRangeByName(nrpartname);//DEBUG
// var rangeCheckName = rangeCheck.getA1Notation(); //DEBUG
// Logger.log("DEBUG: Rangename: "+nrpartname+", Range: "+rangeCheckName);//DEBUG
// credit megabyte1024 https://stackoverflow.com/a/12325103/1330560 "setNamedRange() outside of the spreadsheet container?"
}
}
function deletenamedranges() {
//set master spreadhseet
var ss = SpreadsheetApp.getActiveSpreadsheet();
//create variables for calc and save sheets
var calcSheet = ss.getSheetByName('Part Cost Calculator');
// get the named ranges
var namedRanges = calcSheet.getNamedRanges();
// loop through the list of named ranges and delete them
for (var i = 0; i < namedRanges.length; i++) {
namedRanges[i].remove();
}
}
ADDENDUM: - Copy based on Named Ranges
The original so_5466573501 assumes that the parts are in a simple 2 column-list; in which case, Named Ranges are irrelevant.
The following code assumes that the parts are not in a list but scattered, in no particular order, throughout the sheet "Part Cost Calculator". This code is based on obtaining the NamedRanges, identifying the respective Named Range row and column, correlating said row and column to the ENTIRE data range, and then copying the results to the "Saved Parts" sheet. No Named Ranges are created by default on the "Saved Parts" sheet but this can be easily done by using the createnamedranges function (appropriately edited for the correct sheet name).
function so_5466573502() {
//set master spreadhseet
var ss = SpreadsheetApp.getActiveSpreadsheet();
//create variables for calc and save sheets
var calcSheet = ss.getSheetByName('Part Cost Calculator')
var saveSheet = ss.getSheetByName('Saved Parts');
//get the Parts Parameters from Part Cost Calculator
var namedRanges = calcSheet.getNamedRanges();
var numNR = namedRanges.length
//Logger.log("DEBUG: Number of named ranges on Parts Cost Calculator = "+numNR);
// get all the data
var dataRangeValues = calcSheet.getDataRange().getValues();
// create an array to temporarily store results
var resultsarray = [];
// Loop through the array of Named Ranges
for (var x = 0; x < numNR; x++) {
var nrName = namedRanges[x].getName();
var nrRange = namedRanges[x].getRange();
var nrRangerow = nrRange.getRow();
var nrRangecol = nrRange.getColumn();
var nrRangeValue = dataRangeValues[nrRangerow - 1][nrRangecol - 1];
//Logger.log("DEBUG: Named Range-Name: "+nrName+", Range: "+nrRange.getA1Notation()+", Row: "+nrRangerow+", Column: "+nrRangecol+", Value-"+nrRangeValue);//DEBUG
// populate the array with the part name and the part value
resultsarray.push([nrName, nrRangeValue]);
}
// identify the range on the Saved Parts sheet to copy the parts list array.
var saveRange = saveSheet.getRange(1, 1, numNR, 2);
saveRange.setValues(resultsarray);
// sort the results on "Saved Parts"
saveRange.activate().sort({
column: 1,
ascending: true
});
}

Google Apps Script Replace and update cell within a range

I have a Google spreadsheet that I'm trying to remove the word "woo" within a range of cells
So far I've managed to loop through the results and log the results, however I haven't figured how to update that information in the spreadsheet itself.
Any guidance would be welcomed
Thank you
function myFunction () {
var ss = SpreadsheetApp.getActiveSheet().getRange('B:B')
var data = ss.getValues();
for (var i = 0; i < data.length; i++) {
var text = data[i].toString();
var finaltext = text.replace(/woo/g, "");
data[i] = finaltext;
Logger.log(data[i]);
}
}
Use setValues()
Notes:
Usually ss is used as a shorthand for spreadsheet, as it's used on the code for a range it's better to use range as a variable name.
setValues() returns a 2D array, so data[i] returns an array of row values rather than a cell value. To get/set cell values, use data[i][0] notation.
Considering the above replace
var ss = SpreadsheetApp.getActiveSheet().getRange('B:B')
by
var range = SpreadsheetApp.getActiveSheet().getRange('B:B')
then add the following line after the for block.
range.setValues(data);
Regarding text var declaration, replace
var text = data[i].toString();
to
var text = data[i][0].toString();
Using open ended references like B:B could lead to problems. To avoid them be sure to keep the sheet rows at minimum or better instead of using an open ended reference use something like B1:B10.

Store formatting information in an array then apply it to a range

I'm trying to create a script that will automatically format a selection based on the formatting of a table in another sheet. The idea is that a user can define a table style for header, rowOdd and rowEven in the Formats sheet, then easily apply it to a selected table using the script.
I've managed to get it working, but only by applying one type of formatting (background colour).
I based my code for reading the code into an array on this article.
As you will hopefully see from my code below, I am only able to read one formatting property into my array.
What I would like to do is read all formatting properties into the array, then apply them to the range in one go. I'm new to this so sorry if my code is a mess!
function formatTable() {
var activeRange = SpreadsheetApp.getActiveSpreadsheet().getActiveRange(); //range to apply formatting to
var arr = new Array(activeRange.getNumRows());
var tableStyleSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Formats"); //location of source styles
var tableColours = {
header: tableStyleSheet.getRange(1, 1, 1).getBackground(),
rowEven: tableStyleSheet.getRange(2, 1, 1).getBackground(),
rowOdd: tableStyleSheet.getRange(3, 1, 1).getBackground()
}
for (var x = 0; x < activeRange.getNumRows(); x++) {
arr[x] = new Array(activeRange.getNumColumns());
for (var y = 0; y < activeRange.getNumColumns(); y++) {
x == 0 ? arr[x][y] = tableColours.header :
x % 2 < 1 ? arr[x][y] = tableColours.rowOdd : arr[x][y] = tableColours.rowEven;
Logger.log(arr);
}
}
activeRange.setBackgrounds(arr);
}
Thanks!
I might be wrong but based from the list of methods given in Class Range, feature to save or store formatting details currently do not exist yet.
However, you may want to try using the following:
copyFormatToRange(gridId, column, columnEnd, row, rowEnd) or copyFormatToRange(sheet, column, columnEnd, row, rowEnd) wherein it copies the formatting of the range to the given location.
moveTo(target) wherein it cuts and paste (both format and values) from this range to the target range.
Did you know that you can get all of the different formatting elements for a range straight into an array?
E.g.
var backgrounds = sheet.getRange("A1:D50").getBackgrounds();
var fonts = sheet.getRange("A1:D50").getFontFamilies();
var fontcolors = sheet.getRange("A1:D50").getFontColors();
etc.
However, there's no way to get all of the formatting in one call unfortunately, so you have to handle each element separately. Then you can apply all of the formats in one go:
targetRng.setFontColors(fontcolors);
targetRng.setBackgrounds(backgrounds);
and so on.

Get data from a lot of different sheets with a script in Google Spreadsheet

I have a spreadsheet containing 50 sheets, named "1", "2", "3". The very first sheet is a summary, gathering specific information from the different sheets. The simple way to fill it in is by using ='1'!B5 and so on. What I want to do is enter that formula into a script and have it pull the specified data from all the different sheets on new rows. So that info from sheet 1 is at row 1, info from sheet 2 is on row 2.
The reason I don't want to do it manually is that I have 14 cells that I need to pull and insert into 4 different overviews from 50 sheets and 2 spreadsheets where I need to do this. Adding up to 5600 functions that I would need to change manually.
The reason I named the sheets in this simple manner is that I know it enables me to write this kind of function. A variable that increases its value by 1 for every loop and outputs the function on a new row with every loop, for instance
var sheetName = 0;
output.setValue('='' + sheetName + ''!B5');
I know I should have a variable for the specified output cell that also increase its value by 1 for every loop. But I have no idea how to get this sorted out, my scripting skills only allow me to modify others script to make them suit my own purposes but not write anything by myself and I have been unable to figure this one out more then the theory behind it. I know this isn't the place to ask for ready made code so I don't demand or even expect a solution, I just felt I had to try and ask for aid.
Here is a dummy which shows what I'm trying to do.
https://docs.google.com/spreadsheet/ccc?key=0ArjDeqGD779cdEh2Ynh5ODBFQVFkVE9lX0p4aWpXelE&usp=sharing#gid=0
You are a lucky man Mattis! I was doing this thing myself earlier this week so I have added a full working script to your dummy sheet. I'll add a copy here for completeness. Any questions please let me know :)
function populateOverview() {
//set basics
var ss = SpreadsheetApp.getActiveSpreadsheet();
var viewSheet = ss.getSheetByName('Overview');
var dataLength = 4; //this is how many cells from each sheet
//create array of sheet names and remove 'overview'
var sheetNames = getSheetNames();
var overviewIndex = sheetNames.indexOf('Overview');
sheetNames.splice(overviewIndex, 1);
//set initial data and target columns
var dataColumn = 2;
var dataRow = 2;
var targetColumn = 3;
var j = 0;
//outer loop iterates through sheets
for (var i = 0; i < sheetNames.length; i++){
//inner loop works across the columns in each sheet, and across the column on the overview
for(var k = 0; k < dataLength; k++){
viewSheet.getRange(j+3, targetColumn+k).setValue(ss.getSheetByName(sheetNames[i]).getRange(dataRow, dataColumn).getValue());
dataColumn = dataColumn + 2;
}
//increments row counter for next sheet input
j = j+1;
//resets for next sheet
dataColumn = 2;
targetColumn = 3;
}
}
/*return sheetnames as array*/
function getSheetNames(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheetArray = ss.getSheets();
var sheetNameArray = [];
for(var i = 0; i<sheetArray.length; i++){
sheetNameArray.push(sheetArray[i].getSheetName());
}
return sheetNameArray;
}

Resources