Sub MyStrNum()
  Rem *----*----*    *----*----*    *----*----*    *----*----*
  Rem 漢数字検索 洋数字置換 逐次 半自動処理
  Rem 記録者:Hitrock Camellia Shinopy
  Rem 言語:Word VBA
  Rem 機能:カーソル位置から後の漢数字を検索し、洋数字に置換する。
  Rem 参照設定する場合...
  Rem     Microsoft VBScript Regular Expressions 5.5
  Rem 注記...
  Rem  「myStrNum」を起動して使用。
  Rem   兆単位までの漢数字を検索。
  Rem   蛍光ペン書式の設定にwdTurquoise(水色)を使用。
  Rem 履歴...
  Rem   第1版:2004/11/30:作成。
  Rem   第2版:2004/12/02:不具合修正。
  Rem   第3版:2006/05/03:逐次置換処理・モーダル処理に変更。
  Rem   第4版:2006/05/22:位取りがない場合に、単純置換する処理を追加。
  Rem *----*----*    *----*----*    *----*----*    *----*----*
  Dim myTitle As String
  Dim myHead As String
  Dim myMsg As String
  Dim myAns As Long
  Dim myCbox(5) As Boolean
  Dim myCboxFlag As Boolean
  Dim i As Integer
  Dim j As Integer
  '
  Dim myRange As Range
  Dim myChrs As Characters
  Dim myStartMarker As Word.Range
  Dim myText As String
  Dim myCount As Long
  Dim myCountRep As Long
  Dim myMoveRight As Integer
  '
  Dim myRegExp As Variant ' VBScript_RegExp_55.RegExp
  Dim myMatches As Variant ' MatchCollection
  Dim myMatch As Variant ' Match
  Dim myPttn As String
  Dim myDigit As String
  Dim myUnit As String
  Rem *----*----*    *----*----*    *----*----*    *----*----*
  '
  myTitle = "MyStrNum"
  myHead = "漢数字 検索" & vbCr & "洋数字 置換" & vbCr & "逐次 半自動 処理"
  Assistant.Visible = True
  '
  myMsg = "[検索]ボタンを押して、" & vbCr & "処理を開始して下さい。"
  myMsg = myMsg & " " & vbCr
  myMsg = myMsg & "カーソル位置から後を検索します。"
  Application.StatusBar = myTitle & ":" & Replace(myMsg, vbCr, "")
  With Assistant.NewBalloon
    .Animation = msoAnimationIdle
    .BalloonType = msoBalloonTypeButtons
    .Icon = msoIconAlertInfo
    .Button = msoButtonSetCancel
    .Heading = myTitle & vbCr & myHead
    .Text = myMsg
    .Labels(1).Text = "[検索]"
    .Checkboxes(1).Text = "2字以上"
    .Checkboxes(2).Text = "〜円"
    .Checkboxes(3).Text = "〜m/km/g/kg"
    .Checkboxes(4).Text = ""
    .Checkboxes(5).Text = ""
    .Mode = msoModeModal
    myAns = .Show
    myCbox(0) = False
    myUnit = ""
    For i = 1 To 5
      myCbox(i) = .Checkboxes(i).Checked
      Select Case i
        Case 2, 3
          If myCbox(i) = True Then
            myCbox(0) = True
            myUnit = myUnit & .Checkboxes(i).Text & "/"
            myUnit = Replace(myUnit, "〜", "")
          End If
      End Select
    Next ' i
    If myCbox(0) = True Then
      myUnit = Left(myUnit, Len(myUnit) - 1)
      myUnit = Replace(myUnit, "/", "|")
    End If
  End With
  '
  If myAns = msoBalloonButtonCancel Then
    Assistant.NewBalloon.Close
    Assistant.Visible = False
    Exit Sub
  End If
  Rem *----*----*    *----*----*    *----*----*    *----*----*
  '
  myDigit = "〇一二三四五六七八九十百千万億兆"
  '
  myPttn = "[" & myDigit & "]"
  If myCbox(1) = True Then
    myPttn = myPttn & "{2,}"
    Rem 十以上の場合: "(" & myPttn & "{2,})|([十百千]{1})"
  Else
    myPttn = myPttn & "{1,}"
  End If
  '
  If myCbox(0) = True Then
    myPttn = myPttn & "(" & myUnit & ")"
  End If
  '
  Rem カーソルが文章の途中あると、不都合が起こるので、
  Rem 文章の先頭に移動する。
  Selection.Sentences(1).Select
  Selection.Collapse wdCollapseStart
  Rem カーソル位置から文書の末尾までの範囲を選択する。
  Selection.EndKey Unit:=wdStory, Extend:=wdExtend
  Set myRange = Selection.Range
  Set myChrs = myRange.Characters
  myRange.Select
  '
  Set myRegExp = CreateObject("VBScript.RegExp") ' New VBScript_RegExp_55.RegExp
  With myRegExp
    .Pattern = myPttn ' パターンを設定
    .IgnoreCase = False ' 大文字と小文字を区別する
    .Global = True ' 文字列全体を検索
  End With
  Set myMatches = myRegExp.Execute(myRange.Text)
  Rem 検索開始点の取得。
  Selection.Collapse wdCollapseStart
  Set myStartMarker = Selection.Range
  myCount = 0
  myCountRep = 0
  '
  If myMatches.Count = 0 Then
    myMsg = "検索終了:" & vbCr & "該当する漢数字がありません。"
    Application.StatusBar = myTitle & ":" & Replace(myMsg, vbCr, "")
    With Assistant.NewBalloon
      .Animation = msoAnimationIdle
      .BalloonType = msoBalloonTypeButtons
      .Icon = msoIconAlertInfo
      .Button = msoButtonSetOK
      .Heading = myTitle & vbCr & myHead
      .Text = myMsg
      .Mode = msoModeModal
      .Show
    End With
    '
    GoTo MyStrNumSubExit
  End If
  '
  Rem 漢数字を検索。
  With Selection.Find
    For i = 0 To myMatches.Count - 1
      .ClearFormatting
      .Text = myMatches.Item(i).Value
      .Forward = True
      .Wrap = wdFindStop
      .MatchCase = True
      .MatchAllWordForms = False
      .MatchSoundsLike = False
      .MatchFuzzy = False
      .MatchWildcards = False
      .Execute
      Rem *----*----*    *----*----*
      '
      Rem 円/m/km/g/kgを選択範囲からはずす。
      myMoveRight = 0
      If myCbox(0) = True Then
        For j = 1 To 2 ' ←単位の最大文字数 Len("km")
          Select Case True
            Case Selection.Characters.Last.Text Like "[" & myDigit & "]"
              Rem 漢数字の場合は、何もしない。
            Case Else
              Rem 選択範囲を1文字狭める。
              Call Selection.MoveLeft(wdCharacter, 1, wdExtend)
              myMoveRight = myMoveRight + 1
          End Select
        Next ' j
      End If
      Call MyStrNumScroll
      Rem 検索した文字列を蛍光ペン書式にする。
      Selection.Range.HighlightColorIndex = wdTurquoise ' 水色
      DoEvents ' 画面更新のため、瞬間停止。
      myText = Selection.Range.Text
      '
      myCount = myCount + 1
      myMsg = "洋数字に置換しますか?"
      Application.StatusBar = myTitle & ":" & myMsg & " " & myCount & "/" & myMatches.Count
      '
      With Assistant.NewBalloon
        .Animation = msoAnimationIdle
        .BalloonType = msoBalloonTypeButtons
        .Icon = msoIconAlertQuery
        .Button = msoButtonSetCancel
        .Heading = myTitle & vbCr & myHead
        .Text = myMsg
        .Labels(1).Text = "はい"
        .Labels(2).Text = "いいえ"
        Rem 位取りがない漢数字の場合
        If (InStr(myText, "千") + InStr(myText, "百") + InStr(myText, "十")) = 0 Then
          If Len(myText) >= 5 Then
            .Checkboxes(1).Text = "単純置換"
          End If
        End If
        .Mode = msoModeModal
        myAns = .Show
        myCboxFlag = .Checkboxes(1).Checked
      End With
      '
      Selection.Range.HighlightColorIndex = wdNoHighlight ' 蛍光ペン書式解除
      If myAns = msoBalloonButtonCancel Then
        Rem [キャンセル]
        GoTo MyStrNumSubExit
      End If
      If myAns = 1 Then
        Set myChrs = Selection.Range.Characters
        Rem 選択範囲の文字列を洋数字に置換する。
        Call MyStrNumReplace(myCboxFlag)
        myCountRep = myCountRep + 1
        Rem 時間待ち処理
        Call MyStrNumDoEvents(3000)
      Else
        Rem 選択範囲を解除する。(カーソルは文字列の後)
        Selection.Collapse wdCollapseEnd
        Rem 時間待ち処理
        Call MyStrNumDoEvents(3000)
      End If
      Call Selection.MoveRight(wdCharacter, myMoveRight, wdMove)
    Next ' i
  End With
  '
  myMsg = "検索終了:" & vbCr
  myMsg = myMsg & "全部で、" & myCount & "件 検索しました。"
  myMsg = myMsg & " " & vbCr
  myMsg = myMsg & "その内、" & myCountRep & "件 置換しました。"
  Application.StatusBar = myTitle & ":" & Replace(myMsg, vbCr, "")
  With Assistant.NewBalloon
    .Animation = msoAnimationIdle
    .BalloonType = msoBalloonTypeButtons
    .Icon = msoIconAlertInfo
    .Button = msoButtonSetOK
    .Heading = myTitle & vbCr & myHead
    .Text = myMsg
    .Mode = msoModeModal
    .Show
  End With
  Rem *----*----*    *----*----*    *----*----*    *----*----*
  '
