• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

Creating Sequential Numbers for Table Column Via JavaScript Ascending and Descending

Enthusiast ,
Nov 16, 2021 Nov 16, 2021

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

Best
Mohammad Hasanin
TOPICS
Scripting

Views

1.3K

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 4 Correct answers

Community Expert , Nov 16, 2021 Nov 16, 2021

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

Votes

Translate

Translate
Community Expert , Nov 17, 2021 Nov 17, 2021

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

Votes

Translate

Translate
Community Expert , Nov 17, 2021 Nov 17, 2021

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
...

Votes

Translate

Translate
Enthusiast , Nov 18, 2021 Nov 18, 2021

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()
    }
...

Votes

Translate

Translate
Community Expert ,
Nov 16, 2021 Nov 16, 2021

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 )

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Nov 16, 2021 Nov 16, 2021

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 :

Table ID Column Numbering.jpg

Best
Mohammad Hasanin

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Nov 16, 2021 Nov 16, 2021

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

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Nov 17, 2021 Nov 17, 2021

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.

 

Best
Mohammad Hasanin

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Nov 17, 2021 Nov 17, 2021

Copy link to clipboard

Copied

Hi @M.Hasanin,

quote

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

quote

 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

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Nov 17, 2021 Nov 17, 2021

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)
Working after OK.jpg 

Best
Mohammad Hasanin

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Nov 17, 2021 Nov 17, 2021

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

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Nov 17, 2021 Nov 17, 2021

Copy link to clipboard

Copied

Thank you a lot @Manan Joshi 

 

 

 

Best
Mohammad Hasanin

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Nov 17, 2021 Nov 17, 2021

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

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Nov 18, 2021 Nov 18, 2021

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()
    }
}

 

Best
Mohammad Hasanin

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Nov 19, 2021 Nov 19, 2021

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:

ERROR-1-Message-Selection-on-SELECTED-CELLS.PNG

 

Regards,
Uwe Laubender

( ACP )

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Nov 19, 2021 Nov 19, 2021

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 ).

 

Crash-when-trying-to-access-menu-Edit.PNG

 

FWIW: The two bugs are already reported at InDesign Prerelease.

 

Regards,
Uwe Laubender

( ACP )

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Nov 19, 2021 Nov 19, 2021

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 

Best
Mohammad Hasanin

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Nov 19, 2021 Nov 19, 2021

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 )

 

 

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Nov 19, 2021 Nov 19, 2021

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?

User Warning.jpg

Script only run in case user select cells :

Script Run only after user select a column.jpg

Script will stuck if the user select non column cells, i mean not one direction but indesign didnt crash (images from InDesign 2021)

Script will stuck if the user select non column cells.jpg

Best
Mohammad Hasanin

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Nov 19, 2021 Nov 19, 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 )

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Nov 19, 2021 Nov 19, 2021

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

 

 

 

Best
Mohammad Hasanin

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Nov 19, 2021 Nov 19, 2021

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)


Object is invalid.jpg

What Condition must be added to avoid that error? thanks a lot

Best
Mohammad Hasanin

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Nov 19, 2021 Nov 19, 2021

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 )

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Nov 19, 2021 Nov 19, 2021

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()
    }
}

 

Best
Mohammad Hasanin

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Nov 20, 2021 Nov 20, 2021

Copy link to clipboard

Copied

LATEST

@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()
    }
}

 

Best
Mohammad Hasanin

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines