VBA
Publisher

Publisher VBA 全世界初数字をコンマ付き数字に変えるマクロ

たぶん全世界初

検索しても見つからないので。まあコンマじゃない国もあるし(ドイツが確か上)Publisher自体マイナーなので。

Word に続いて

Word VBA 数字をコンマ付き数字に変えるマクロ
が出来たので、これをPublsherに移植してみました。
いまのところ、単純な整数のみです。
というかここに来るまでが大変でしたけど。

Sub Insertcommas()
'For Publisher
'Microsoft VBScript Regular Expression 5.5 Laterを参照設定してください。

Dim pbDoc As Publisher.Document: Set pbDoc = ThisDocument
Dim pbPage As Publisher.Page, pbPages As Publisher.Pages
Dim shps As Publisher.Shapes, Shp As Publisher.Shape
Dim i As Long, i1 As Long, i2 As Long, iLength As Long
Dim tFrame As TextFrame, pbStories As Publisher.Stories, pbStory As Publisher.Story
Dim tRn1 As TextRange, tRng As Publisher.TextRange, tRn1sub As TextRange
Dim str As String
Set pbStories = pbDoc.Stories
For Each pbStory In pbStories
 If pbStory.HasTextFrame Then
  Set tFrame = pbStory.TextFrame
  Set tRng = tFrame.TextRange
  iLength = tRng.Length
  For i = iLength To 1 Step -1
     Set tRn1 = tRng.Characters(Start:=i, Length:=1)
      If IsNumericString(tRn1.Text) Then
         str = ""
         str = tRn1.Text
         For i1 = i - 1 To 1 Step -1
         Set tRn1sub = tRng.Characters(Start:=i1, Length:=1)
          If IsNumericString(tRn1sub.Text) Then
           str = tRn1sub.Text & str
           Else
             If Len(str) > 3 Then
             Call StringInsertcommma(i, iLength, i1, tRng, str)
             Exit For
             Else
             Exit For
             End If
          End If
         Next i1
       End If 'If IsNumericString(tRn1.Text) Then
  Next
 End If 'If pbStory.HasTextFrame Then
Next 'For Each pbStory In pbStories
End Sub
Sub StringInsertcommma(i As Long, iLength As Long, i1 As Long, tRng As TextRange, str As String)
Dim re As RegExp: Set re = New RegExp
Dim iDigi As Long
Dim tRna As TextRange
Dim tRNext As TextRange
Dim tRPrev As TextRange
Dim icommas As Long
Dim icnt As Long, icnt1 As Long
Dim buf As String
Dim rngFind As TextRange
Set tRna = tRng.Characters(Start:=i1 + 1, Length:=i - i1)
If tRna.Length <= 3 Then
icommas = 1
Else
  icommas = Int(tRna.Length / 3) - 1
  If tRna.Length Mod 3 <> 0 Then
  icommas = icommas + 1

  End If
End If
buf = ""
icnt1 = 1
For icnt = Len(str) To 1 Step -1
If icnt1 Mod 3 <> 0 Then
  buf = Mid(str, icnt, 1) & buf
Else
  buf = "," & Mid(str, icnt, 1) & buf
End If
icnt1 = icnt1 + 1
Next icnt
If Mid(buf, 1, 1) = "," Then buf = Replace(buf, ",", "", 1, 1, vbTextCompare)
With tRna.Find
.ReplaceScope = pbReplaceScopeOne
.FindText = str
.ReplaceWithText = buf
.Execute
End With


Set re = Nothing

End Sub
Function IsNumericString(str As String) As Boolean
Dim re As RegExp: Set re = New RegExp
With re
.Pattern = "[0-9]"
.Global = True
.IgnoreCase = False
.Multiline = False
If .Test(str) Then IsNumericString = True Else IsNumericString = False
End With
Set re = Nothing
End Function

ポイント

  • VBScript Regular Expression 5.5を参照設定してください。
  • ほぼすべてのテキストレンジを取得するにはActiveDocument.Storiesを使う。
  • この場合、全ページのテキストレンジを扱える。
  • 各テキストレンジの最後から順にテキストレンジを動かして数字ではないところでいったん変換する。
  • 変換文字列(コンマ入り数字)を作ってからReplaceする。中途半端にテキストレンジを動かすと例外処理でおかしくなる。
  • 現在のところ半角数字のみ。年などの例外処理はない。(あとから追加する予定)
  • ワイルドカードがないのがWordと違う点。(参照設定をしないと正規表現が使えない)

確認されている問題

  • 現在のところ1行目の1文字目から始まる数字が変換できません。なぜか2行目までテキストレンジが広がっていて、調べています。