はじめに
概要
MSOfficeの書式付きテキストから一部を取得(抽出)する方法について、備忘録がてらまとめます。
ここでいう「書式付きテキスト」は以下のものです。
| Office | 対象 |
|---|---|
| Excel | 挿入したテキストボックスや、形状内のテキスト。 |
| PowerPoint | 通常使用する各種形状内のテキスト。 |
| Word | 本文および、挿入したテキストボックスや形状内のテキスト。 |
なぜ一部を取得する必要があるのか
書式付きのテキストの場合、それぞれの場所で書式が異なります。
そのため無造作に中のテキストを変更してしまうと、意図しない結果になることがあります(書式がすべて同じになるなど)。
意図しない動作を防ぐためには、必要な部分だけを取得して操作を行う必要があります。
今回の内容
以下のサイトの内容に加えて、類似メソッドの紹介等を含めたものとなります。
TextRange.RunsメソッドとTextRange2.Runsプロパティ:パワーポイントマクロ・PowerPoint VBAの使い方-TextFrame・TextRange
その他
内容の間違い等あれば指摘していただけると助かります。
特に、Wordはあまり使用したことがないので誤りが含まれる可能性が高いです。
対象オブジェクト
今回説明の対象とするオブジェクトは以下の通りです。
Office.TextRange2
Microsoft Office X.X Object Library内のオブジェクトです。
Excelの書式付きテキスト、PowerPointの書式付きテキストの操作に使用できます~~(Wordでも使用できそうですがアクセス方法がわかりません)~~。
2017/1/16 追記
Wordの場合について詳しい解説を頂きました。
Word VBAでTextFrame2・TextRange2を利用する:ワードマクロ・Word VBAの使い方-Shape・図形
基本的にはWordでOffice.TextRange2は使用できないと思って良さそうです。
2017/1/16 追記ここまで
MSOffice共通のオブジェクトなのでコードの移植もしやすいです。
PowerPoint.TextRange
Microsoft PowerPoint X.X Object Library内のオブジェクトです。
ライブラリが示す通り、PowerPointの書式付きテキストの操作に使用できます。
Office.TextRange2と比較すると、やや機能が少ないです。
Word.Range
Microsoft Word X.X Object Library内のオブジェクトです。
ライブラリが示す通り、Wordの書式付きテキストの操作に使用できます。
Wordの本文のオブジェクトでもあるので、多くの機能が含まれています。
Excel.Rangeと名前が同じですが、全く別物なので注意が必要です。
オブジェクトへのアクセス方法
各対象オブジェクトへのアクセス方法を簡単にまとめます。
Excel
基本的にExcel.ShapeまたはExcel.ShapeRangeオブジェクトから辿っていきます。
式.TextFrame2.TextRange
式:Excel.ShapeまたはExcel.ShapeRangeオブジェクト
サンプルコード
'現在選択している形状の持つOffice.TextRange2を取得する
'セルを選択している場合、テキストを持っていない場合はNothing
'複数選択されている場合は後処理が必要(ForEach)
Function SelectedTextRangeXl() As Office.TextRange2
'選択対象チェック
Select Case VBA.TypeName(Excel.Selection)
Case "Range" 'セルを選択中
GoTo Fail
Case Else
'Next
End Select
'今選択している形状群
Dim selShpRng As Excel.ShapeRange
Set selShpRng = Excel.Selection.ShapeRange
'Shape/ShapeRange→TextFrame/TextFrame2→TextRange
Dim selTxtFrm As Office.TextFrame2
Set selTxtFrm = selShpRng.TextFrame2
'テキスト存在チェック
If selTxtFrm.HasText Then
Set SelectedTextRangeXl = selTxtFrm.TextRange
Else
GoTo Fail
End If
Exit Function
Fail:
Set SelectedTextRangeXl = Nothing
Exit Function
End Function
PowerPoint
基本的にPowerPoint.ShapeまたはPowerPoint.ShapeRangeオブジェクトから辿っていきます。
式.TextFrame.TextRange 'PowerPoint.TextRange
式.TextFrame2.TextRange 'Office.TextRange2
式:PowerPoint.ShapeまたはPowerPoint.ShapeRangeオブジェクト
サンプルコード
Office.TextRange2を取得する場合のコードです。
最初の条件判定部分を除けば、上記のSelectedTextRangeXlとほぼ同じことがわかるかと思います。
'選択しているテキスト、または形状の持つOffice.TextRange2を取得する
'形状・テキスト以外を選択している場合、テキストを持っていない場合はNothing
'テキストを選択している場合はそのテキストを示すOffice.TextRange2
'形状を複数選択されている場合は後処理が必要(ForEach)
Function SelectedTextRangePpt() As Office.TextRange2
Dim mySel As PowerPoint.Selection
Set mySel = PowerPoint.ActiveWindow.Selection
'選択対象チェック
Select Case mySel.Type
Case ppSelectionNone, ppSelectionSlides '未選択 Or スライドを選択中
GoTo Fail
Case ppSelectionText 'テキストにカーソルがある
'特定の文字列を選択していた場合
If mySel.TextRange2.Length <> 0 Then
Set SelectedTextRangePpt = mySel.TextRange2
Exit Function
End If
'何も文字を選択していない場合は形状選択の場合とみなす。
Case ppSelectionShapes
'Next
End Select
'今選択している形状群
Dim selShpRng As PowerPoint.ShapeRange
Set selShpRng = mySel.ShapeRange
'Shape/ShapeRange→TextFrame/TextFrame2→TextRange
Dim selTxtFrm As PowerPoint.TextFrame2
Set selTxtFrm = selShpRng.TextFrame2
'テキスト存在チェック
If selTxtFrm.HasText Then
Set SelectedTextRangePpt = selTxtFrm.TextRange
Else
GoTo Fail
End If
Exit Function
Fail:
Set SelectedTextRangePpt = Nothing
Exit Function
End Function
Word
本文の場合はWord.DocumentのRangeから、
形状内テキストの場合はWord.ShapeRangeのTextFrame.TextRangeから取得できそうです。
あまり触ったことがないのでこのあたりで。
WordのVBAに関しては以下のサイトが詳しいです。
書式付きテキストから一部を取得(抽出)する
とっちらかってきましたが、本題である「書式付きテキストから一部を取得(抽出)する」方法を確認していきます。
Office.TextRange2・PowerPoint.TextRangeオブジェクトでは、以下のメソッドを使用することで取得単位毎に分解された一部を取得することができます。
| メソッド名 | 取得単位 |
|---|---|
| Characters | 文字 |
| Lines | 行 |
| Paragraphs | 段落 |
| Runs | 書式 |
| Sentences | 文章 |
| Words | 単語 |
Word.Rangeの場合も同名のプロパティ(オブジェクト)があればそちらから取得することができます。
共通動作
StartとLengthの省略可能引数があります。
両方省略した場合は、含まれる文字列を取得単位ごとに分解した全てのTextRangeをItemに持つTextRangeを返します。
最初のTextRange → メソッド戻り値のTextRange → ItemプロパティのTextRange(取得単位毎)
Characters
元のTextRangeを、1文字毎に区切って取得できます。
ちなみに
純粋な改行Shift+Enterは
Chr(11)=vbVerticalTab
改段落Enterは
Chr(13)=vbCr
で表されます。
Lines
元のTextRangeを、改行・改段落・自動折り返しによる改行毎(=表示されている行毎)に区切って取得できます。
Paragraphs
元のTextRangeを、改段落毎に区切って取得できます。
Runs
元のTextRangeを、書式毎に区切って取得できます。
Officeのデフォルトだと、半角文字には英数字用フォント・全角文字には日本語用フォントが割り当てられるため、日本語と英語で書式が異なると判定され分割されます。
書式を維持しながら単語を差し替えたい場合などに便利です。
Sentences
元のTextRangeを、文章毎に区切って取得できます。
文章の区切りとして扱われるのは改段落と「. 」(ドット + スペース)のようです。
つまり、日本語の文章の分割にはほぼ使えないと思ってよいです。
Words
元のTextRangeを、単語毎に区切って取得できます。
日本語の文章で使用する場合、Sentencesに比べればいくらかましですが、精度に期待してはいけません。
その他参考情報
段落の増殖
TextRangeを操作したとき、場合によっては段落が増えることがあります。
明確な条件はわかりませんが、どこかのタイミングで末尾にvbCrが自動付与されるようです。
リンク
TextRange2 Object (Office) | Microsoft Docs
VBA 似ているようで違うExcel・Word・PowerPointのシェイプをオブジェクトブラウザーで比較する - t-hom’s diary