MyStrNumSubExit:
  myStartMarker.Select
  Assistant.NewBalloon.Close
  Assistant.Visible = False
  '
  Set myRange = Nothing
  Set myRegExp = Nothing
  Set myStartMarker = Nothing
  Set myChrs = Nothing
End Sub ' MyStrNum *----*----*    *----*----*    *----*----*    *----*----*

Sub MyStrNumScroll()
  Rem *----*----*    *----*----*    *----*----*    *----*----*
  Rem 現在の選択範囲が文書ウィンドウに表示されるように、
  Rem 作業中の文書をスクロールする。
  Rem *----*----*    *----*----*    *----*----*    *----*----*
  On Error Resume Next
  '
  Application.ScreenUpdating = False
  '
  ActiveDocument.ActiveWindow.PageScroll Up:=1
  ActiveWindow.ScrollIntoView Selection.Range, True
  '
  Application.ScreenUpdating = True
End Sub ' MyStrNumScroll *----*----*    *----*----*    *----*----*    *----*----*

Sub MyStrNumDoEvents(myMax As Long)
  Rem *----*----*    *----*----*    *----*----*    *----*----*
  Rem 時間待ち処理
  Rem *----*----*    *----*----*    *----*----*    *----*----*
  Dim i As Long
  '
  For i = 1 To myMax
    DoEvents: DoEvents: DoEvents: DoEvents: DoEvents
    DoEvents: DoEvents: DoEvents: DoEvents: DoEvents
    DoEvents: DoEvents: DoEvents: DoEvents: DoEvents
    DoEvents: DoEvents: DoEvents: DoEvents: DoEvents
    DoEvents: DoEvents: DoEvents: DoEvents: DoEvents
  Next ' i
