Run ExtendScript down a column on a table

Explorer ,
Sep 12, 2019 Sep 12, 2019

Copy link to clipboard

Copied

I am putting together a script to align numbers in a table by decimal/assumed decimals. (I think all of the parts I’ve found here on the forum – what a great resource!)

FrameMaker aligns like this:

clipboard_image_0.png

We'd like it to align like this:

clipboard_image_1.png

My script adds “.0” and changes the character style to white. (I got help with that part last week but the post got lost in the Adobe forum conversion.) That part works, but I can’t get it to do more than one cell. We can't run it on all tables in the document, or even a whole table. It will need to be by column. Right now, I'm thinking to put the cursor in the top cell of the column, then run the script. Here’s what I have.

#target framemaker  

var doc, pgf, cell, regex; 

//given the cell containing the insertion point
doc = app.ActiveDoc;  
pgf = doc.TextSelection.beg.obj;  
cell = pgf.InTextObj;  
regex = /\./; // this finds a decimal
    
// ...navigate down the column.  
while (cell.ObjectValid () === 1) {  //I think this is where it breaks down
  processDec (pgf, doc, regex);  
  cell = cell.CellBelowInCol;  
}  
// From here down it works great, on one cell. 
function processDec (pgf, doc, regex) {  //by FrameExpert  
    var end = Constants.FV_OBJ_END_OFFSET - 1, begin = 0, textRange;  
    var textList = pgf.GetText (Constants.FTI_CharPropsChange);  
   
    for (var i = textList.length - 1; i >= 0; i -= 1) {  
        begin = textList[i].offset;  
        if (begin !== end) {  
            textRange = new TextRange (new TextLoc (pgf, begin), new TextLoc (pgf, end));  
                if (regex.test (getText (textRange, doc)) === false) {  // if there is a decimal, nothing happens
                    
                    addDecimal ();
                } 
            end = begin;  
        }  
    }  
    if (end > 0) {  
        textRange = new TextRange (new TextLoc (pgf,0), new TextLoc (pgf,end));  

            if (regex.test (getText (textRange, doc)) === false) {  // if there is a decimal, nothing happens
                addDecimal ();
            }  
    }  
}  
  
function getText (textObj, doc) {  //by FrameExpert
  
    var text = "", textItems, i;  
       
    if (textObj.constructor.name !== "TextRange") {  
        textItems = textObj.GetText(Constants.FTI_String);  
    } else {  
         textItems = doc.GetTextForRange(textObj, Constants.FTI_String);  
    }    
    for (i = 0; i < textItems.len; i += 1) {  
        text += (textItems[i].sdata);  
    }  
    return text; 
}  
  
function addDecimal () {

var textRange = new TextRange;
    textRange.beg.obj = textRange.end.obj = pgf;
    textRange.beg.offset = 0;
    textRange.end.offset = Constants.FV_OBJ_END_OFFSET - 1;  

    doc.TextSelection = textRange;
    textRange = doc.TextSelection;
    
    doc.AddText(textRange.end, ".0");
    
    addWhite (); //calls function to apply the White character format to the .0
  }
   
function addWhite () { 
 
var textRange = new TextRange;
    textRange.beg.obj = textRange.end.obj = pgf;
    textRange.beg.offset = Constants.FV_OBJ_END_OFFSET - 3;     
    textRange.end.offset = Constants.FV_OBJ_END_OFFSET - 1;  
    applyCharFmt (textRange, "White", doc);  
}

function applyCharFmt (textRange, name, doc) {  
    var charFmt = 0;  
    charFmt = doc.GetNamedCharFmt (name);  
    if (charFmt.ObjectValid()) {  
        doc.SetTextProps (textRange, charFmt.GetProps());  
    }  
}  

 

If it's possible, I'd like it if we could run it on multiple selected columns. Can anyone help me fix this?

Thank you.

TOPICS
Scripting

Views

1.1K

Likes

translate

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 2 Correct Answers

Mentor , Sep 17, 2019 Sep 17, 2019
Hi, You have gone a long time without a reply. Maybe you figured it out already. I think the lack of response is related to the big changes with these forums. I'm sorry that you did not get any help yet. I think your problem is very simple and exactly where you identified it. The problem is that you are iterating through multiple cells, but never resetting the paragraph for processing to the new cells. I think you just need to add one line as shown below: // ...navigate down the column.while (ce...

Likes

translate

Translate

Translate
Mentor , Sep 19, 2019 Sep 19, 2019
Great. For your question about notifications, yes, I get notifications for everything, even things I do. And then when I click on links, it takes a while to find whatever is new because so much is hidden behind expansion links. At the risk of sounding like someone who just gets mad when something changes, I have to say that usability was one of the last things considered with this rollout. Or, if it was, somebody should look for a different job. Regarding your coding success, great news. I thoug...

