Вставленная форма не рассматривается как "последняя" форма - PullRequest
0 голосов
/ 04 июля 2018

Я нахожусь в процессе автоматизации создания отчета PowerPoint из электронной таблицы Excel. У меня процесс работает до тех пор, пока я не вставлю таблицу.

Я вставляю таблицу в PowerPoint, используя PPApp.CommandBars.ExecuteMso ("PasteSourceFormatting"), и таблица отображается в виде фигуры на моем слайде (третья фигура).

Чтобы сослаться на новую фигуру, которую я использовал Set pShape = Slide2.Shapes(Slide2.Shapes.Count), но теперь, когда я вставляю, pShape присваивается «Форма 2» (не «Форма 3»). Есть ли что-то, что нужно сделать между вставкой и назначением объекта?

Код ниже, прокомментировал, где возникает проблема. (Полный код удален; видимый здесь )

'Copy tables from Excel
Set rng = ws.Range("A:A")
rng.ColumnWidth = 22.75
Set rng = ws.Range("A4:C27")

'Copy the table range
Application.CutCopyMode = False
rng.Copy
Application.Wait (Now + TimeValue("0:00:02"))

'The issue occurs here!!! '-------------------------------------
'Paste the table in to the slide
Slide2.Select
PPApp.CommandBars.ExecuteMso ("PasteSourceFormatting")

'Name the new shape object
Set pShape = Slide2.Shapes(Slide2.Shapes.Count)
pShape.Name = "Slide_2_Table_1"
pShape.LockAspectRatio = False

1 Ответ

0 голосов
/ 04 июля 2018

'Shapes.Count' Index Индекс формы #!

.Count не совпадает с верхним пределом текущей формы .Index чисел.

Систему нумерации легче понять, перечислив все фигуры в документе:

Sub ListShapes()
    'hit CTRL+G to view output in Immediate Window
    Dim sh As Shape, sld As Slide, idx As Long
    Set sld = ActivePresentation.Slides(1) '<-- change to your slide number
    For Each sh In sld.Shapes
        idx = idx + 1
        Debug.Print "Shape ID#" & sh.Id, "Index #" & idx, "Name: " & sh.Name
    Next sh
    Debug.Print "Count of shapes: " & sld.Shapes.Count
End Sub

ПРИМЕЧАНИЕ: Внизу этого поста альтернативный код для Excel !

Для демонстрации мы можем добавить фигуры в новый документ:

  • Сначала добавьте один прямоугольник вручную, нажав Insert (на ленте)
  • [При использовании Excel нажмите Illustrations], затем Shapes и символ прямоугольника. image▯">
  • Нарисуйте фигуру, затем нажмите Ctrl + C , чтобы скопировать ее, и нажмите Ctrl + C четыре раза, чтобы вставить 4 копии.
  • Запустите описанную выше процедуру, и результат будет:

    Shape ID#2 Index #1 Name: Rectangle 1
    Shape ID#3 Index #2 Name: Rectangle 2
    Shape ID#4 Index #3 Name: Rectangle 3
    Shape ID#5 Index #4 Name: Rectangle 4
    Shape ID#6 Index #5 Name: Rectangle 5
    Count of shapes: 5         

