[CDR 2017-2022] Несколько групп рядом

Григор-313

Участник
Топикстартер
Сообщения
18
Реакции
1
Всем доброго дня! Есть способ или макрос как сгруппировать в несколько групп массив чисел (номеров)
Есть список номеров преобразованных в линии и теперь нужно сделать отдельные 2х и 3х значные числа в группы
В ручную ну очень долго.
Кто как группирует? Есть макрос который группирует рядом стоящие объекты по заданным параметрам, расстоянию например?
Screenshot_1.jpg
 
Если бы числа у вас были бы не "преобразованы в линии", то задача была бы тривиальной. А так ее даже сложно формулизовать - назовите мне внятный критерий, чем "преобразованное в линии" двузначное число отличается от трехзначного? Минимальная ширина? Или вам надо просто "преобразованные в линии" цифры сгруппировать в 2 или 3 значные группы по критерию расстояния до соседней?
 
  • Спасибо
Реакции: Григор-313
Если бы числа у вас были бы не "преобразованы в линии", то задача была бы тривиальной. А так ее даже сложно формулизовать - назовите мне внятный критерий, чем "преобразованное в линии" двузначное число отличается от трехзначного? Минимальная ширина? Или вам надо просто "преобразованные в линии" цифры сгруппировать в 2 или 3 значные группы по критерию расстояния до соседней?
Мне нужно из массива объектов сделать отдельные группы.
конкретно в этом случае разложить на печать номера. но сейчас каждая цифра отдельный объект.
а мне нужно сделать объектами номера - объединив цифры в номер
группирую в ручную.... долго
 
Если прямая нумерация без "хитростей и повторов", быстрее будет вывести заново цифры (числа) через переменные данные, подобрав нужный шрифт и его параметры.

"Текст в кривых" - в данном случае - тут уже мало что поможет (имхо).
 
  • Спасибо
Реакции: zollinger
Если прямая нумерация без "хитростей и повторов", быстрее будет вывести заново цифры (числа) через переменные данные, подобрав нужный шрифт и его параметры.

"Текст в кривых" - в данном случае - тут уже мало что поможет (имхо).
то есть нет такого условия в макросах - проверять расстояния между объектами и группировать если соблюдается условие (допустим ближе 5мм) - объединить?
 
то есть нет такого условия в макросах - проверять расстояния между объектами и группировать если соблюдается условие (допустим ближе 5мм) - объединить?
Сходу не найду готового, самое близкое вот такое, наверное, можно допилить под вашу задачу 'hmmm'
 
  • Спасибо
Реакции: Григор-313
Какой смысл ковыряться в каше кривых, если задача напечатать номера?
 
В 100 раз проще перегенерировать номера. да хоть в том же excel, и шрифт подобрать. Бредовая затея
 
  • Спасибо
Реакции: Григор-313
Если у вас номера так, как здесь, по порядку просто, то перебрать. Если же какие-то уникальные неупорядоченные номера идут, то распознать ocr и, опять же, работать как с текстом. 5 секунд на всё
 

Вложения

  • Спасибо
Реакции: Григор-313
Люди добрые, я же спросил как объекты сгруппировать в группы в массиве. Не важно текст или другое.
У каждого свои задачи и свои условия в которых он работает.
Получается нет такого макроса?
 
Сходу не найду готового, самое близкое вот такое, наверное, можно допилить под вашу задачу 'hmmm'
Этот уже скачал, он группирует только те объекты которые пересекаются.
Может его получится изменить для группировки объектов рядом стоящих?
 
Алиса Аи что то такое выдала, но я не спец во всем этом, не знаю будет ли работать

Ниже — VBA‑скрипт для CorelDRAW, который сканирует страницу сеткой прямоугольников заданного размера и группирует объекты в каждом отдельном прямоугольнике (а не по всей строке).

Как работает скрипт​

  1. Определяет границы страницы.
  2. Разбивает страницу на сетку прямоугольников размером <span>tileWidth&nbsp;×&nbsp;tileHeight</span>.
  3. Для каждого прямоугольника:
    • создаёт область выделения;
    • находит объекты, полностью или частично попавшие в область;
    • группирует их (если найдено ≥ 2 объектов).
  4. Визуализирует сканирующие прямоугольники (опционально).
  5. Выводит отчёт о количестве созданных групп.

Код скрипта​

vba