End Sub ' MyStrNumDoEvents *----*----*    *----*----*    *----*----*    *----*----*

Sub MyStrNumReplace(myCboxFlag As Boolean)
  Rem *----*----*    *----*----*    *----*----*    *----*----*
  Rem 選択範囲の文字列を洋数字に置換する。
  Rem *----*----*    *----*----*    *----*----*    *----*----*
  Dim myArray As Variant
  Dim myArrayDigitRev(1 To 20) As Variant
  Dim myFlagIsNumeric As Boolean
  Dim myFlagDigit As Integer
  Dim myFlagUnit As Integer
  Dim myText As String
  Dim myTextCount As Long
  Dim myDigit As String
  Dim i As Integer
  Dim j As Integer
  '
  Rem 数値判断用の表を準備する。
  myArray = Array("〇", "一", "二", "三", "四", "五", "六", "七", "八", "九", "十", "百", "千", "万", "億", "兆", "京")
  myText = Selection.Range.Text
  '
myStrNumReplaceSubEntry:
  Rem 位取りがない場合、漢数字から洋数字へ単純置換する。
  If (InStr(myText, "千") + InStr(myText, "百") + InStr(myText, "十")) = 0 Then
    myDigit = Selection.Range.Text
    myDigit = Replace(myDigit, "〇", "0")
    myDigit = Replace(myDigit, "一", "1")
    myDigit = Replace(myDigit, "二", "2")
    myDigit = Replace(myDigit, "三", "3")
    myDigit = Replace(myDigit, "四", "4")
    myDigit = Replace(myDigit, "五", "5")
    myDigit = Replace(myDigit, "六", "6")
    myDigit = Replace(myDigit, "七", "7")
    myDigit = Replace(myDigit, "八", "8")
    myDigit = Replace(myDigit, "九", "9")
    Selection.Range.Text = myDigit
    Selection.MoveRight Unit:=wdCharacter, Count:=Len(myDigit), Extend:=wdExtend
    
    Select Case Len(myDigit)
      Case 1 To 4
        myFlagDigit = Len(myDigit) - 1
        myFlagUnit = 1
      Case Else
        myFlagUnit = Len(myDigit) \ 4
        myFlagUnit = myFlagUnit * 4 + 1
        myFlagDigit = Len(myDigit) - myFlagUnit
    End Select
    '
    If myCboxFlag = True Then
      Selection.Collapse wdCollapseEnd
      Exit Sub
    Else
      GoTo myStrNumReplaceSubExit
    End If
  End If
  '
  Rem 以下、位取りがある場合の漢数字から洋数字へ置換処理。
  Rem 逆順表を準備する。
  Selection.Collapse wdCollapseEnd
  For i = 1 To UBound(myArrayDigitRev)
    myArrayDigitRev(i) = "〇"
  Next i
  '
  myFlagUnit = 1 ' 一の位
  myFlagDigit = 0
  With Selection.Range
    Do
      Rem 下の位から順に文字列を選択する。
      myTextCount = Selection.MoveLeft(wdCharacter, 1, wdExtend)
      If myTextCount = 0 Then
        Exit Do
      End If
      '
      Rem 選択した文字列が漢数字かどうか調べて、
      Rem 逆順表に数値を転記する。
      For i = 0 To UBound(myArray)
        If Left(Selection.Range.Text, 1) = myArray(i) Then
          myFlagIsNumeric = True
          Select Case myArray(i)
            Case "十"
              myFlagDigit = 1
            Case "百"
              myFlagDigit = 2
            Case "千"
              myFlagDigit = 3
            Case "万"
              myFlagUnit = 5
            Case "億"
              myFlagUnit = 9
            Case "兆"
              myFlagUnit = 13
            Case "京"
              myFlagUnit = 17
          End Select
          Select Case myArray(i)
            Case "〇", "一", "二", "三", "四", "五", "六", "七", "八", "九"
              myArrayDigitRev(myFlagUnit + myFlagDigit) = myArray(i)
            Case "十", "百", "千"
              myArrayDigitRev(myFlagUnit + myFlagDigit) = "一"
            Case Else
              myArrayDigitRev(myFlagUnit) = "一"
              myFlagDigit = 0
          End Select
          Exit For
        Else
          myFlagIsNumeric = False
        End If
      Next i
      '
      Rem 上の位が漢数字でない場合は、右へ1文字分戻り、繰り返しを抜ける。
      If myFlagIsNumeric = False Then
        Selection.MoveRight Unit:=wdCharacter, Count:=1, Extend:=wdExtend
        Exit Do
      End If
    Loop
    '
    Rem 逆順表を元に洋数字に置換し、選択範囲の文字列を置換する。
    myDigit = Join(myArrayDigitRev(), "")
    myDigit = Left(myDigit, myFlagUnit + myFlagDigit)
    myDigit = StrReverse(myDigit)
    myDigit = Replace(myDigit, "〇", "0")
    myDigit = Replace(myDigit, "一", "1")
    myDigit = Replace(myDigit, "二", "2")
    myDigit = Replace(myDigit, "三", "3")
    myDigit = Replace(myDigit, "四", "4")
    myDigit = Replace(myDigit, "五", "5")
    myDigit = Replace(myDigit, "六", "6")
    myDigit = Replace(myDigit, "七", "7")
    myDigit = Replace(myDigit, "八", "8")
    myDigit = Replace(myDigit, "九", "9")
  End With
  Selection.Range.Text = myDigit
  '
myStrNumReplaceSubExit:
  Rem 位取りを4桁ごとに文字列に挿入する。
  Selection.Collapse wdCollapseStart
  If myFlagUnit < 5 Then
    Selection.MoveRight Unit:=wdCharacter, Count:=myFlagDigit + 1, Extend:=wdMove
  Else
    Select Case myFlagUnit
      Case 5   '  万
        j = 13
      Case 9   '  億
        j = 14
      Case 13  '  兆
        j = 15
      Case 17  '  京
        j = 16
    End Select
    Selection.MoveRight Unit:=wdCharacter, Count:=myFlagDigit + 1, Extend:=wdMove
    For i = 1 To ((myFlagUnit - 1) / 4)
      Selection.InsertBefore (myArray(j))
      j = j - 1
      Selection.MoveRight Unit:=wdCharacter, Count:=5, Extend:=wdMove
    Next ' i
  End If
End Sub ' myStrNumReplace *----*----*    *----*----*    *----*----*    *----*----*
inserted by FC2 system