Likes

translate

Translate

Translate
Adobe Community Professional ,
Sep 13, 2019 Sep 13, 2019

Copy link to clipboard

Copied

I would suggest contacting someone like Rick Quatro. His TableCleanerES script already does formatting changes for columns on a mass basis, and I expect the parts of it that move from cell to cell or apply column formats could be adapted to what you want to do. Be aware that his scripting is part of how he makes a living, so he may charge for this. I can vouch that his scripts are excellent aids and that his charges are quite reasonable.

Likes

translate

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
Mentor ,
Sep 17, 2019 Sep 17, 2019

Copy link to clipboard

Copied

Hi,

 

You have gone a long time without a reply. Maybe you figured it out already. I think the lack of response is related to the big changes with these forums. I'm sorry that you did not get any help yet.

 

I think your problem is very simple and exactly where you identified it. The problem is that you are iterating through multiple cells, but never resetting the paragraph for processing to the new cells. I think you just need to add one line as shown below:

 

// ...navigate down the column.
while (cell.ObjectValid () === 1) { //I think this is where it breaks down
  var pgf = cell.FirstPgf;
  processDec (pgf, doc, regex);
  cell = cell.CellBelowInCol;
}

 

For multiple selected columns, you need to first be able to find out which cells are selected. Here is an uncommented function I use for that. You will need to interpolate the results into the desired columns. For example, for each selected cell returned, you would need to iterate up to find the top of the column, then run your column modifier routine. And you would want to remember the columns you processed (by remembering the top cell) so you don't process columns multiple times. I hope this helps.

 

Russ

 

 

 

 

function tbl_GetSelectedCells(oDoc, oTable)
{
    var cells = new Array();
    
    if(!oDoc.ObjectValid())
        return cells;
    
    if(!oTable.ObjectValid()) 
        oTable = doc.SelectedTbl;
    
    if(!oTable.ObjectValid())
        return cells;

    var oRow = oTable.TopRowSelection;
    var bottomRowSelected = oTable.BottomRowSelection;

    var leftColSelected = oTable.LeftColNum;
    var rightColSelected = oTable.RightColNum;

    while(oRow.ObjectValid())
    {
        var i = 0;
        oCell = oRow.FirstCellInRow;

        while(oCell.ObjectValid())
        {
            if(i >= leftColSelected && i <= rightColSelected)
                cells.push(oCell);

            i++;

            oCell = oCell.NextCellInRow;
        }

        if(oRow.id == bottomRowSelected.id) 
            oRow = oDoc.GetNamedColor ("InvalidateThisObject");
        else oRow = oRow.NextRowInTbl;
    }

    return cells;
}

Likes

translate

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
Explorer ,
Sep 17, 2019 Sep 17, 2019

Copy link to clipboard

Copied

Hi Russ,
Thank you for your reply. No, I hadn't received an answer yet. I figured the new format was why. 

I used the line you added in my initial code and it does move down the column now. But something is still wrong. I put the cursor in the first cell of each column and ran it. It does this:

table.png

(I used "bold" instead of "white" so I could see what it was doing.) The code says to use the addDecimal function if there is no decimal, but on some of the cells it is ignoring that. Is there something wrong with my textRange?

Thanks,
Julie

Likes

translate

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
Mentor ,
Sep 17, 2019 Sep 17, 2019

Copy link to clipboard

Copied

Hi Julie, I think I can help. But I need you to help me first... Can you explain the basic logic of the processDec() function? It basically looks like a simple end goal... check if there is a decimal in the cell. If there is one, do nothing. If there is none, add ".0" to the end of the text.

 

If that is the goal, I can't follow your various loops. I don't know why you are retrieving FTI_CharPropsChange text items and I don't follow the second conditional - if(end > 0)...

 

If all you care about is checking for a decimal; that is, a period, it seems that it could be much simpler. I would do something like this (untested):

 

var pgf = cell.FirstPgf;
var text = getText(pgf, doc);
if(text.indexOf(".") > -1)
{
  //Do the decimal add...
}

 

You might even want to test an index >0 instead of -1, just to be sure there actually is a digit before the decimal. But that probably doesn't really matter.

 

So let me know if there is more to the story. The complexity of your code suggests that there is something else going on and I don't have the time to decipher it all 🙂  And apparently the history of this thread is not available now.

 

Russ

Likes

translate

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
Mentor ,
Sep 17, 2019 Sep 17, 2019

Copy link to clipboard

Copied

Sorry, I have the conditional backwards, should be if(text.indexOf(".") < 0)

Likes

