#vba #ms-word #powerpoint
#vba #ms-word #powerpoint
Вопрос:
Я хочу взять все статьи в документе Word и преобразовать их в презентацию PowerPoint.
1 статья = 1 слайд (если текст не помещается, уменьшите его, иначе создайте новый слайд).
Мне удалось распознать каждую часть статьи по ее стилю в Word. Я получаю текст по его стилю и вставляю его в слайд и так далее. Я извлекаю текст по абзацам (выделение.startOf и endOf не работали).
Я не нашел способа избежать наложения одного текста на другой.
Может быть, я могу получить то, что мне нужно, по координатам текстовых фреймов?
Что у меня есть до сих пор:
For Each StyleInWord In ActiveDocument.Paragraphs
If StyleInWord.Style = "NAME_OF_THE_ARTICLE" Then
wordText0 = StyleInWord.Range
Set pptLayout = pptPres.SlideMaster.CustomLayouts.Add(ppLayoutBlank)
Set pptSlide = pptPres.Slides.AddSlide(1, pptLayout)
If pptPres.Slides(1).Shapes(1).HasTextFrame Then
pptPres.Slides(1).Shapes(1).Delete
End If
With pptPres.PageSetup
.SlideSize = ppSlideSizeCustom
.SlideHeight = CentimetersToPoints(21.008)
.SlideWidth = CentimetersToPoints(28.011)
End With
Set mySlide = pptPres.Slides(1).Shapes.AddTextbox(msoTextOrientationHorizontal, CentimetersToPoints(1.31), CentimetersToPoints(3.73), CentimetersToPoints(24.34), CentimetersToPoints(12.57))
With mySlide.TextFrame.TextRange
.Text = wordText0
With .Font
.Size = 11 ' points
.Name = "Arial"
.Bold = msoTrue
End With
End With
End If
If StyleInWord.Style = "DESCRIPTION_OF_THE_ARTICLE" Then
wordText1 = StyleInWord.Range
Set mySlide = pptPres.Slides(1).Shapes.AddTextbox(msoTextOrientationHorizontal, CentimetersToPoints(1.31), CentimetersToPoints(5.73), CentimetersToPoints(24.34), CentimetersToPoints(12.57))
With mySlide.TextFrame
With .TextRange
.Text = wordText1
With .Font
.Size = 11 ' points
.Name = "Arial"
.Bold = msoTrue
End With
End With
End With
End If
If StyleInWord.Style = "MAIN_TEXT_OF_THE_ARTICLE" Then
Set mySlide = pptPres.Slides(1).Shapes.AddTextbox(msoTextOrientationHorizontal, CentimetersToPoints(1.31), CentimetersToPoints(7.73), CentimetersToPoints(24.34), CentimetersToPoints(12.57))
wordText2 = StyleInWord.Range
With mySlide.TextFrame
With .TextRange
.Text = wordText2
With .Font
.Size = 11 ' points
.Name = "Arial"
.Bold = msoTrue
End With
End With
End With
End If
Next StyleInWord
'Here i change the order, so the first slide i create will stay the first by the end of the forEachLoop
i = 1
For i = 1 To pptPres.Slides.Count
pptPres.Slides(i).MoveTo 1
Next i
Ответ №1:
Каждый раз, когда вы добавляете текстовое поле, вы устанавливаете верхнюю позицию просто на 2 см ниже предыдущей. При этом не учитывается высота предыдущего текстового поля.
Для этого есть очень простое решение. Текстовое поле имеет свойства как для вершины, так и для высоты, поэтому просто сохраните их в переменных. Таким образом, вы можете добавлять каждое новое текстовое поле непосредственно под предыдущим.
Ваш код также нуждается в некотором улучшении, поскольку некоторые настройки презентации, которые вы выполняете, должны быть вне цикла. Вы также должны переименовать mySlide
как pptTextBox
, чтобы переменная имела логическое имя, которое согласуется с другими.
Set pptLayout = pptPres.SlideMaster.CustomLayouts.Add(ppLayoutBlank)
не делает того, что вы думаете, и в этом нет необходимости. Презентация уже будет содержать пустой макет, услужливо названный «Пустой», поэтому все, что вам нужно сделать, это установить на него указатель, опять же вне цикла.
'do presentation setup outside the loop
With pptPres.PageSetup
.SlideSize = ppSlideSizeCustom
.SlideHeight = CentimetersToPoints(21.008)
.SlideWidth = CentimetersToPoints(28.011)
End With
'a presentation will already include a blank layout so there is no need to create one
For Each pptLayout In pptPres.SlideMaster.CustomLayouts
If pptLayout.Name = "Blank" Then Exit For
'pptLayout now points to the Blank layout
Next
For Each StyleInWord In ActiveDocument.Paragraphs
If StyleInWord.Style = "NAME_OF_THE_ARTICLE" Then
wordText0 = StyleInWord.Range
Set pptSlide = pptPres.Slides.AddSlide(1, pptLayout)
If pptPres.Slides(1).Shapes(1).HasTextFrame Then
pptPres.Slides(1).Shapes(1).Delete
End If
Set pptTextBox = _
pptPres.Slides(1).Shapes.AddTextbox(msoTextOrientationHorizontal, _
CentimetersToPoints(1.31), CentimetersToPoints(3.73), _
CentimetersToPoints(24.34), CentimetersToPoints(12.57))
With pptTextBox
With .TextFrame.TextRange
.Text = wordText0
With .Font
.Size = 11 ' points
.Name = "Arial"
.Bold = msoTrue
End With
End With
textBoxTop = .Top
textBoxHeight = .Height
End With
End If
If StyleInWord.Style = "DESCRIPTION_OF_THE_ARTICLE" Then
wordText1 = StyleInWord.Range
Set pptTextBox = _
pptPres.Slides(1).Shapes.AddTextbox(msoTextOrientationHorizontal, _
CentimetersToPoints(1.31), textBoxTop textBoxHeight, _
CentimetersToPoints(24.34), CentimetersToPoints(12.57))
With pptTextBox
With .TextFrame.TextRange
.Text = wordText1
With .Font
.Size = 11 ' points
.Name = "Arial"
.Bold = msoTrue
End With
End With
textBoxHeight = textBoxHeight .Height
End With
End If
If StyleInWord.Style = "MAIN_TEXT_OF_THE_ARTICLE" Then
Set pptTextBox = _
pptPres.Slides(1).Shapes.AddTextbox(msoTextOrientationHorizontal, _
CentimetersToPoints(1.31), textBoxTop textBoxHeight, _
CentimetersToPoints(24.34), CentimetersToPoints(12.57))
wordText2 = StyleInWord.Range
With pptTextBox
With .TextFrame.TextRange
.Text = wordText2
With .Font
.Size = 11 ' points
.Name = "Arial"
.Bold = msoTrue
End With
End With
textBoxHeight = textBoxHeight .Height
End With
End If
Next StyleInWord
'Here i change the order, so the first slide i create will stay the first by the end of the forEachLoop
i = 1
For i = 1 To pptPres.Slides.Count
pptPres.Slides(i).MoveTo 1
Next i
Комментарии:
1. это действительно очень помогло. Спасибо за комментарии о «Code Tone», я пришел из сферы автоматизации, многому нужно научиться. Большое вам спасибо!
2. Также мне было интересно. Теперь с помощью этого кода выше a я получаю все нужные мне абзацы, но я также копирую символ «Enter», который появляется в презентации в виде пустой строки, есть мысли о том, как избавиться от этого?
3. @TahirRuzbaev — сразу после назначения текста строке сократите строку на один символ, например
wordText0 = Left(wordText0, Len(wordText0) - 1)
4. Это тоже сработало, спасибо @Timothy Rylatt. Возможно, вы можете помочь мне с другой логикой этой программы. Теперь мне нужно уменьшить текст, если он не помещается на слайд (что я могу сделать, однако применимо для всего слайда, мне это нужно только для основного текста) Я подумал о добавлении тега к каждому абзацу основного текста и попытке работы с ним. Но, может быть, кто-нибудь может предложить другой способ?
5. @TahirRuzbaev — вам нужно опубликовать это как новый вопрос.