Word (VBA) |
|
(Windows 11 Home : Word 2013)
wordテキストボックス内の操作
投稿日時: 25/08/27 11:06:24
投稿者: Tetsuyan
|
|---|---|
|
よろしくお願いします。
Sub tbxSentence()
'貼り付けてフォント操作
Call tbxSet
Selection.Paste
Selection.MoveUp Unit:=wdLine, Count:=1
Selection.HomeKey Unit:=wdLine
Selection.MoveDown Unit:=wdLine, Count:=1, Extend:=wdExtend
Selection.Font.Size = 8
Selection.MoveLeft Unit:=wdCharacter, Count:=1
Selection.TypeText Text:="〔意味〕"
Selection.HomeKey Unit:=wdLine
Selection.MoveDown Unit:=wdLine, Count:=1
Selection.MoveDown Unit:=wdLine, Count:=1, Extend:=wdExtend
Selection.Font.Name = "Century Schoolbook"
Selection.Font.Size = 13
Selection.EndKey Unit:=wdStory
Selection.MoveDown Unit:=wdLine, Count:=1, Extend:=wdExtend
Selection.TypeParagraph
End Sub
Sub tbxSet()
' wrodテキストボックスの作成
'
Dim tgtDoc As Document
Set tgtDoc = ActiveDocument
Dim tb As Word.Shape
Set tb = tgtDoc.Shapes.AddTextbox( _
Orientation:=msoTextOrientationHorizontal, _
Left:=0, Top:=0, _
Width:=450.5276, _
Height:=106.0945)
tb.WrapFormat.Type = wdWrapInline
With tb
With .Line
'テキストボックスの体裁設定
End With
With .TextFrame
.TextRange.Select
.MarginTop = 11
.MarginBottom = 11
.MarginLeft = 11
.MarginRight = 0
.TextRange.Select
End With
End With
End Sub
|
|
|
|
投稿日時: 25/08/28 09:13:35
投稿者: sk
|
|---|---|
引用: ・1 つのテキストファイルの中に「日本語の文とその英訳文の組み合わせ」が 複数セット( 1 セット以上)格納されている。 ・それぞれの「日本語の文」はテキストファイルの奇数行に、 「英訳文」はその直下の行(偶数行)に記録されている。 ・それぞれの行に記録されているのは常に 1 つの文だけである ( 1 つの行の中に 2 つ以上の文を記述しない)。 ・1 つの文の途中で改行されることはない。 以上のような前提であるとして、 引用: 「文字列の範囲選択とコピー」はユーザーが手動で行なう、ということでしょうか。 それとも、その部分の操作も含めて自動化したいということでしょうか。 もし後者(自動化)を想定されている場合、コピー対象となる文字列範囲 (どの和英文セットをコピーするのか)はどのようにして決定されるのでしょうか。 引用: 何故貼り付け先が「テキストボックスの中」なのでしょうか。 そもそも、最終成果物としてどのような Word 文書を作成なさろうとされているのでしょうか。 仮に「日本語の文とその英訳文の組み合わせが記述されたテキストボックス」を 1 つの Word 文書の中に複数個挿入することを目的とされているのであれば、 それぞれのテキストボックスの配置をどのように制御されるつもりなのでしょうか。 |
|
|
|
投稿日時: 25/08/28 13:11:00
投稿者: Tetsuyan
|
|---|---|
|
sk様、ご回答とご質問頂きありがとうございます。
引用: おっしゃる通りです。テキストエディタ(メモ帳)に、 1行目は日本語、2行目は英文、3行目は日本語、4行目は英文…と300行ほどあり、 それをテキストエディター内で手動でコピーしてから wordに移動して、自分で割り当てたキーコマンドで「Sub tbxSentence()」を呼び出しています。 引用: 中学生に重要英文の和訳と文法解析をさせるために、各英文(日本語訳付きの2行)を区切りとして、それぞれを一定の大きさの枠(テキストボックス)に入れて表示したいと考えています。 各英文が入ったテキストボックスは、中学生が和訳を書いたり、線を引いたり、メモを記入したりするために、縦36mm横17mm位の大きさで設定しています。 できあがりとしては横長のテキストボックスが、数ミリの間隔をあけて、word文書内に縦にズラッと並べるイメージです。 テキストボックスを選ぶのは、体裁上「枠」にこだわったからです(^^;)。 もし、300行のテキストが一発で、2行ずつ150個のテキストボックスに収まる方法があるのなら、ご教示いただきたいところですが、私には想像もできません。 なお、現在の仕様では、和訳は〔意味〕としてテキストボックス内に残ってしまいますが、生徒用では和訳部分を消してから配布するつもりです。 実は、前回の投稿に対するsk様から頂いたコードからヒントを得て、この英文解釈文書の作成にとりかかりました。和訳の削除はsk様から頂いたコードをもとに何とか自力でできそうです。 何卒宜しくお願い致します。 |
|
|
|
投稿日時: 25/08/28 21:20:28
投稿者: sk
|
|---|---|
引用: では、とりあえずの叩き台としてサンプルを例示します。 内容が少々長いので、複数に分けて投稿します。 ------------------------------------------------------------------------- Sub ConvertTextFileToWordDocument()
'Microsoft Scripting Rumtime の定数の宣言
Const ForReading = 1, ForWriting = 2, ForAppending = 8
Const TristateUseDefault = -2, TristateTrue = -1, TristateFalse = 0
Dim strTextFilePath As String
'読み込み対象となるテキストファイルの絶対パスを指定
strTextFilePath = ThisDocument.Path & "\Examples.txt"
Dim objFSO As Object 'Scripting.FileSystemObject
'FileSystemObject の新規インスタンスを生成
Set objFSO = CreateObject("Scripting.FileSystemObject")
'ファイルの有無をチェック
If objFSO.FileExists(strTextFilePath) = False Then
'見つからなければエラーメッセージを返す
MsgBox "指定されたパス'" & strTextFilePath & "'に該当するファイルが見つかりません。", _
vbExclamation, _
"ファイル参照エラー"
Set objFSO = Nothing
'プロシージャを抜ける
Exit Sub
End If
Dim objTextStream As Object 'Scripting.TextStream
'テキストファイルを開く
Set objTextStream = objFSO.OpenTextFile(FileName:=strTextFilePath, _
IOMode:=ForReading, _
Format:=TristateUseDefault)
'空のテキストファイルである場合はプロシージャを抜ける
If objTextStream.AtEndOfStream Then
objTextStream.Close
Set objTextStream = Nothing
Set objFSO = Nothing
Exit Sub
End If
Dim docNew As Word.Document
Dim rngTarget As Word.Range
Dim lngParagraphCount As Long
Dim strJapanese As String
Dim strEnglish As String
'Word 文書の作成処理を呼び出し、作成された文書を参照する
Set docNew = CreateDocument
'テキストファイルの操作
With objTextStream
'ファイルポインタが末尾に達するまでループ
Do Until .AtEndOfStream
'現在の行(奇数行)全体を和訳文として読み込む
strJapanese = .ReadLine
'ファイルポインタがまだ末尾に達していない場合
If .AtEndOfStream = False Then
'更に次の行(偶数行)全体を英文として読み込む
strEnglish = .ReadLine
End If
'段落カウンタを1増やす
lngParagraphCount = lngParagraphCount + 1
'段落カウンタの値、和訳文、英文をイミディエイトウィンドウに出力(デバッグ用)
Debug.Print lngParagraphCount & vbTab & strJapanese & vbTab & strEnglish
'Word 文書の最後の段落の文字列範囲を参照する
Set rngTarget = docNew.Paragraphs.Last.Range
'末尾の改行文字を参照範囲から除外する
rngTarget.MoveEnd Unit:=wdCharacter, Count:=-1
'テキストボックスの挿入先として、現在の参照範囲を選択する
rngTarget.Select
'例文テキストボックスの作成処理を呼び出す
CreateExampleBox docNew, strJapanese, strEnglish
Set rngTarget = Nothing
'読み込んだ和訳文と英訳を初期化
strJapanese = ""
strEnglish = ""
'ファイルポインタがまだ末尾に達していない場合
If .AtEndOfStream = False Then
'Word 文書に新しい段落を挿入
docNew.Paragraphs.Add
End If
Loop
End With
'テキストファイルを閉じる
objTextStream.Close
Set objTextStream = Nothing
Set objFSO = Nothing
docNew.Activate
MsgBox lngParagraphCount & " 組の例文を読み込み、新規文書に挿入しました。", _
vbInformation, _
"実行完了"
Set docNew = Nothing
End Sub------------------------------------------------------------------------- |
|
|
|
投稿日時: 25/08/28 21:22:27
投稿者: sk
|
|---|---|
|
-------------------------------------------------------------------------
'Word 文書の新規作成と初期設定を行なう処理
Private Function CreateDocument() As Word.Document
Dim docNew As Word.Document
'Word 文書の新規作成
Set docNew = Documents.Add
'スタイル[標準]の操作
With docNew.Styles(wdStyleNormal)
'フォントの設定
With .Font
.Size = 10.5
.Name = "游ゴシック"
End With
End With
'ページ設定の操作
With docNew.PageSetup
'用紙サイズ
.PaperSize = wdPaperA4
'用紙の向き
.Orientation = wdOrientPortrait
'ページ上余白
.TopMargin = MillimetersToPoints(20)
'ページ下余白
.BottomMargin = MillimetersToPoints(25)
'ページ左余白
.LeftMargin = MillimetersToPoints(20)
'ページ右余白
.RightMargin = MillimetersToPoints(20)
'用紙の端からヘッダーまでの距離
.HeaderDistance = MillimetersToPoints(15)
'用紙の端からフッターまでの距離
.FooterDistance = MillimetersToPoints(17.5)
'1ページ当たりの行数
.LinesPage = 42
End With
'作成した文書への参照を戻り値として返す
Set CreateDocument = docNew
End Function------------------------------------------------------------------------- |
|
|
|
投稿日時: 25/08/28 21:24:32
投稿者: sk
|
|---|---|
|
-------------------------------------------------------------------------
'例文テキストボックスの作成処理
Private Function CreateExampleBox(Target As Word.Document, JapaneseSentence As String, EnglishSentence As String) As Word.Shape
Dim tbxNew As Word.Shape
'横書きテキストボックスの新規作成
Set tbxNew = Target.Shapes.AddTextbox(Orientation:=msoTextOrientationHorizontal, _
Left:=0, _
Top:=0, _
Width:=MillimetersToPoints(170), _
Height:=MillimetersToPoints(36))
Dim rngJapanese As Word.Range
Dim rngEnglish As Word.Range
With tbxNew
'[文字列の折り返し]プロパティの設定
With .WrapFormat
.Type = wdWrapInline
.DistanceLeft = 0
.DistanceTop = 0
.DistanceRight = 0
.DistanceBottom = 0
End With
'レイアウト枠の操作
With .TextFrame
'各マージンを設定
.MarginTop = 11
.MarginBottom = 11
.MarginLeft = 11
.MarginRight = 0
End With
'レイアウト枠の文字列領域の段落コレクションを操作
With .TextFrame.TextRange.Paragraphs
'2つめの段落を追加
.Add
'1つめ(和訳文用)の段落の文字列範囲全体を参照する
Set rngJapanese = .Item(1).Range
'2つめ(英文用)の段落の文字列範囲全体を参照する
Set rngEnglish = .Item(2).Range
End With
'和訳文用の文字列範囲の操作
With rngJapanese
'フォントの設定
With .Font
'フォントサイズ
.Size = 9
'全てのフォント
.Name = "游ゴシック"
End With
'末尾の改行文字を参照範囲から除外する
.MoveEnd Unit:=wdCharacter, Count:=-1
'現在の参照範囲の後ろにキャプション"〔意味〕"を挿入
.InsertAfter "〔意味〕"
'更に和訳文を挿入
.InsertAfter JapaneseSentence
End With
'英文用の文字列範囲の操作
With rngEnglish
'フォントの設定
With .Font
'フォントサイズ
.Size = 13
'英数字のフォント
.NameAscii = "Century"
End With
'末尾の改行文字を参照範囲から除外する
.MoveEnd Unit:=wdCharacter, Count:=-1
'現在の参照範囲の後ろに英文を挿入
.InsertAfter EnglishSentence
End With
Set rngJapanese = Nothing
Set rngEnglish = Nothing
End With
'作成したテキストボックスへの参照を戻り値として返す
Set CreateExampleBox = tbxNew
End Function-------------------------------------------------------------------------
|
|
|
|
投稿日時: 25/08/28 21:33:23
投稿者: sk
|
|---|---|
|
以上の 3 つのプロシージャを任意のマクロ有効文書の標準モジュールに貼り付けた上、
引用: なお、上記のコードは「マクロ有効文書が保存されているフォルダ上に "Examples.txt" という名前のテキストファイルが存在する」 という状況を仮定したものです。 |
|
|
|
投稿日時: 25/08/29 10:29:32
投稿者: Tetsuyan
|
|---|---|
|
sk様、ご回答ありがとうございます。
引用: 恥ずかしながら、上記を行った後、 3つのプロシージャをword文書内で、どう実行すればいいかがわかりません。 いずれかのプロシージャをキーコマンドに割り当てるということでしょうか。 恐縮ですが、教えて下さい。 |
|
|
|
投稿日時: 25/08/29 15:13:37
投稿者: sk
|
|---|---|
引用: どのような方法でも構いませんので、ConvertTextFileToWordDocument プロシージャを 実行して下さい。 ・3 つのプロシージャが記述された標準モジュールのコードウィンドウで表示し、 ConvertTextFileToWordDocument プロシージャのいずれかのコードに カーソルがある状態で[Sub/ユーザーフォームの実行]コマンドを呼び出す (または F5 キーをクリックする)。 ・Word アプリケーションより[開発]タブ -> [コード]グループ -> [マクロ]をクリックし、 マクロリスト上の ConvertTextFileToWordDocument プロシージャを選択した状態で [実行]ボタンをクリックする。 ・ConvertTextFileToWordDocument プロシージャを呼び出すための インターフェース(ユーザーフォームなど)を別途作成する。 |
|
|
|
投稿日時: 25/08/31 15:59:54
投稿者: Tetsuyan
|
|---|---|
|
sk様、
|
|
|
|
投稿日時: 25/09/01 18:56:31
投稿者: sk
|
|---|---|
引用: 引用: テキストファイルの文字コードセットが Shift_JIS 以外である (例えば Unicode など)ならば、それに合わせたコードに 書き換えるだけです。 引用: Dim strTextFilePath As String
Dim lngFormat As Long
With Application.FileDialog(msoFileDialogOpen)
.Title = "テキストファイルの選択"
.AllowMultiSelect = False
With .Filters
.Clear
.Add "テキスト", "*.txt"
.Add "Unicode テキスト", "*.txt"
End With
If .Show = False Then
Exit Sub
End If
strTextFilePath = .SelectedItems(1)
If .FilterIndex = 2 Then
lngFormat = TristateTrue
Else
lngFormat = TristateUseDefault
End If
End With
引用: 'テキストファイルを開く
Set objTextStream = objFSO.OpenTextFile(FileName:=strTextFilePath, _
IOMode:=ForReading, _
Format:=TristateUseDefault)
'テキストファイルを開く
Set objTextStream = objFSO.OpenTextFile(FileName:=strTextFilePath, _
IOMode:=ForReading, _
Format:=lngFormat)
引用: 引用: 既に作成済みのテキストファイルが複数個存在する状況においては、 それぞれのテキストファイルを直接読み込んだ方が簡単ではないでしょうか。 「複数個あるテキストファイル内の(全ての、あるいは一部の)文字列を 1 つのWord 文書上に(本文として)統合する」といった作業を行なった上で 「 2 段落(≠行)ずつテキストボックスに出力する」という処理を実行するのは 二度手間であるようにしか思えません。 引用: 「ユーザーが手動で任意の文字列を範囲選択する」という要件が どうしても必須であるのであれば、話は別ですが。 引用: 引用: 「範囲選択したい文字列が含まれている Word 文書」と 「テキストボックスの追加先となる Word 文書」が同一である、 ということでしょうか。 |
|
|
|
投稿日時: 25/09/02 11:46:45
投稿者: Tetsuyan
|
|---|---|
|
sk様、ご回答ありがとうございます。
引用: 引用: 作りたい「英文解釈」教材は、 ●学年別、単元別(受動態、現在完了・・・など)に分けて複数冊作成予定です。 各単元の始めには解説文を加えたり、体裁上のテキストボックスや図形を配置することも考えています。 また、完成した教材にあとから当該テキストボックスを付加する可能性もあります。 ●テキストファイル内の「2行の意味付き英文セット」はすべてを利用するのでなく、選別する必要がある。 ●VBA を使って、PC上にあるテキストファイルを目に見えない形で開き、word文書に読み込んで、操作するという、sk様にいただいたコードの流れは、初心者の私には非常に高度で複雑なものに感じられたため、もしかしたら「とても不合理で、無理のあること」を求めていたのかもと感じました。sk様には検討不足で言葉足らずな私の要望に、柔軟に対応してもらったのかも、と感じてしまいました。 以上のことから、前回の「word文書内での処理」を思いつき、質問するに至った次第です。 引用: 同一のword文書内での処理を想定していました。 ファイルをまたぐ処理よりも、単一の文書内の方が簡単と考えたためです。 同一ファイルであることにこだわってはいませんので、同一ファイル内の操作の方がむしろ不合理であるなら、変えたいと思います。 何卒宜しくお願い致します。 |
|
|
|
投稿日時: 25/09/03 12:20:46
投稿者: sk
|
|---|---|
引用: 引用: 引用: では、問題の前提を少し変えた方が良さそうですね。 引用: ・「 2 行の意味付き英文セット」のいくつかが、ある Word 文書の本文上に記述されている。 (テキストファイルから Word 文書へのコピーアンドペーストは既に終わっている) ・上記の状況下において、ユーザーはその Word 文書の本文内の任意の文字列/段落を範囲選択する。 ・選択中の範囲に含まれる全ての段落を、前述の仕様に応じた形でテキストボックスに変換する マクロ( ConvertToExampleBox プロシージャ)を呼び出す。 以上のようなケースを仮定するのであれば、先日提示した CreateExampleBox プロシージャと 同じモジュールに以下の Sub プロシージャを追記します。 ------------------------------------------------------------------------- '選択中の段落内の文字列範囲を例文テキストボックスに変換する処理
Sub ConvertToExampleBox()
'選択中の範囲が本文中の文字列範囲ではない場合
If Selection.Type <> wdSelectionNormal Then
'プロシージャを抜ける
Exit Sub
End If
Dim rngSelected As Word.Range
Dim lngParagraphsCount As Long
Dim rngDestination As Word.Range
'選択中の文字列範囲を参照
Set rngSelected = Selection.Range
'その範囲を段落単位に拡張する
rngSelected.Expand Unit:=wdParagraph
'その範囲に含まれる全ての段落の操作
With rngSelected.Paragraphs
'段落の数を取得
lngParagraphsCount = .Count
'最後の段落が「その文書内の最後の段落」である(次の段落がない)場合
If .Last.Next Is Nothing Then
'新しい段落を追加
.Add
'追加した段落を参照範囲から除外する
rngSelected.MoveEnd Unit:=wdParagraph, Count:=-1
End If
'テキストボックスの挿入先範囲として、次の段落の文字列範囲を参照
Set rngDestination = .Last.Next.Range
'始点方向にその範囲の選択を解除(挿入先カーソルを段落の先頭とする)
rngDestination.Collapse Direction:=wdCollapseStart
End With
Dim lngParagraphIndex As Long
Dim rngJapanese As Word.Range
Dim strJapanese As String
Dim rngEnglish As Word.Range
Dim strEnglish As String
'選択範囲内の段落を 2 ずつ進める形でループ
For lngParagraphIndex = 1 To lngParagraphsCount Step 2
'文字列変数の初期化
strJapanese = ""
strEnglish = ""
'現在の(奇数)段落全体の文字列を和訳文として読み込む
Set rngJapanese = rngSelected.Paragraphs(lngParagraphIndex).Range
With rngJapanese
'末尾の改行文字を除外するため
.MoveEnd Unit:=wdCharacter, Count:=-1
'プレーンテキストのみ取得
strJapanese = .Text
End With
'その次の(偶数)段落全体の文字列を英文として読み込む。
'但しその段落が「選択された範囲」に含まれていない場合は読み込まない。
If (lngParagraphIndex + 1) <= lngParagraphsCount Then
Set rngEnglish = rngSelected.Paragraphs(lngParagraphIndex + 1).Range
With rngEnglish
'末尾の改行文字を除外するため
.MoveEnd Unit:=wdCharacter, Count:=-1
'プレーンテキストのみ取得
strEnglish = .Text
End With
End If
'挿入先範囲の操作
With rngDestination
'新しい段落を挿入し、その段落の文字列範囲を参照する
Set rngDestination = .Paragraphs.Add.Range
'始点方向にその範囲の選択を解除する
.Collapse Direction:=wdCollapseStart
'その範囲(=段落の先頭)を Word 上で選択
.Select
'例文テキストボックスの作成処理を呼び出す
CreateExampleBox ActiveDocument, strJapanese, strEnglish
'次の挿入先範囲の参照
Set rngDestination = .Paragraphs.Last.Range
rngDestination.Collapse Direction:=wdCollapseEnd
End With
Set rngJapanese = Nothing
Set rngEnglish = Nothing
Next
'選択範囲全体を削除する(結果、テキストボックスと入れ替わる)
rngSelected.Delete
Set rngDestination = Nothing
Set rngSelected = Nothing
End Sub------------------------------------------------------------------------- |
|
|
|
投稿日時: 25/09/19 19:30:40
投稿者: Tetsuyan
|
|---|---|
|
sk様
|
|