Код:
Sub ScanAndGroupByRowsWithVisualFeedback()
    Dim doc As Document
    Dim page As Page
    Dim bounds As Rect
    Dim scanRowHeight As Double  ' Высота строки сканирования (в пунктах)
    Dim yStart As Double, yEnd As Double, yCurrent As Double
    Dim selectionRect As Rect
    Dim shapesInRow As ShapeRange
    Dim groupCount As Long
    Dim feedbackRect As Shape  ' Визуальный прямоугольник для отображения полосы
    
    ' Настройки
    scanRowHeight = 40          ' Высота строки (меняйте по необходимости)
    Const feedbackOpacity As Double = 0.3  ' Прозрачность визуальной полосы (0–1)
    
    Set doc = ActiveDocument
    Set page = doc.ActivePage
    
    ' Получаем границы страницы
    Set bounds = page.GetBoundingBox
    yStart = bounds.Top
    yEnd = bounds.Bottom
    
    groupCount = 0
    
    ' Отключаем обновление экрана для скорости (опционально)
    doc.BeginCommandGroup
    Application.RefreshScreen = False
    
    ' Сканируем строки сверху вниз
    yCurrent = yStart
    Do While yCurrent > yEnd  ' В CorelDRAW Y уменьшается сверху вниз
        ' Определяем прямоугольник для текущей строки
        Set selectionRect = New Rect
        selectionRect.Left = bounds.Left
        selectionRect.Right = bounds.Right
        selectionRect.Top = yCurrent
        selectionRect.Bottom = yCurrent - scanRowHeight
        
        ' Визуализируем полосу сканирования (временный прямоугольник)
        Set feedbackRect = page.CreateRectangle(selectionRect.Left, selectionRect.Top, _
                                                  selectionRect.Right, selectionRect.Bottom)
        feedbackRect.Fill.UniformColor.RGBAssign 255, 255, 0  ' Жёлтый цвет
        feedbackRect.Opacity = feedbackOpacity
        feedbackRect.Outline.Width = 0.1
        
        ' Находим объекты, пересекающие или содержащиеся в полосе
        Set shapesInRow = page.FindShapes(selectionRect, cdrIntersectsRect Or cdrInsideRect)
        
        ' Если найдено 2+ объекта — группируем
        If shapesInRow.Count >= 2 Then
            shapesInRow.Group
            groupCount = groupCount + 1
        End If
        
        ' Удаляем визуальный прямоугольник после обработки
        feedbackRect.Delete
        
        ' Переходим к следующей строке
        yCurrent = yCurrent - scanRowHeight
    Loop
    
    ' Включаем обновление экрана
    Application.RefreshScreen = True
    doc.EndCommandGroup
    
    ' Сообщение о результате
    If groupCount > 0 Then
        MsgBox "Сгруппировано " & groupCount & " строк объектов.", vbInformation, "Готово"
    Else
        MsgBox "Не найдено строк с 2+ объектами для группировки.", vbExclamation, "Внимание"
    End If
End Sub

Как настроить​

  1. <span>tileWidth = 60</span> и <span>tileHeight = 40</span>
    • Размеры сканирующего прямоугольника в пунктах.
    • Уменьшите значения для более детального сканирования (больше прямоугольников).
    • Увеличьте для крупных объектов (меньше групп).
    • Пример: <span>tileWidth = 30</span>, <span>tileHeight = 30</span> — мелкая сетка.
  2. <span>feedbackOpacity = 0.2</span>
    • Прозрачность визуальных прямоугольников (от <span>0</span> — невидимо до <span>1</span> — непрозрачно).
    • Чтобы отключить визуализацию, установите <span>feedbackOpacity = 0</span>.
  3. Цвет визуальных прямоугольников
    • <span>RGBAssign 0, 255, 0</span> — зелёный.
    • Меняйте числа: <span>RGBAssign R, G, B</span> (каждое от 0 до 255).
    • Например: <span>RGBAssign 255, 0, 0</span> — красный.
  4. Критерии отбора объектов
    • <span>cdrIntersectsRect</span> — объекты, пересекающие прямоугольник.
    • <span>cdrInsideRect</span> — объекты, полностью внутри прямоугольника.
    • В коде использованы оба флага (<span>Or</span>). Если нужно только полное включение, оставьте <span>cdrInsideRect</span>.

Как использовать​

  1. Откройте CorelDRAW.
  2. Нажмите <span>Alt</span> + <span>F11</span> — откроется редактор VBA.
  3. В меню <span>Insert</span> → <span>Module</span> создайте новый модуль.
  4. Вставьте код выше.
  5. Настройте <span>tileWidth</span>, <span>tileHeight</span> и <span>feedbackOpacity</span> под свои нужды.
  6. Запустите скрипт кнопкой <span>Run</span> (или <span>F5</span>).