translate

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
Explorer ,
Sep 18, 2019 Sep 18, 2019

Copy link to clipboard

Copied

Russ,

Here is my original post (it got lost in the forum transition):

 

I am looking for/trying to write a script to align decimals (and assumed decimals) in a table. FrameMaker does not align a column of numbers in a table to the decimal/assumed decimal. Instead, numbers without the decimal are shifted to the right a little.

clipboard_image_0.png

To get around this, we have to add a decimal after the whole number and color it white, so that it looks like this:

clipboard_image_1.png

I am trying to write a script to do this for us. The ultimate goal is for us to select the column or columns and then run the script on them. The script will read through the columns and when if finds a whole number, it will add “.0” and tag it “White,” then move on to the next whole number. I’ve been searching the forum for scripts others have shared, and I’m trying to build from the bottom up. So far, I can add the decimal in single cell.

clipboard_image_2.png

I can also apply the character format; however, it only works if the cursor is before the decimal. If the cursor is after the decimal, it jumps to the next cell, but it doesn’t do anything. How do I make it apply the character format regardless of where the cursor is? [I got this part to work with help from people on the forum.]

clipboard_image_3.png

 

I was trying to build from the bottom up, like FrameExpert always says to do. So I started with the most basic step  -- adding the decimal. Did I make it more complicated that I needed to?

 

Likes

translate

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
Mentor ,
Sep 19, 2019 Sep 19, 2019

Copy link to clipboard

Copied

So, I think that last question, "Did I make it more complicated..." is for me, not part of the original post? I was just questioning your method to determine if a whole number currently exists, or whether the cell has a decimal point. I could not follow all those loops and the use of regex. It seems you could just grab the text and do a simple indexOf() to test for the period. I'm not sure what "build from the bottom up" means.

Likes

translate

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
Explorer ,
Sep 19, 2019 Sep 19, 2019

Copy link to clipboard

Copied

Yes, the questions was for you. I'll give what you suggested a try.

By "build from the bottom up" I just meant making it work one step at at time. First, seeing if it was a decimal; next, add a decimal; next, make it white, etc. I was trying to adapt code that I already had, which is probably why it was so complicated.

By the way, do you get notifications? I keep changing my settings to get them, but whenever I log back in, it's reset.

Likes

translate

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
Explorer ,
Sep 19, 2019 Sep 19, 2019

Copy link to clipboard

Copied

It works!

 

var pgf = cell.FirstPgf;
var text = getText(pgf, doc);
if(text.indexOf(".") === -1)
{
addDecimal ();
}

 

Thank you for your help, Russ!

 

Julie

Likes

translate

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
Mentor ,
Sep 19, 2019 Sep 19, 2019

Copy link to clipboard

Copied

Great. For your question about notifications, yes, I get notifications for everything, even things I do. And then when I click on links, it takes a while to find whatever is new because so much is hidden behind expansion links. At the risk of sounding like someone who just gets mad when something changes, I have to say that usability was one of the last things considered with this rollout. Or, if it was, somebody should look for a different job. Regarding your coding success, great news. I thought it could be much simpler. BTW, the check for -1 might be reliable, but for sure a check for <0 would be the most reliable. Keep coding! It makes FrameMaker fun and makes it a more valuable tool for you.

Likes

translate

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
Explorer ,
Sep 20, 2019 Sep 20, 2019

Copy link to clipboard

Copied

I changed it to <0 and also added "&& isNaN(text) == false" because sometimes we may have a dash or NA or some other non-number in the field. Thank you again for your help!

Likes

translate

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
Mentor ,
Sep 20, 2019 Sep 20, 2019

Copy link to clipboard

Copied

Sure thing. BTW, one of the things that encourages us is having an answer marked as "correct", so if you don't mind...

Likes

translate

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
Explorer ,
Sep 20, 2019 Sep 20, 2019

Copy link to clipboard

Copied

Where do you do that now? I don't see that option anywhere.

Likes

translate

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
Mentor ,
Sep 20, 2019 Sep 20, 2019

Copy link to clipboard

Copied

Ha, well, excellent question. I haven't started any posts myself so I don't know. You probably need a PhD in UI Design and Analysis to figure it out. And then only after somebody shows you.

Likes

translate

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
Explorer ,
Sep 20, 2019 Sep 20, 2019

Copy link to clipboard

Copied

Maybe it's Report, but that's usually is a bad thing. I was a little scared to try it. 🙂

---

Nope, it's not Report.

 

I'm not a fan of this new forum design.

 

Likes

translate

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
Explorer ,
Sep 24, 2019 Sep 24, 2019

Copy link to clipboard

Copied

Apparently only an Adobe staff member or moderator can mark a post as corrrect. 

Likes

translate

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