docxをpptxにするマクロ
大体フォーマットが決まっているdocxをpptxにするマクロが欲しいと言われたので備忘録。
VBA初心者なので処理に煩雑さや不具合ありそうだったらぜひ教えてください。
docxの大体のフォーマット
<Title> 1. テキスト。 2. テキスト。 改行される時もある。 3. テキスト。続く時もある。 ...
必要な要件
- 改行でページ追加
- 改行文字以外は一文字にならない運用のため、一文字しかない行は処理しない
- たまにShift + Enterで入るVertical Tabが入ることがあるため、vbCrに置換
- docxと同名のpptxファイルを作成
- 上寄せの横中央揃え
実際のコード
Sub docxをpptxに変換する()
' Replace vbVerticalTab with vbCr whole document
With ActiveDocument.Range.Find
.text = Chr(11)
.Replacement.text = Chr(13)
.Replacement.ClearFormatting
.Forward = True
.Wrap = wdFindContinue
.Execute Replace:=wdReplaceAll
End With
' Create new pptx
Dim pptApp As PowerPoint.Application
Dim file As Object
Set pptApp = New PowerPoint.Application
Set file = pptApp.Presentations.Add
Dim sideMargin As Integer: sideMargin = 38
Dim slideWidth As Integer: slideWidth = file.PageSetup.slideWidth - sideMargin * 2
Dim slideHeight As Integer: slideHeight = file.PageSetup.slideHeight - sideMargin * 2
For Each Paragraph In ActiveDocument.Paragraphs
Dim text As String: text = Paragraph.Range.text
If Len(text) <= 1 Then
GoTo EMPTY_LINE
End If
Set Slide = file.Slides.Add(file.Slides.Count + 1, Layout:=ppLayoutBlank)
Set textBox = Slide.Shapes.AddTextbox(msoTextOrientationHorizontal, Left:=sideMargin, Top:=sideMargin, Width:=slideWidth, Height:=slideHeight)
With textBox
With .TextFrame
.TextRange = text
.TextRange.Font.Name = "Meiryo UI"
.TextRange.Font.NameFarEast = "Meiryo UI"
.TextRange.ParagraphFormat.Alignment = ppAlignCenter
End With
.TextEffect.FontSize = 40
End With
EMPTY_LINE:
Next Paragraph
DoEvents
Dim fileName As String: fileName = Split(ActiveDocument.FullName, ".")(0) & ".pptx"
pptApp.ActivePresentation.SaveAs fileName:=fileName
' pptApp.Quit
' Set pptApp = Nothing
End Sub
コードの流れ
- docxで、vbVerticalTabをvbCrに全置換
- スライド新規作成
- スライドに追加するテキストボックスの余白やサイズを指定するための前準備
- docxの行取得
- 一文字なら何もせず次の行
- pptxに空のページ追加
- テキストボックスを指定の位置に追加
- テキストや指定したフォント、中央揃えを設定
- docxの行が終わるまで上記実行
- docxと同じパスに、同じ名前で保存
- 確認や修正のためにpptxは開いたままにする
部分ごと
コードの流れと該当のコード
1. docxで、vbVerticalTabをvbCrに全置換
With ActiveDocument.Range.Find
.text = Chr(11)
.Replacement.text = Chr(13)
.Replacement.ClearFormatting
.Forward = True
.Wrap = wdFindContinue
.Execute Replace:=wdReplaceAll
End With
Chr(11) = vbVerticalTab Chr(13) = vbCr
VBA Strings & Characters - Built-in Constants
2. スライド新規作成
Dim pptApp As PowerPoint.Application
Dim file As Object
Set pptApp = New PowerPoint.Application
Set file = pptApp.Presentations.Add
3. スライドに追加するテキストボックスの余白やサイズを指定するための前準備
スライドの幅高さ取得してmarginを考慮する
Dim sideMargin As Integer: sideMargin = 38
Dim slideWidth As Integer: slideWidth = file.PageSetup.slideWidth - sideMargin * 2
Dim slideHeight As Integer: slideHeight = file.PageSetup.slideHeight - sideMargin * 2
4. docxの行取得
マクロ実行しようと開いているwordのparagraphを取得して文字列取得
3で用意した設定使いながら、メイリオのフォントサイズ40の横中央揃えに設定
For Each Paragraph In ActiveDocument.Paragraphs
Dim text As String: text = Paragraph.Range.text
If Len(text) <= 1 Then
GoTo EMPTY_LINE
End If
Set Slide = file.Slides.Add(file.Slides.Count + 1, Layout:=ppLayoutBlank)
Set textBox = Slide.Shapes.AddTextbox(msoTextOrientationHorizontal, Left:=sideMargin, Top:=sideMargin, Width:=slideWidth, Height:=slideHeight)
With textBox
With .TextFrame
.TextRange = text
.TextRange.Font.Name = "Meiryo UI"
.TextRange.Font.NameFarEast = "Meiryo UI"
.TextRange.ParagraphFormat.Alignment = ppAlignCenter
End With
.TextEffect.FontSize = 40
End With
EMPTY_LINE:
Next Paragraph
- For文のcontinueを途中で呼びたい時はGoToを使うのでよいのかな?もっとよい方法あるの?
- この後にDoEvents設置してたけど、これ効果あるの?確認しないと
5. docxと同じパスに、同じ名前で保存
フルパス取得した上で拡張子だけ変える
Dim fileName As String: fileName = Split(ActiveDocument.FullName, ".")(0) & ".pptx"
pptApp.ActivePresentation.SaveAs fileName:=fileName
6. 確認や修正のためにpptxは開いたままにする
保存は5でしているので、閉じたい場合はコメントアウトを外す
' pptApp.Quit ' Set pptApp = Nothing
雑感
VSCodeでVBAの環境作ろうと思ったけど、text-scripting-vbaをマクロにコピーして実行したらエラー出た。まあいいかと思って大人しくVBEで実装。また触ることがあったら今度こそ整えよう...。(自分のPCでないけども。Office365普段使わないから入ってない。)
このシンプルな処理を実装するのに半日以上掛かった(´・ω・`)以前2つ開いているdocxの行を交互に抽出して新規作成したdocxの1ページに納めていく(最終的にPDFに保存したいという要望)マクロを作ったけど、全然覚えてなかった。人は忘却の生き物ですね。
疲れたけど、普段書かない言語書くのも面白いなー。関数への切り出ししないなら、せめてコードにちゃんとコメント入れないと、数日後の自分が分からなくなりそうだなぁ。
RecyclerViewで最後の行を中央揃えしたい
結論: FlexboxLayoutManagerを適用する
binding.recyclerView.layoutManager = FlexboxLayoutManager(requireContext()).also {
it.flexDirection = FlexDirection.ROW
it.justifyContent = JustifyContent.CENTER
}
行内の最大数の指定は出来ないから、幅計算してRecyclerViewの幅指定とかで実装するしかないのかな?
アイテムの数が少ないのが明確なら
<androidx.constraintlayout.helper.widget.Flow ... app:flow_wrapMode="chain" app:flow_horizontalStyle="packed" app:flow_maxElementsWrap="5"/>
アイテムの数が固定でないなら、programmaticallyにView作ってFlowのreferenceIdsに設定する
上2つを試したコードのPR
RecyclerView Multiline Centering by takattata · Pull Request #1 · takattata/TasksForStudy · GitHub
(もしコードご覧になって、この書き方すると危ないのではなどお気づきの点あったら教えてください^^)
flexbox-layout初めて使ったなぁ
Codelabメモ: Cast-enable an Android app

残った疑問点
- このアプリはSender AppでありReceiver Appであるということで良いの?
- SessionManagerがCastSession以外を扱うことはある?
- MiniControllerFragmentはvisibilityどう制御されてるの?(id変えても制御出来てた)
ここら辺確認しておこう
Google Cast Developer登録したし何か作ってみようかなぁ