Примечания​

  • Визуальные прямоугольники появляются временно и удаляются после обработки каждой ячейки.
  • Скрипт работает на активной странице документа.
  • Объекты на скрытых/заблокированных слоях не обрабатываются.
  • Группировка сохраняет исходные атрибуты объектов.
  • Для отмены действий используйте <span>Ctrl</span> + <span>Z</span>.
  • Если в прямоугольнике только 1 объект, группировка не выполняется.

Пример работы​

  • Страница 300 × 200 пт, <span>tileWidth&nbsp;=&nbsp;60</span>, <span>tileHeight&nbsp;=&nbsp;40</span> → сетка 5 × 5 прямоугольников.
  • В 3 прямоугольниках найдено по 2–4 объекта → создано 3 группы.
  • В остальных прямоугольниках по 0–1 объекту → группировки нет.
  • Итог: «Сгруппировано 3 прямоугольных областей».
 
Последнее редактирование:
  • Спасибо
Реакции: Григор-313
  1. Разбивает страницу на сетку прямоугольников размером <span>tileWidth&nbsp;×&nbsp;tileHeight</span>.
  2. Для каждого прямоугольника:
    • создаёт область выделения;
    • находит объекты, полностью или частично попавшие в область;
    • группирует их (если найдено ≥ 2 объектов).
Сомневаюсь, что вы именно это и хотите.
 
Не тот кусок кода воткнул в предыдущем сообщении.. (

Код:
Sub TileScanAndGroup()
    Dim doc As Document
    Dim page As Page
    Dim bounds As Rect
    Dim tileWidth As Double, tileHeight As Double  ' Размеры прямоугольника (в пунктах)
    Dim xStart As Double, xEnd As Double, yStart As Double, yEnd As Double
    Dim xCurrent As Double, yCurrent As Double
    Dim selectionRect As Rect
    Dim shapesInTile As ShapeRange
    Dim groupCount As Long
    Dim feedbackRect As Shape  ' Визуальный прямоугольник
    
    ' Настройки
    tileWidth = 60      ' Ширина прямоугольника сканирования
    tileHeight = 40     ' Высота прямоугольника сканирования
    Const feedbackOpacity As Double = 0.2  ' Прозрачность визуальной сетки (0–1)
    
    Set doc = ActiveDocument
    Set page = doc.ActivePage
    
    ' Получаем границы страницы
    Set bounds = page.GetBoundingBox
    xStart = bounds.Left
    xEnd = bounds.Right
    yStart = bounds.Top
    yEnd = bounds.Bottom
    
    groupCount = 0
    
    ' Отключаем обновление экрана для скорости
    doc.BeginCommandGroup
    Application.RefreshScreen = False
    
    ' Сканируем сетку: слева направо, сверху вниз
    yCurrent = yStart
    Do While yCurrent > yEnd  ' Y уменьшается сверху вниз
        xCurrent = xStart
        Do While xCurrent < xEnd  ' X увеличивается слева направо
            ' Определяем прямоугольник для текущей ячейки сетки
            Set selectionRect = New Rect
            selectionRect.Left = xCurrent
            selectionRect.Right = xCurrent + tileWidth
            selectionRect.Top = yCurrent
            selectionRect.Bottom = yCurrent - tileHeight
            
            ' Визуализируем прямоугольник (временный)
            Set feedbackRect = page.CreateRectangle( _
                selectionRect.Left, selectionRect.Top, _
                selectionRect.Right, selectionRect.Bottom)
            feedbackRect.Fill.UniformColor.RGBAssign 0, 255, 0  ' Зелёный цвет
            feedbackRect.Opacity = feedbackOpacity
            feedbackRect.Outline.Width = 0.1
            
            ' Находим объекты, пересекающие или содержащиеся в прямоугольнике
            Set shapesInTile = page.FindShapes(selectionRect, cdrIntersectsRect Or cdrInsideRect)
            
            ' Если найдено 2+ объекта — группируем
            If shapesInTile.Count >= 2 Then
                shapesInTile.Group
                groupCount = groupCount + 1
            End If
            
            ' Удаляем визуальный прямоугольник
            feedbackRect.Delete
            
            ' Переходим к следующему прямоугольнику по горизонтали
            xCurrent = xCurrent + tileWidth
        Loop
        
        ' Переходим к следующей строке по вертикали
        yCurrent = yCurrent - tileHeight
    Loop
    
    ' Включаем обновление экрана
    Application.RefreshScreen = True
    doc.EndCommandGroup
    
    ' Сообщение о результате
    If groupCount > 0 Then
        MsgBox "Сгруппировано " & groupCount & " прямоугольных областей.", vbInformation, "Готово"
    Else
        MsgBox "Не найдено областей с 2+ объектами для группировки.", vbExclamation, "Внимание"
    End If
End Sub
 
  • Спасибо
Реакции: Григор-313
Вот эту пробуй. Выделяешь нужные объекты, говоришь, на каком максимальном удалении находятся члены кластера (единой группы), получаешь. Пример приложен. То есть группирует между собой объекты, которые расположены достаточно близко друг к другу. Размеры задаются в миллиметрах
 

Вложения

Последнее редактирование:
  • Спасибо
Реакции: lev и Григор-313
Да, лучше сделать размеры побольше, чтобы ошибок округления было меньше. Я сначала масштабировал на 1000%. Но работает на удивление красиво :)
 
  • Спасибо
