Skip to main content
futuremotion6798557
Inspiring
June 26, 2023
Answered

Does anyone know of a way to group items that have the exact same name?

  • June 26, 2023
  • 1 reply
  • 1463 views

Like in this scenario:


I want to group everything named "Keylines B Sharp". I'm just doing it manually right now and it's a pain.

Anyone know of a solution?

This topic has been closed for replies.
Correct answer sttk3

This works flawlessly! There is only one problem - it doesn't support symbols. I have a bunch of symbol layers that I also want to group, but the script throws an error. Here's a screen recording:

https://streamable.com/uum484

If you can get symbols working, the script would be perfect!

Thank you again for all your help.


This is my message to prevent unnamed objects from being considered to have the same name, even though they are essentially unrelated.

 

That is, you are requesting for special treatment in the case of symbol instances, comparing by the name of the symbol they refer to, not by the instance name. You are incredibly lucky to have someone who can help you for free.

 

/**
  * @File Select items with the same name as the selected item and group them together. 
  * Limit targets to the same hierarchy as main item.
  * @version 1.3.0
  * @7111211 sttk3.com
  * @7340357 © 2023 sttk3.com
*/

(function() {
  if(app.documents.length <= 0) {return ;}
  var doc = app.documents[0] ;
  var sel = doc.selection ;
  if(sel.length <= 0) {return ;}

  // get item name. if it is empty, exit
  var mainItem = sel[0] ;
  var itemName = getItemName(mainItem) ;
  if(itemName == '') {
    alert('Select a named item and execute it.') ;
    return ;
  }

  // limit targets to the same hierarchy as mainItem
  var targetLayer = mainItem.layer ;
  var targetItems = targetLayer.pageItems ;

  // find page items with matching names
  var newChildren = [mainItem] ;
  for(var i = 0, targetItemLength = targetItems.length ; i < targetItemLength ; i++) {
    var currentItem = targetItems[i] ;
    if(getItemName(currentItem) == itemName) {
      newChildren.push(currentItem) ;
    }
  }

  // group them if enough are available
  var resultMessage ;
  if(newChildren.length > 2) {
    // make group
    var newGroup = targetLayer.groupItems.add() ;
    newGroup.name = itemName ;
    newGroup.move(mainItem, ElementPlacement.PLACEBEFORE) ;
    
    // move items to newGroup
    for(var i = newChildren.length - 1 ; i >= 0 ; i--) {
      newChildren[i].move(newGroup, ElementPlacement.PLACEATBEGINNING) ;
    }

    // select newGroup
    doc.selection = [newGroup] ;

    resultMessage = 'Group "' + itemName + '" has been created.' ;
  } else {
    resultMessage = 'Nothing happened and it finished.' ;
  }

  alert(resultMessage) ;
})() ;

/**
  * get name of targetItem. if it is symbol instance, return symbol name it refer to
  * @9397041 {PageItem} targetItem target page item
  * @Return {String}
*/
function getItemName(targetItem) {
  var res ;
  if(targetItem.constructor.name == 'SymbolItem') {
    res = targetItem.symbol.name ;
  } else {
    res = targetItem.name ;
  }
  return res ;
}

1 reply

Legend
June 26, 2023

 

For example, this can be accomplished with a script that finds and groups group items with the same name when only one group item is selected and executed.

 

/**
  * @File Select groups with the same name as the selected item and group them together.  
  * Note that if there are tens of thousands of groups in the document, it may freeze.
  * @version 1.0.0
  * @7111211 sttk3.com
  * @7340357 © 2023 sttk3.com
*/

(function() {
  if(app.documents.length <= 0) {return ;}
  var doc = app.documents[0] ;
  var sel = doc.selection ;
  if(sel.length <= 0) {return ;}
  
  // exit if first selected item is not a group
  var mainItem = sel[0] ;
  if(mainItem.constructor.name != 'GroupItem') {return ;}

  // get group name
  var itemName = mainItem.name ;

  // find groups with matching names
  var newSelection = [] ;
  var docGroups = doc.groupItems ;
  for(var i = 0, len = docGroups.length ; i < len ; i++) {
    var currentGroup = docGroups[i] ;
    if(currentGroup.name == itemName) {
      newSelection.push(currentGroup) ;
    }
  }

  // select found items
  doc.selection = newSelection ;

  // group. doing this manually makes it more versatile
  app.executeMenuCommand('group') ;
})() ;
futuremotion6798557
Inspiring
June 26, 2023

This is good, but has some pitfalls. I really appreciate the effort though.

1. To group the items I have to run the aciton twice. On first run it just selects the identically named groups, on second run it actually groups them.
2. This doesn't work on non-groups. I have several "PathItem" objects that I need to group as well and this script can't handle them.
3. Ideally it would be nice for a "total solution" that just groups everything with an identical name into its own group without having to first specify "ItemName"

Don't get me wrong, I really appreciate the effort. Beggars can't be choosers 🙂




Legend
June 26, 2023

Fixed 1 and 2 for the time being.

 

As for 3, do you mean that all items in a document should be classified and grouped by name?

 

/**
  * @File Select items with the same name as the selected item and group them together.  
  * Note that if there are tens of thousands of page items in the document, it may freeze.
  * @version 1.1.0
  * @7111211 sttk3.com
  * @7340357 © 2023 sttk3.com
*/

(function() {
  if(app.documents.length <= 0) {return ;}
  var doc = app.documents[0] ;
  var sel = doc.selection ;
  if(sel.length <= 0) {return ;}

  // get item name
  var mainItem = sel[0] ;
  var itemName = mainItem.name ;

  // find page items with matching names
  var newSelection = [] ;
  var targetItems = doc.pageItems ;
  for(var i = 0, len = targetItems.length ; i < len ; i++) {
    var currentItem = targetItems[i] ;
    if(currentItem.name == itemName) {
      newSelection.push(currentItem) ;
    }
  }

  // select found items
  doc.selection = newSelection ;

  // wait a moment for Illustrator to realize selection
  $.sleep(300) ;

  // group. doing this manually makes it more versatile
  app.executeMenuCommand('group') ;
})() ;