Обратите внимание, что Index не является свойством этого объекта, но он учитывается для того, чтобы Excel сохранял фигуры в памяти (так же, как порядок, возвращаемый оператором For Each..Next.

  • Вы можете доказать это, запустив:

    Debug.Print ActivePresentation.Slides(1).Shapes(5).Name  
    

    ... которые в этом случае возвращают Rectangle 5.

Еще один способ понять, как Excel хранит фигуры, - Окно просмотра . Добавьте разрыв или Stop в середине цикла, затем выделите ws.Shapes, щелкните его правой кнопкой мыши, выберите Add Watch... и нажмите OK. Просмотрите дерево, чтобы обнаружить различные свойства / атрибуты фигур в документе.


  • Далее, если мы удалим"средний прямоугольник" и снова запустим описанную выше процедуру, мы получим:

    Shape ID#2 Index #1 Name: Rectangle 1
    Shape ID#3 Index #2 Name: Rectangle 2
    Shape ID#5 Index #3 Name: Rectangle 4
    Shape ID#6 Index #4 Name: Rectangle 5
    Count of shapes: 4         

ID и Name оставшихся фигур не изменяются, но Index перенумерован для отражения нового «порядка».

... таким образом, чтобы вернуть имя Rectangle 5, теперь нам нужно использовать:

Debug.Print ActivePresentation.Slides(1).Shapes(4).Name  

Ссылаясь на фигуры (включая элементы управления )

Когда вы ссылаетесь на фигуру по номеру, например .Shapes(?), вы имеете в виду фигуру Индекс Number , а не ID. Индексные номера назначаются динамически по мере необходимости, поэтому не является стабильным методом для ссылки на форму.

  • Следовательно, .Count не имеет отношения к форме Индекс .

В идеале вы должны ссылаться на форму по номеру .Name или .ID. Если вы генерируете фигуры динамически, в идеале вы должны хранить список фигур в массиве или коллекции, чтобы вы могли просматривать список по мере необходимости.


Получить "Последняя форма создана"

Если единственная причина использования порядкового номера состоит в том, чтобы получить «последнюю созданную фигуру», то вы можете использовать функцию, подобную этой, чтобы получить порядковый номер:

Function idxLastShape(slideNum As Long) As Long
    Dim sh As Shape
    For Each sh In ActivePresentation.Slides(slideNum).Shapes
        idxLastShape = idxLastShape + 1
    Next sh
End Function

Пример использования:

Debug.Print idxLastShape(1) 'Returns index of last shape on slide#1

ПРИМЕЧАНИЕ: Внизу этого поста альтернативный код для Excel !


В качестве альтернативы, вы можете сделать так, чтобы функция возвращала ссылку на фактический объект формы , а не на число, например:

Function LastShape(slideNum As Long) As Shape
    Dim sh As Shape
    For Each sh In ActivePresentation.Slides(slideNum).Shapes
        Set LastShape = sh
    Next sh
End Function

... чтобы вы могли получить имя "последней фигуры" с помощью:

Debug.Print LastShape(1).Name

Удалить самую последнюю созданную фигуру

Используя вышеописанную функцию, вы можете использовать любые методы, которые вы обычно используете с фигурами. Например, вы можете удалить «последнюю фигуру», созданную на слайде № 1:

LastShape(1).Delete

Caution ВНИМАНИЕ!

Примеры в посте (включая пример удаления!) без разбора, какой тип фигуры они возвращают / редактируют / удаляют!

Существует десятков типов фигур , от графики до звука / видео и элементов управления . Вы можете отфильтровать формы, перечисляемые этими процедурами, используя свойство .Type объекта Shape, а также другие методы. Частичный список здесь , а дополнительную информацию можно найти по ссылкам ниже.


Альтернативный код для Excel:

Список всех фигур на рабочем листе (Excel)

Sub ListShapes()
    'hit CTRL+G to view output in Immediate Window
    Dim sh As Shape, ws As Worksheet, idx As Long
    Set ws = Sheets("Sheet1") '<-- change to your worksheet name
    For Each sh In ws.Shapes
        idx = idx + 1
        Debug.Print "Shape ID#" & sh.ID, "Index #" & idx, "Name: " & sh.Name
    Next sh
    Debug.Print "Count of shapes: " & Sheets("Sheet1").Shapes.Count
End Sub

Возвращает порядковый номер «последней фигуры» (Excel)

Function idxLastShape(shtName As String) As Long
    Dim sh As Shape
    For Each sh In Sheets(shtName).Shapes
        idxLastShape = idxLastShape + 1
    Next sh
End Function

Пример использования: Debug.Print idxLastShape("Sheet1")


Возврат ссылки на объект "последняя фигура" (Excel)

Function LastShape(shtName As String) As Shape
    Dim sh As Shape
    For Each sh In Sheets(shtName).Shapes
        Set LastShape = sh
    Next sh
End Function

Пример использования: Debug.Print LastShape("Sheet1").Name


Дополнительная информация:

Другие способы копирования из Excel в Powerpoint:

...