Реакции: Григор-313
Тут исправлена ошибка при вводе дробных чисел (можно ставить и точку, и запятую), и пример понагляднее.
Точнее описать так: "Указываем, на каком минимальном удалении находятся разные группы" (то есть ширину пробела между числами или словами и межстрочный интервал). Всё что ближе между собой - группируется
 

Вложения

Последнее редактирование:
  • Спасибо
Реакции: lev и Григор-313
Не тот кусок кода воткнул в предыдущем сообщении.. (

Код:
Sub TileScanAndGroup()
    Dim doc As Document
    Dim page As Page
    Dim bounds As Rect
    Dim tileWidth As Double, tileHeight As Double  ' Размеры прямоугольника (в пунктах)
    Dim xStart As Double, xEnd As Double, yStart As Double, yEnd As Double
    Dim xCurrent As Double, yCurrent As Double
    Dim selectionRect As Rect
    Dim shapesInTile As ShapeRange
    Dim groupCount As Long
    Dim feedbackRect As Shape  ' Визуальный прямоугольник
   
    ' Настройки
    tileWidth = 60      ' Ширина прямоугольника сканирования
    tileHeight = 40     ' Высота прямоугольника сканирования
    Const feedbackOpacity As Double = 0.2  ' Прозрачность визуальной сетки (0–1)
   
    Set doc = ActiveDocument
    Set page = doc.ActivePage
   
    ' Получаем границы страницы
    Set bounds = page.GetBoundingBox
    xStart = bounds.Left
    xEnd = bounds.Right
    yStart = bounds.Top
    yEnd = bounds.Bottom
   
    groupCount = 0
   
    ' Отключаем обновление экрана для скорости
    doc.BeginCommandGroup
    Application.RefreshScreen = False
   
    ' Сканируем сетку: слева направо, сверху вниз
    yCurrent = yStart
    Do While yCurrent > yEnd  ' Y уменьшается сверху вниз
        xCurrent = xStart
        Do While xCurrent < xEnd  ' X увеличивается слева направо
            ' Определяем прямоугольник для текущей ячейки сетки
            Set selectionRect = New Rect
            selectionRect.Left = xCurrent
            selectionRect.Right = xCurrent + tileWidth
            selectionRect.Top = yCurrent
            selectionRect.Bottom = yCurrent - tileHeight
           
            ' Визуализируем прямоугольник (временный)
            Set feedbackRect = page.CreateRectangle( _
                selectionRect.Left, selectionRect.Top, _
                selectionRect.Right, selectionRect.Bottom)
            feedbackRect.Fill.UniformColor.RGBAssign 0, 255, 0  ' Зелёный цвет
            feedbackRect.Opacity = feedbackOpacity
            feedbackRect.Outline.Width = 0.1
           
            ' Находим объекты, пересекающие или содержащиеся в прямоугольнике
            Set shapesInTile = page.FindShapes(selectionRect, cdrIntersectsRect Or cdrInsideRect)
           
            ' Если найдено 2+ объекта — группируем
            If shapesInTile.Count >= 2 Then
                shapesInTile.Group
                groupCount = groupCount + 1
            End If
           
            ' Удаляем визуальный прямоугольник
            feedbackRect.Delete
           
            ' Переходим к следующему прямоугольнику по горизонтали
            xCurrent = xCurrent + tileWidth
        Loop
       
        ' Переходим к следующей строке по вертикали
        yCurrent = yCurrent - tileHeight
    Loop
   
    ' Включаем обновление экрана
    Application.RefreshScreen = True
    doc.EndCommandGroup
   
    ' Сообщение о результате
    If groupCount > 0 Then
        MsgBox "Сгруппировано " & groupCount & " прямоугольных областей.", vbInformation, "Готово"
    Else
        MsgBox "Не найдено областей с 2+ объектами для группировки.", vbExclamation, "Внимание"
    End If
End Sub
1763634214109.png

Заработало!!!!
Круто! Круто! Круто!
Благодарю от всей души вас!