I have a code which copies row if condition.
By the source sheet is around 8 000 lines and the script fails because is too long.
How can I speed it up?
I would like it takes one 1 hr max.
I think it makes too many calls to Google. I hope we can reduce them.
function dispacthtosheets() {
var sSheet = SpreadsheetApp.openById('xxxxxx');
var srcSheet = sSheet.getSheetByName ( "Dispatch" );
var lastRow = srcSheet.getLastRow ();***emphasized text***
for ( var i = 1 ; i <= lastRow ; i ++ ) {
var cellule = srcSheet.getRange ( "L" + i );
var val = cellule.getValue();
if ( val == "Changement ENT" ) {
var tarSheet3 = sSheet.getSheetByName ( "Changement ENT" );
var srcRange = srcSheet.getRange ( "C" + i + ":R" + i );
var tarRow3 = tarSheet3.getLastRow ();
var tarRange3 = tarSheet3.getRange ( "C" + tarRow3 + ":R" + tarRow3);
srcRange.copyTo (tarRange3);
tarSheet3.insertRowAfter ( tarRow3 );
} if ( val == "VC en REL" ) {
var tarSheet1 = sSheet.getSheetByName ( "VC en REL" );
var srcRange = srcSheet.getRange ( "C" + i + ":R" + i );
var tarRow1 = tarSheet1.getLastRow ();
var tarRange1 = tarSheet1.getRange ( "C" + tarRow1 + ":R" + tarRow1);
srcRange.copyTo (tarRange1);
tarSheet1.insertRowAfter ( tarRow1 );
} if ( val == "Solo à étudier" ) {
var tarSheet2 = sSheet.getSheetByName ( "Solo à étudier" );
var srcRange = srcSheet.getRange ( "C" + i + ":R" + i );
var tarRow2 = tarSheet2.getLastRow ();
var tarRange2 = tarSheet2.getRange ( "C" + tarRow2 + ":R" + tarRow2);
srcRange.copyTo (tarRange2);
tarSheet2.insertRowAfter ( tarRow2 );
} if ( val == "VC + 6 mois" ) {
var tarSheet4 = sSheet.getSheetByName ( "VC + 6 mois" );
var srcRange = srcSheet.getRange ( "C" + i + ":R" + i );
var tarRow4 = tarSheet4.getLastRow ();
var tarRange4 = tarSheet4.getRange ( "C" + tarRow4 + ":R" + tarRow4);
srcRange.copyTo (tarRange4);
tarSheet4.insertRowAfter ( tarRow4);
} if ( val == "Sortie Nat" ) {
var tarSheet5 = sSheet.getSheetByName ( "Sortie Nat" );
var srcRange = srcSheet.getRange ( "C" + i + ":R" + i );
var tarRow5 = tarSheet5.getLastRow ();
var tarRange5 = tarSheet5.getRange ( "C" + tarRow5 + ":R" + tarRow5);
srcRange.copyTo (tarRange5);
tarSheet5.insertRowAfter ( tarRow5 );
} if ( val == "ZCTM" ) {
var tarSheet6 = sSheet.getSheetByName ( "ZCTM" );
var srcRange = srcSheet.getRange ( "C" + i + ":R" + i );
var tarRow6 = tarSheet6.getLastRow ();
var tarRange6 = tarSheet6.getRange ( "C" + tarRow6 + ":R" + tarRow6);
srcRange.copyTo (tarRange6);
tarSheet6.insertRowAfter ( tarRow6 );
} if ( val == "Appro validée" ) {
var tarSheet7 = sSheet.getSheetByName ( "Appro validée" );
var srcRange = srcSheet.getRange ( "C" + i + ":R" + i );;
var tarRow7 = tarSheet7.getLastRow ();
var tarRange7 = tarSheet7.getRange ( "C" + tarRow7 + ":R" + tarRow7);
srcRange.copyTo (tarRange7);
tarSheet7.insertRowAfter ( tarRow7 );
} if ( val == "F943" ) {
var tarSheet8 = sSheet.getSheetByName ( "F943" );
var srcRange = srcSheet.getRange ( "C" + i + ":R" + i );
var tarRow8 = tarSheet8.getLastRow ();
var tarRange8 = tarSheet8.getRange ( "C" + tarRow8 + ":R" +
tarRow8);
srcRange.copyTo (tarRange8);
tarSheet8.insertRowAfter ( tarRow8 );
}
sSheet.toast(' VC dispacthé !', 'Confirmation 📡');
}
};
Archive for a complete sheet at once
function archiver(){
var feuille = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
var archive = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Archive");
var data = feuille.getRange('A2:AC'+(feuille.getLastRow()-1)).getValues()
var archiveData = []
var lignes = []
var ligne = 1
try{
data.forEach(function(row){
ligne++
if (row[28]) {
archiveData.push(row)
lignes.push(ligne)
}
})
archive.getRange(archive.getLastRow()+1,1,archiveData.length,archiveData[0].length).setValues(archiveData)
lignes.reverse().forEach(x => feuille.deleteRow(x));
SpreadsheetApp.getActive().toast('Ligne(s) archivée(s) !', 'Fin de script 🗃️')
}catch(e){
SpreadsheetApp.getActive().toast('Rien à archiver !', 'Fin de script 🗃️')
}
}
Related
Working with this plugin. Demo here https://www.jqueryscript.net/demo/animated-lines-elements-bezier/
On this demo when you resize the page it redraws. When I use this locally it doesn't redraw and the reason seems to be the this.selector is undefined when I run locally so after it clears the svg's it can't recreate them. Anyone have any idea why this might be?
See // Bug: comment below. Is this.selector a special variable for jquery plugins because I don't see it defined anywhere here, but the demo works so not sure how.
(function ($) {
$.fn.extend({
bezier: function (options) {
var defaults = {
strokeColor: '#999',
strokeWidth: 2,
opacity: 1,
fill: 'none',
animate: true,
animationDirection: 'right',
animationDuration: 0.75
};
// Color wheel stuff
var color_wheel = [];
var frequency = .3;
for (var i = 0; i < 32; ++i) {
red = Math.sin(frequency * i + 0) * 127 + 128;
green = Math.sin(frequency * i + (2 * Math.PI / 3)) * 127 + 128;
blue = Math.sin(frequency * i + (4 * Math.PI / 3)) * 127 + 128;
color_wheel.push(RGB2Color(red, green, blue));
}
var color_index = 0;
function RGB2Color(r, g, b) {
return '#' + byte2Hex(r) + byte2Hex(g) + byte2Hex(b);
}
function byte2Hex(n) {
var nybHexString = "0123456789ABCDEF";
return String(nybHexString.substr((n >> 4) & 0x0F, 1)) + nybHexString.substr(n & 0x0F, 1);
}
// Color wheel stuff
//override default options with user set options
var settings = $.extend(defaults, options);
var me = {};
me.init = function (initObj) {
if (initObj) {
$.each(initObj, function (index, value) {
settings[index] = value;
});
}
};
me.set = function (prop, val) {
settings[prop] = val;
};
me.on = function (el1, el2) {
var $el1 = $(el1);
var $el2 = $(el2);
if ($el1.length && $el2.length) {
var svgheight, p, svgleft, svgtop, svgwidth;
var el1pos = $(el1).offset();
var el2pos = $(el2).offset();
var el1H = $(el1).outerHeight();
var el1W = $(el1).outerWidth();
var el2H = $(el2).outerHeight();
var el2W = $(el2).outerWidth();
svgleft = Math.round(el1pos.left + el1W);
svgwidth = Math.round(el2pos.left - svgleft);
var curvinessFactor, cpt;
////Determine which is higher/lower
if ((el2pos.top + (el2H / 2)) <= (el1pos.top + (el1H / 2))) {
// console.log("low to high");
svgheight = Math.round((el1pos.top + el1H / 2) - (el2pos.top + el2H / 2));
svgtop = Math.round(el2pos.top + el2H / 2) - settings.strokeWidth;
cpt = Math.round(svgwidth * Math.min(svgheight / 300, 1));
p = "M0," + (svgheight + settings.strokeWidth) + " C" + cpt + "," + (svgheight + settings.strokeWidth) + " " + (svgwidth - cpt) + "," + settings.strokeWidth + " " + svgwidth + "," + settings.strokeWidth;
}
else {
// console.log("high to low");
svgheight = Math.round((el2pos.top + el2H / 2) - (el1pos.top + el1H / 2));
svgtop = Math.round(el1pos.top + el1H / 2) - settings.strokeWidth;
cpt = Math.round(svgwidth * Math.min(svgheight / 300, 1));
p = "M0," + settings.strokeWidth + " C" + cpt + ",0 " + (svgwidth - cpt) + "," + (svgheight + settings.strokeWidth) + " " + svgwidth + "," + (svgheight + settings.strokeWidth);
}
$ropebag = $('#ropebag').length ? $('#ropebag') : $('main').append($("<div id='ropebag' />")).find('#ropebag');
var svgnode = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
var newpath = document.createElementNS('http://www.w3.org/2000/svg', "path");
var color_to_use = (settings.strokeColor != 'rainbow') ? settings.strokeColor : color_wheel[color_index];
color_index = color_index + 1;
if (color_index == 32) {
color_index = 0;
}
newpath.setAttributeNS(null, "d", p);
newpath.setAttributeNS(null, "stroke", color_to_use);
newpath.setAttributeNS(null, "stroke-width", settings.strokeWidth);
newpath.setAttributeNS(null, "opacity", settings.opacity);
newpath.setAttributeNS(null, "fill", settings.fill);
svgnode.appendChild(newpath);
$(svgnode).css({
left: svgleft,
top: svgtop,
position: 'absolute',
width: svgwidth,
height: svgheight + settings.strokeWidth * 2,
minHeight: '20px'
});
$ropebag.append(svgnode);
if (settings.animate) {
var pl = newpath.getTotalLength();
// Set up the starting positions
newpath.style.strokeDasharray = pl + ' ' + pl;
if (settings.animationDirection == 'right') {
newpath.style.strokeDashoffset = pl;
}
else {
newpath.style.strokeDashoffset = -pl;
}
// IE sucks, dont expect this to work.
newpath.getBoundingClientRect();
newpath.style.transition = newpath.style.WebkitTransition = 'stroke-dashoffset ' + settings.animationDuration + 's ease-in-out';
newpath.style.strokeDashoffset = '0';
}
}
};
me.off = function () {
$("#ropebag").empty();
};
// Redraw upon resizing the window
var selector = this.selector;
$(window).resize(function () {
me.off();
// BUG: selector is undefined
console.log(selector);
$(selector).each(function () {
console.log("looping over eac comp");
var theID = this.id;
$("." + theID).each(function (i, e) {
var rand = Math.random() * 0.7 + 0.3;
me.set('animationDuration', rand);
me.on($("#" + theID), e);
console.log("Window resize" + theID);
});
});
});
// Loop through each parent and draw the lines connecting children
return this.each(function () {
var theID = this.id;
$("." + theID).each(function (i, e) {
var rand = Math.random() * 0.7 + 0.3;
me.set('animationDuration', rand);
me.on($("#" + theID), e);
});
});
}
});
})(jQuery);
I have a WP Theme project.
I´m using Webpack 4 to compile sass files and merge them with css.
project structure
dev
|_ my-theme
|_css
| |_common
| | |_main.sass
| | |_normalize.css
| |_home
| |_home.sass
|_style.sass
I would like to do compile like this:
dist/my-theme/style.css = style.sass include normalize.css and main.sass in the right order
dist/my-theme/css/home/home.css = home.sass
For the moment I managed to do a unique output with the first point.
I saw there is a solution with extract-text-webpack-plugin but it´s deprecated with Webpack 4 so I´m using mini-css-extract-plugin but I have got no idea how doing this.
my current webpack.config.js
const PLUGIN_DIR_NAME = "mytheme";
const GENERAL_CONFIG_INI = "../config/config.ini";
const THEME_CONFIG_INI = "./config/config.ini";
const path = require('path');
const Promise = require('bluebird');
const fs = Promise.promisifyAll( require('fs') );
const ini = require('ini');
// include the css extraction and minification plugins
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CopyPlugin = require('copy-webpack-plugin');
const {CleanWebpackPlugin} = require('clean-webpack-plugin');
module.exports = env => {
const global_config = ini.parse( fs.readFileSync( GENERAL_CONFIG_INI, 'utf-8' ) );
const theme_config = ini.parse( fs.readFileSync( THEME_CONFIG_INI, 'utf-8' ) );
var a_author_uri = global_config.author_uri.split(":");
var author_protocol = a_author_uri[0];
var author_uri_without_protocol = a_author_uri[1].replace( "//", "" );
var a_author_uri_domain = author_uri_without_protocol.split(".");
var author_uri_domain_name, author_uri_extension;
if( a_author_uri_domain.length === 3 ){
author_uri_domain_name = a_author_uri_domain[1];
author_uri_extension = a_author_uri_domain[2];
}else if( a_author_uri_domain.length === 2 ){
author_uri_domain_name = a_author_uri_domain[0];
author_uri_extension = a_author_uri_domain[1];
}
var a_prev_theme_version = theme_config.theme_infos.version.split(".");
var prev_major_theme_version = parseInt( a_prev_theme_version[0] );
var prev_minor_theme_version = parseInt( a_prev_theme_version[1] );
var prev_patch_theme_version = parseInt( a_prev_theme_version[2] );
var prev_build_theme_version = parseInt( a_prev_theme_version[3] );
var next_build_theme_version, next_patch_theme_version, next_minor_theme_version, next_major_theme_version;
if( env.version === "build" ){
next_build_theme_version = prev_build_theme_version + 1;
next_patch_theme_version = prev_patch_theme_version;
next_minor_theme_version = prev_minor_theme_version;
next_major_theme_version = prev_major_theme_version;
}else if( env.version === "patch" ){
next_build_theme_version = 0;
next_patch_theme_version = prev_patch_theme_version + 1;
next_minor_theme_version = prev_minor_theme_version;
next_major_theme_version = prev_major_theme_version;
}else if( env.version === "minor" ){
next_build_theme_version = 0;
next_patch_theme_version = 0;
next_minor_theme_version = prev_minor_theme_version + 1;
next_major_theme_version = prev_major_theme_version;
}else if( env.version === "major" ){
next_build_theme_version = 0;
next_patch_theme_version = 0;
next_minor_theme_version = 0;
next_major_theme_version = prev_major_theme_version + 1;
}
theme_config.theme_infos.version = next_major_theme_version + "." + next_minor_theme_version + "." + next_patch_theme_version + "." + next_build_theme_version;
fs.writeFileSync( THEME_CONFIG_INI, ini.stringify( theme_config, {} ) );
return{
plugins: [
new CleanWebpackPlugin(),
// extract css into dedicated file
new MiniCssExtractPlugin({
filename: './' + PLUGIN_DIR_NAME + '/style.css'
}),
//Only copy php files
new CopyPlugin([
{
from: 'dev',
ignore: ['*.sass', 'next/css/common/**/*.css'],
},
])
],
entry: [ './dev/' + PLUGIN_DIR_NAME + '/style.sass', './dev/' + PLUGIN_DIR_NAME + '/css/common/normalize.css', './dev/' + PLUGIN_DIR_NAME + '/css/common/main.sass' ],
output: {
path: path.resolve(__dirname, 'dist/'),
},
module: {
rules: [
// compile all .scss files to plain old css
{
test: [/css\/common\/.*\.(css|sass)$/],
use: [{loader: MiniCssExtractPlugin.loader},
{loader: 'css-loader'},
{
loader: 'sass-loader',
options: {
prependData: '$theme-name: ' + theme_config.theme_infos.name +
';$author:' + global_config.author +
';$author-uri-protocol:' + author_protocol +
';$author-uri-domain:' + author_uri_domain_name +
';$author-uri-extension:' + author_uri_extension +
';$description:' + theme_config.theme_infos.description.replace(/:/g, "%3A").replace(/;/g, "%3B") + ';' +
';$version-major:' + next_major_theme_version + ';' +
';$version-minor:' + next_minor_theme_version + ';' +
';$version-patch:' + next_patch_theme_version + ';' +
';$version-build:' + next_build_theme_version + ';',
}
}
]
}
]
}
}
};
I found a solution using MiniCssExtractPlugin.
The solution was here.
Basicaly you can change the json array as entry value with an object.
before
entry: [ './dev/' + PLUGIN_DIR_NAME + '/style.sass', './dev/' + PLUGIN_DIR_NAME + '/css/common/normalize.css', './dev/' + PLUGIN_DIR_NAME + '/css/common/main.sass' ],
after
entry:{
style: [ './dev/' + PLUGIN_DIR_NAME + '/style.sass', './dev/' + PLUGIN_DIR_NAME + '/css/common/normalize.css', './dev/' + PLUGIN_DIR_NAME + '/css/common/main.sass' ],
home: [ './dev/' + PLUGIN_DIR_NAME + '/css/home/home.sass' ]
},
If you want that one of css files is inside a subdirectory like css/home.css :
entry:{
style: [ './dev/' + PLUGIN_DIR_NAME + '/style.sass', './dev/' + PLUGIN_DIR_NAME + '/css/common/normalize.css', './dev/' + PLUGIN_DIR_NAME + '/css/common/main.sass' ],
'css/home': [ './dev/' + PLUGIN_DIR_NAME + '/css/home/home.sass' ]
},
Good evening. I am export two models from Blender 2.79 to three.js.
Scene: link
Shadows work. Objects reflect the world around them but do not reflect among themselves.
Scene code:
function init() {
camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 1, 1000 );
camera.position.set( 0, -8, 2 );
// envmap
var path = '/textures/sky_glTF/pisa/'; // ADD "/"
var format = '.png';
var envMap = new THREE.CubeTextureLoader().load( [
path + 'px' + format, path + 'nx' + format,
path + 'py' + format, path + 'ny' + format,
path + 'pz' + format, path + 'nz' + format
] );
scene = new THREE.Scene();
scene.background = envMap;
//MR - YES mirror
var loader = new THREE.GLTFLoader();
loader.load( '/gltf/1.gltf', function ( gltf ) {
gltf.scene.traverse( function ( node ) {
if ( node.isMesh || node.isLight ) node.castShadow = true;
if ( node.isMesh || node.isLight ) node.receiveShadow = true;
} );
gltf.scene.traverse( function ( child ) {
if ( child.isMesh ) {
child.material.envMap = envMap;
}
} );
gltf.scene.position.x = 0;
gltf.scene.position.y = 0;
gltf.scene.position.z = 0;
scene.add( gltf.scene );
} );
//MR - YES mirror
var loader = new THREE.GLTFLoader();
loader.load( '/gltf/2.gltf', function ( gltf2 ) {
gltf2.scene.traverse( function ( node ) {
if ( node.isMesh || node.isLight ) node.castShadow = true;
if ( node.isMesh || node.isLight ) node.receiveShadow = true;
} );
gltf2.scene.traverse( function ( child ) {
if ( child.isMesh ) {
child.material.envMap = envMap;
}
} );
gltf2.scene.position.x = 0;
gltf2.scene.position.y = 0;
gltf2.scene.position.z = 0;
scene.add( gltf2.scene );
} );
How to implement reflections between objects?
What part of the code do you still have to show for a complete answer to my question?
Is there a simple way to include the TOTAL value in the stackedAreaChart's interactiveGuideline tooltip? It'd be great if I could display total users using this awesome tooltip as well.
If not, what's the cleanest alternative?
You can use interactiveGuideline.tooltip.contentGenerator
https://github.com/novus/nvd3/blob/master/src/tooltip.js#L316
e.g.
chart.multiChart.interactiveLayer.tooltip.contentGenerator(function(d) {
var header = d.value;
var headerhtml =
"<thead><tr><td colspan='3'><strong class='x-value'>" +
header +
"</strong></td></tr></thead>";
var bodyhtml = "<tbody>";
var series = d.series;
series.forEach(function(c) {
var value = (c.value || 0).toFixed(2);
if (
c.key === keyForActualGreaterThanPredicted ||
c.key === keyForActualLessThanPredicted
) {
var diff = Math.abs(c.data.y0 - c.data.y1);
if (diff === 0) {
value = "-";
} else {
value = diff.toFixed(2);
}
}
bodyhtml =
bodyhtml +
"<tr><td class='legend-color-guide'><div style='background-color: " +
c.color +
";'></div></td><td class='key'>" +
c.key +
"</td><td class='value'>" +
value +
"</td></tr>";
});
bodyhtml = bodyhtml + "</tbody>";
return "<table>" + headerhtml + "" + bodyhtml + "</table>";
});
the script I am making should do this
PDF-to psd (ok)
all documents stays open (ok)
the user make a selection what defines the crop for every open documents in Photoshop (not ok)
close and save in an other folder(ok)
The idea is that we have pdf's that we wound to crop in a certain way. But next time we will have other pdfs that has to be cropped in a different way. this what I 'have got so far but it's crops the documents like a set in the parameters.
thanks
//PDFOpenOptions.jsx
var OpenAIFile = new PDFOpenOptions;
OpenAIFile.antiAlias = false;
OpenAIFile.mode = OpenDocumentMode.CMYK;
OpenAIFile.resolution = 150;
var myFolder = Folder.selectDialog("select folder");
if(myFolder != null)
{
var fileList = myFolder.getFiles(/\.(pdf)$/i);
for(var i = 0 ;i < fileList.length; i++)
{
if(fileList[i] instanceof File)
{
var doc= open(fileList[i],OpenAIFile);
}
}
};
var outputFolder = Folder.selectDialog("Dossier de destination:");
//alert(outputFolder);
if (app.documents.length > 0) {
//flatten the active document
app.activeDocument.flatten();
//jpeg options
var myJPEGOptions = new JPEGSaveOptions();
myJPEGOptions.embedColorProfile = true;
myJPEGOptions.formatOptions = FormatOptions.STANDARDBASELINE;
myJPEGOptions.matte = MatteType.WHITE;
myJPEGOptions.quality = 12;
myJPEGOptions.scans = 3;
// get documents;
var docs = app.documents;
for (var m = 0; m < app.documents.length; m++) {
app.activeDocument = docs[m];
try {
//crop 1Lsquaire-got from script lisner
var idCrop = charIDToTypeID( "Crop" );
var desc4 = new ActionDescriptor();
var idT = charIDToTypeID( "T " );
var desc5 = new ActionDescriptor();
var idTop = charIDToTypeID( "Top " );
var idPxl = charIDToTypeID( "#Pxl" );
desc5.putUnitDouble( idTop, idPxl, 601.000000 );
var idLeft = charIDToTypeID( "Left" );
var idPxl = charIDToTypeID( "#Pxl" );
desc5.putUnitDouble( idLeft, idPxl, 2068.000000 );
var idBtom = charIDToTypeID( "Btom" );
var idPxl = charIDToTypeID( "#Pxl" );
desc5.putUnitDouble( idBtom, idPxl, 2948.000000 );
var idRght = charIDToTypeID( "Rght" );
var idPxl = charIDToTypeID( "#Pxl" );
desc5.putUnitDouble( idRght, idPxl, 2918.000000 );
var idRctn = charIDToTypeID( "Rctn" );
desc4.putObject( idT, idRctn, desc5 );
var idAngl = charIDToTypeID( "Angl" );
var idAng = charIDToTypeID( "#Ang" );
desc4.putUnitDouble( idAngl, idAng, 0.000000 );
var idDlt = charIDToTypeID( "Dlt " );
desc4.putBoolean( idDlt, false );
var idcropAspectRatioModeKey = stringIDToTypeID( "cropAspectRatioModeKey" );
var idcropAspectRatioModeClass = stringIDToTypeID( "cropAspectRatioModeClass" );
var idtargetSize = stringIDToTypeID( "targetSize" );
desc4.putEnumerated( idcropAspectRatioModeKey, idcropAspectRatioModeClass, idtargetSize );
executeAction( idCrop, desc4, DialogModes.ALL );
//crop 1Lsquaire
//save file to folder
var myFile = new File((outputFolder ) + "/" + activeDocument.name);
app.activeDocument.saveAs(myFile, myJPEGOptions, true);
}
catch (e) {
alert ("Error the script did not execute");
}
}
while(documents.length>0){
documents[documents.length-1].close(SaveOptions.DONOTSAVECHANGES);
}
};
If I understand you correctly you can work out where the crop co-ordinates need to be and then apply them as you see fit. If you change the script-listener crop code to a function you can pass in those co-ordinates. Just add another line for the second set of crops and either save as a new script, or just comment them out
// usage:
selectRectangle(601, 2068, 2948, 2918);
cropToSelection();
// function SELECT RECTANGLE(top, left, bottom, right)
//
// Note: co-ordinates are same as script listener
// and not so human-friendly as t,l,r,b.
// --------------------------------------------------------
function selectRectangle(top, left, bottom, right)
{
// deselect EVERYTHING first
app.activeDocument.selection.deselect();
// =======================================================
var id1 = charIDToTypeID( "setd" );
var desc1 = new ActionDescriptor();
var id2 = charIDToTypeID( "null" );
var ref1 = new ActionReference();
var id3 = charIDToTypeID( "Chnl" );
var id4 = charIDToTypeID( "fsel" );
ref1.putProperty( id3, id4 );
desc1.putReference( id2, ref1 );
var id5 = charIDToTypeID( "T " );
var desc2 = new ActionDescriptor();
var id6 = charIDToTypeID( "Top " );
var id7 = charIDToTypeID( "#Pxl" );
desc2.putUnitDouble( id6, id7, top );
var id8 = charIDToTypeID( "Left" );
var id9 = charIDToTypeID( "#Pxl" );
desc2.putUnitDouble( id8, id9, left );
var id10 = charIDToTypeID( "Btom" );
var id11 = charIDToTypeID( "#Pxl" );
desc2.putUnitDouble( id10, id11, bottom );
var id12 = charIDToTypeID( "Rght" );
var id13 = charIDToTypeID( "#Pxl" );
desc2.putUnitDouble( id12, id13, right );
var id16 = charIDToTypeID( "Rctn" );
desc1.putObject( id5, id16, desc2 );
executeAction( id1, desc1, DialogModes.NO );
}
function cropToSelection()
{
executeAction( charIDToTypeID( "Crop" ), new ActionDescriptor(), DialogModes.NO );
}