Copy link to clipboard
Copied
Hi Expert,
I Wonder if there a Script to Create Sequential Numbers into Table Column That User Select (Ascending and Descending) , I Heard that Marijan Tompa Create Script to Numbering Table Cells but i Can't find it anywhere.
Thanks in Advance
Does the following work
var a = app.selection[0]
var startIdx = 1
if(a instanceof Cell && a.columnSpan == 1)
{
for(var i = 0; i < a.cells.length; i++)
{
if(a.cells[i].parentRow.rowType == RowTypes.BODY_ROW)
a.cells[i].contents = (startIdx++).toString()
}
}
The code will need a selection of a column to work, it will also work for selection of cells provide all the cells lie in the same column
-Manan
Try the following
var a = app.selection[0]
if(a instanceof Cell && a.columnSpan == 1)
{
var startIdx = a.cells.length
for(var i = 0; i < a.cells.length; i++)
{
if(a.cells[i].parentRow.rowType == RowTypes.BODY_ROW);
a.cells[i].contents = (startIdx--).toString()
}
}
As i mentioned that I used startIdx for numbering so that is what was needed to be tweaked for reversing the numbering order.
-Manan
If you want to use the logic that you were following then you need to twek your for loop condition. The problem is that you are starting the loop with -1 and decreasing it so the condition i < a.cells.length will always be true as length will be positive and i will always be negative. So at one point when you outrun the number of cells it would result in a crash due to invalid cell object, if it would not crash you would end in a endless loop. Try the following
var a = app.selection[0]
var start
...
Thank alot @Manan Joshi , I also tried this and its Working also making startIdx = 0 and minus increasing from cells.length :
//Descender Version to Count Selected Column
//User must select the Column need to Count
var a = app.selection[0]
var startIdx = 0 //Starting Number of Counting
if(a instanceof Cell && a.columnSpan == 1)
{
for(var i = 0; i < a.cells.length; i++)
{
if(a.cells[i].parentRow.rowType == RowTypes.BODY_ROW);
a.cells[i].contents = (a.cells.length-startIdx++).toString()
}
...
Copy link to clipboard
Copied
Hi M.Hasanain,
could you show in two screenshots what you like to do?
First screenshot: Table cells selected ( perhaps also with contents )
Second screenshot: Result after script run
Thanks,
Uwe Laubender
( ACP )
Copy link to clipboard
Copied
Dear Uwe Laubender
Thanks a lot for your reply, here is the screen shots in one image, The First Row is Header :
Copy link to clipboard
Copied
Does the following work
var a = app.selection[0]
var startIdx = 1
if(a instanceof Cell && a.columnSpan == 1)
{
for(var i = 0; i < a.cells.length; i++)
{
if(a.cells[i].parentRow.rowType == RowTypes.BODY_ROW)
a.cells[i].contents = (startIdx++).toString()
}
}
The code will need a selection of a column to work, it will also work for selection of cells provide all the cells lie in the same column
-Manan
Copy link to clipboard
Copied
Wow, That's Great and simple, Thanks a lot @Manan Joshi , but please can you explain two things in the code? , First thing i wish to understand (columnspan) what does it mean and the benefit of it? and the second (startidx) , i think the second is the cell ID number(startidx) right?
Thanks a lot again, i really learned a lot, I'm so grateful for your generous efforts.
Copy link to clipboard
Copied
Hi @M.Hasanin,
First thing i wish to understand (columnspan) what does it mean and the benefit of it?
By @M.Hasanin
When we have a column selected the type of selection object is given as Cell so there is no way we could determine if the selection was indeed a column(I did not find the way in my search, I can be wrong though, lots of smart folks out here so better be safe :)). So what I did is use columnspan, which tells how many columns does the selection cells contain. Now for selection to lie in a single colum the columnspan will have to be one. This is the reason the code will work also for selection of cells that lie in a single column in addition to the selection of a single column
and the second (startidx) , i think the second is the cell ID number(startidx) right?
By @M.Hasanin
The startidx is nothing but a variable that holds the sequential number that we need to populate in the cells of the selection. We don't need to check the address as we can iterate the cells collection and are already handling header rows.
Hope this makes sense.
-Manan
Copy link to clipboard
Copied
Thanks a lot @Manan Joshi for details , I played a little with the math to reverse the Numbering (to Make Descender Version) , it works but it gives error in the first! :
//Descender Version to Count Selected Column
//User must select the Column need to Count
var a = app.selection[0]
var startIdx = 1 //Starting Number of Counting
if(a instanceof Cell && a.columnSpan == 1)
{
for(var i = -1; i < a.cells.length; i--) //Descender Working But with Object is Invalid
{
if(a.cells[i].parentRow.rowType == RowTypes.BODY_ROW);
a.cells[i].contents = (startIdx++).toString()
}
}
The Script is Working correctly after hitting ok, (but gives the following error first)
Copy link to clipboard
Copied
Try the following
var a = app.selection[0]
if(a instanceof Cell && a.columnSpan == 1)
{
var startIdx = a.cells.length
for(var i = 0; i < a.cells.length; i++)
{
if(a.cells[i].parentRow.rowType == RowTypes.BODY_ROW);
a.cells[i].contents = (startIdx--).toString()
}
}
As i mentioned that I used startIdx for numbering so that is what was needed to be tweaked for reversing the numbering order.
-Manan
Copy link to clipboard
Copied
Copy link to clipboard
Copied
If you want to use the logic that you were following then you need to twek your for loop condition. The problem is that you are starting the loop with -1 and decreasing it so the condition i < a.cells.length will always be true as length will be positive and i will always be negative. So at one point when you outrun the number of cells it would result in a crash due to invalid cell object, if it would not crash you would end in a endless loop. Try the following
var a = app.selection[0]
var startIdx = 1 //Starting Number of Counting
if(a instanceof Cell && a.columnSpan == 1)
{
for(var i = -1; Math.abs(i) <= a.cells.length; i--)
{
if(a.cells[i].parentRow.rowType == RowTypes.BODY_ROW);
a.cells[i].contents = (startIdx++).toString()
}
}
-Manan
Copy link to clipboard
Copied
Thank alot @Manan Joshi , I also tried this and its Working also making startIdx = 0 and minus increasing from cells.length :
//Descender Version to Count Selected Column
//User must select the Column need to Count
var a = app.selection[0]
var startIdx = 0 //Starting Number of Counting
if(a instanceof Cell && a.columnSpan == 1)
{
for(var i = 0; i < a.cells.length; i++)
{
if(a.cells[i].parentRow.rowType == RowTypes.BODY_ROW);
a.cells[i].contents = (a.cells.length-startIdx++).toString()
}
}
Copy link to clipboard
Copied
Hi M.Hasanain,
please note that a user could select table cells that a script has trouble with.
Could happen with situations where merged cells are in the table, but not necessarily selected.
try
{
app.selection
}catch(e)
{
alert
(
"ERROR Number:" +"\r"+ e.number +"\r"+
"ERROR Message:" +"\r"+ e.message
);
};
will throw an error when you select the yellow cells in this example:
Regards,
Uwe Laubender
( ACP )
Copy link to clipboard
Copied
And there is another issue with a selection of text cells like the one above:
InDesign will crash if the above cells are selected and you want to access the "Edit" main menu ("Bearbeiten" in my German InDesign ).
FWIW: The two bugs are already reported at InDesign Prerelease.
Regards,
Uwe Laubender
( ACP )
Copy link to clipboard
Copied
Thank you @Laubender But do you mean i have to alert user to prevent selecting (Merged Cells)? or there are another fix
Copy link to clipboard
Copied
No. I only want to show that something could go wrong with picking up a user selection to save it to a variable.
Or that something can go wrong if you want to work a user selection directly. Wrap it into try > catch and alert the user that this kind of selection is not supported by your script.
You simply cannot foresee this issue good enough.
Regards,
Uwe Laubender
( ACP )
Copy link to clipboard
Copied
ok, thank you @Laubender , i already made a warning alert to the user to show him to select only column cells to numbering, but i wonder can i prevent user from selecting anything execpet one column direction?
Script only run in case user select cells :
Script will stuck if the user select non column cells, i mean not one direction but indesign didnt crash (images from InDesign 2021)
Copy link to clipboard
Copied
Well. Every selected cell belongs to at least one column in a table.
So check for property parentColumn for example. Perhaps this:
app.selection[0].cells[0].parentColumn == app.selection[0].cells[1].parentColumn
// Returns false
// if the first two cells in the selection belong to two different columns
// Returns true
// if the first two cells in the same column are selected.
Regards,
Uwe Laubender
( ACP )
Copy link to clipboard
Copied
Wow @Laubender Thats Great!, I developed little checker including your advice to check if one column selected or not, thanks a lot, here is the code :
//Check if the User Select One Column Cells
var Selectedcells = app.selection[0];
if (Selectedcells instanceof Cell) {
if (Selectedcells.cells[0].parentColumn == Selectedcells.cells[1].parentColumn == true) {
// Returns false // if the first two cells in the selection belong to two different columns
// Returns true // if the first two cells in the same column are selected
// Delete all Selected Cells content to make it EMPTY Before Continue By Looping
for(var i=0 ; i<Selectedcells.cells.length ; i++)
Selectedcells.cells[i].contents = ""; //Make all Cell Contents EMPTY
}
else {
alert("Select Only One Column Cells and Run Script Again!", "STOP");
exit();
}
}
//Check Again with if no Cells Selected , User didnt Touch a Table
if (Selectedcells instanceof Cell) {
// Delete all Selected Cells content to make it EMPTY Before Continue By Looping
for(var i=0 ; i<Selectedcells.cells.length ; i++)
Selectedcells.cells[i].contents = ""; //Make all Cell Contents EMPTY
}
else {
alert("There is No Selected Table One Column Cells!, Select One Column Cells and Run Script Again!", "STOP");
exit();
}
Copy link to clipboard
Copied
and Please Mr @Laubender One Last Question , I Wonder what if i want to only check for one cell selected? because thats situation also causing error? (Object is Invalid) :
if (Selectedcells.cells[0].parentColumn == Selectedcells.cells[1].parentColumn == true)
What Condition must be added to avoid that error? thanks a lot
Copy link to clipboard
Copied
Check the length of the cells in the first item of the selection:
app.selection[0].cells.length == 1
app.selection[0].cells.length > 1
Regards,
Uwe Laubender
( ACP )
Copy link to clipboard
Copied
Thanks @Laubender , I forgot to drink enough Coffee!. :), Here is the Complete Code in Short but just two Things to make the code good enough and is how to check if the user select text inside cell instead of selecting the cell it-self! and how to check if the cursor inside table cell (not select anything) and also this shouid be not allowed!
//User must select the Column need to Count
//Preparing Check List First!
//Check if the User Select One Column Cells
var Selectedcells = app.selection[0];
//Check for One Cell Selected
if (Selectedcells instanceof Cell && Selectedcells.cells.length == 1) {
alert("One Cell Selection Not Allowed!", "STOP");
exit();
}
else if (Selectedcells instanceof Cell && Selectedcells.cells.length == 0) {
alert("User Didnt Select any Selection!", "STOP");
exit();
}
else if (Selectedcells instanceof Cell && Selectedcells.cells.length < 1) {
alert("There is No Selected Table One Column Cells!, Select One Column Cells and Run Script Again!", "STOP");
exit();
}
else if (Selectedcells instanceof Cell && Selectedcells.cells[0].parentColumn == Selectedcells.cells[1].parentColumn == false) {
alert("Select Only One Column Cells and Run Script Again!", "STOP");
exit();
}
else if(Selectedcells < 0) {
alert("You Select Nothing!", "STOP");
exit();
}
else if(Selectedcells instanceof TextFrame) {
alert("Dont Select The Table Frame!", "STOP");
exit();
PreRun();
}
function PreRun() { //Make all Cell Contents EMPTY at First
var Usercells = app.selection[0];
if(Usercells instanceof Cell && Usercells.columnSpan == 1) {
for(var i=0 ; i<Usercells.cells.length ; i++)
Usercells.cells[i].contents = "";
$.sleep(3);
}
}
var Selectedcells = app.selection[0]
var startIdx = 1 //Starting Number of Counting
if(Selectedcells instanceof Cell && Selectedcells.columnSpan == 1)
{
for(var i = 0; i < Selectedcells.cells.length; i++)
{
if(Selectedcells.cells[i].parentRow.rowType == RowTypes.BODY_ROW)
Selectedcells.cells[i].contents = (startIdx++).toString()
}
}
Copy link to clipboard
Copied
@Laubender , Thank you, I Fixed the Script (Now no Erros) all Error Conditions Covered
In Case Some One want to Benefit , here the final main script , Thanks you all :
//User must select the Column or Cells need to Count
//Preparing Check List First!
var Selectedcells = app.selection[0];
//Check for One Cell Selected
if (Selectedcells instanceof Cell && Selectedcells.cells.length == 1) {
alert("One Cell Selection Not Allowed!", "STOP");
exit();
}
else if (Selectedcells instanceof Cell && Selectedcells.cells.length < 0) {
alert("User Didnt Select any Selection!", "STOP");
exit();
}
else if (Selectedcells instanceof Cell && Selectedcells.cells.length < 1) {
alert("There is No Selected Table One Column Cells!, Select One Column Cells and Run Script Again!", "STOP");
exit();
}
else if (Selectedcells instanceof Cell && Selectedcells.cells[0].parentColumn == Selectedcells.cells[1].parentColumn == false) {
alert("Select Only Punch of Column Cells and Run Script Again!", "STOP");
exit();
}
else if(Selectedcells < 0) {
alert("You Select Nothing!", "STOP");
exit();
}
else if(Selectedcells instanceof TextFrame) {
alert("Dont Select The Table Frame!", "STOP");
exit();
PreRun();
}
else if (Selectedcells.parent instanceof Cell) { //Check Mouse Inside cell not Selecting
alert("You Select Nothing, you are just inside Table Cell!", "STOP");
exit();
PreRun();
}
function PreRun() { //Make all Cell Contents EMPTY at First
var Usercells = app.selection[0];
if(Usercells instanceof Cell && Usercells.columnSpan == 1) {
for(var i=0 ; i<Usercells.cells.length ; i++)
Usercells.cells[i].contents = "";
$.sleep(3);
}
}
var Selectedcells = app.selection[0]
var startIdx = 1 //Starting Number of Counting
if(Selectedcells instanceof Cell && Selectedcells.columnSpan == 1)
{
for(var i = 0; i < Selectedcells.cells.length; i++)
{
if(Selectedcells.cells[i].parentRow.rowType == RowTypes.BODY_ROW)
Selectedcells.cells[i].contents = (startIdx++).toString()
}
}