[[20081219111246]] 『置換え』(sinmaipapa) ページの最後に飛ぶ

[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]

 

『置換え』(sinmaipapa)
 いつも参考にさせていただいております。
 置換えですが、うまくいきません。

 設定条件式
 Cells.Replace What:="A", Replacement:="C"
 Cells.Replace What:="B", Replacement:="E"
 Cells.Replace What:="C", Replacement:="K"
 ・・・20個以上続きます。

 元データ
 A
 B
 C

 変更したい形
 C
 E
 K

 現状
 K
 E
 K

 おそらくA→Cと置き換えられたものが、またCの条件式に反応してA→C→Kとなってしまっていると思われます。
 また、置換えられる値は規則的ではありません。

 説明不足があれば指摘してください。

 よろしくおねがいします。


 お書きのとおりですので、置き換えの順序を変えることで可能なのかもしれません。
 C→KをA→Cの前に置換する。
 でも、20個以上あるとなると、それらをみないことにはどうにもならないような気もしますし、
 書いてあるのはダミーの条件だったりすると、回答が無駄になるような気もしますが。。。
   (Hatch)

 早速ありがとうございます。
 確かにダミーですが、ほとんどそのままです。

 順番を入れ替えることで、対応できるところもあるのですが対応しきれないところがあり、
 例えば、検索文字列をA&B&Cや、AorBorCみたいな表示をして、1つの条件式にして出来ないかな?と思っています。
 なんとなくですが、そうすれば2回検索しないので1回で置換えが済めばこのようなことがおきないのでは?と思っています。

 質問の意味が分かりづらいでしょうか?
 (sinmaipapa)

 置換がセルの内容と完全に一致するものを置き換える場合(LookAt:=xlWhole)であれば「A→!C」「B→!E」「C→!K」に置き換え後、
 セルの一部分でも合致したら置き換える置換(LookAt:=xlPart)で「!」を「""」(空文字)に置き換えるといった方法もあるかと。
 (独覚)

 >ほとんどそのままです。
 の「ほとんど」がくせ者ですよね。

 アルファベット一文字で有れば
 順番を入れ替えて、最初と最後に成る文字は
 (と言ってもループするので、どこかの一文字ですが)
 最初に違う文字に置き換えておけば良い様に思います。

 例えば、A→C,C→K,K→Aの様にループするなら
 まずKを「★」に変えておいてA→C,C→Kにしたあと
 ★→Aをする。

 (HANA)

 かような方法はあります。
 ユーザーフォームを一つ作ります。そのフォームは一切さわらなくてもいいです。
 標準モジュールに
 Sub 検索()
    UserForm1.Show 
 End Sub
 をコピペ
 後フォームモジュールに下のコードを貼り付けます。
 検索を実行し、検索文字を _  で区切ります。A_B_C といった塩梅に。
 置き換えをクリックし、今度は置き換え文字を書き込みます。これも _  で区切って
 書き込みます。
 後は必要項目をクリックすれば置き換わります。
        (弥太郎)
 '-------------------------
 Option Explicit
 Private flg As Boolean
 Private txt As Boolean
 Private Lbl As MSForms.Label
 Private c_1 As Boolean, c_2 As Boolean, c_3 As Boolean
 Private WithEvents 全て置き換え As MSForms.CommandButton
 Private WithEvents txtbox As MSForms.TextBox
 Private WithEvents cmb1 As MSForms.ComboBox
 Private WithEvents テキスト As MSForms.TextBox
 Private WithEvents check_1 As MSForms.CheckBox
 Private WithEvents check_2 As MSForms.CheckBox
 Private WithEvents check_3 As MSForms.CheckBox
 Private WithEvents cmb As MSForms.ComboBox
 Private WithEvents 検索 As MSForms.CommandButton
 Private WithEvents 閉じる As MSForms.CommandButton
 Private WithEvents 置き換え As MSForms.CommandButton
 Private Sub check_1_Click()
    c_1 = IIf(check_1, 1, 0)
    txt = True
 End Sub

 Private Sub check_2_Click()
    c_2 = IIf(check_2, 1, 0)
    txt = True
 End Sub

 Private Sub check_3_Click()
    c_3 = IIf(check_3, 1, 0)
    txt = True
 End Sub

 Private Sub cmb_Click()
    txt = True
 End Sub

 Private Sub cmb1_Click()
    txt = True
 End Sub

 Private Sub txtbox_Change()
    flg = True
End Sub

 Private Sub テキスト_Change()
    txt = True
 End Sub

 Private Sub 検索_Click()
    Dim txt1 As String, c As Range, txt2 As String, rng As Range, data, x
    Dim u As Integer, i As Integer, fnd_type, y(), tbl
    Application.ScreenUpdating = False
    txt1 = Replace(テキスト.Text, "_", "_")
    txt2 = cmb.Value
    data = Split(txt1, "_", -1)
    Static flag As Boolean
    Static b As Integer
    Static m() As Variant
    If txt Then flag = False: txt = False
    With CreateObject("vbscript.regexp")
        .Pattern = "(\D+)(\d+)"
        If UBound(data) <> 0 And Not flag Then
            fnd_type = IIf(cmb1 = "値", xlCellTypeConstants, xlCellTypeFormulas)
            Cells.SpecialCells(fnd_type).Cells(1, 1).Activate
            ReDim x(1 To Rows.Count, 1 To 2)
            For i = 0 To UBound(data)
                For Each rng In Cells.SpecialCells(fnd_type)
                    On Error Resume Next
                    Set c = rng.Find(What:=data(i), LookIn:=IIf(cmb1 = "値", xlValues, xlFormulas), _
                                LookAt:=IIf(c_3, xlWhole, xlPart), MatchCase:=IIf(c_1, True, False), _
                                        MatchByte:=IIf(c_2, True, False))
                    If Not c Is Nothing Then
                        ReDim Preserve y(u)
                        If IsError(Application.Match(c.Address(0, 0), y, 0)) Then
                        y(u) = c.Address(0, 0)
                        u = u + 1
                        x(u, 1) = .Replace(c.Address(0, 0), "$1")
                        x(u, 2) = .Replace(c.Address(0, 0), "$2")
                        End If
                    End If
                Next rng
            Next i
            If u = 0 Then MsgBox "そのデータはみあたりまへん", vbExclamation: Exit Sub
            Sheets.Add.Name = "dmy"
            With Sheets("dmy")
                .Range("a1").Resize(u, 2) = x
                .Range("a1").Resize(u, 2).Sort _
                    key1:=IIf(txt2 = "行", .Range("b1"), .Range("a1")), Order1:=xlAscending, key2:= _
                        IIf(txt2 = "行", .Range("a1"), .Range("b1")), Order2:=xlAscending
                tbl = .Range("a1").Resize(u, 2)
                Application.DisplayAlerts = False
                .Delete
                Application.DisplayAlerts = True
            End With
            For i = 1 To u
                ReDim Preserve m(i - 1)
                m(i - 1) = tbl(i, 1) & tbl(i, 2)
            Next
            flag = True
            b = 0
            Range(m(b)).Activate
        ElseIf flag Then
            b = b + 1
            If UBound(m) + 1 = b Then b = 0
            On Error Resume Next
            Range(m(b)).Activate
            If IsError(Range(m(b)).Activate) Then
                MsgBox "予期せぬエラーが発生しました。もう一度やり直してくらはい。", vbExclamation
                Unload Me
                Exit Sub
            End If
        Else
            On Error Resume Next
            If cmb1 = "数式" Then
                ReDim x(1 To Rows.Count, 1 To 2)
                For Each rng In Cells.SpecialCells(xlCellTypeFormulas)
                     On Error Resume Next
                     Set c = rng.Find(What:=テキスト.Text, LookIn:=xlFormulas, _
                                 LookAt:=IIf(c_3, xlWhole, xlPart), MatchCase:=IIf(c_1, True, False), _
                                         MatchByte:=IIf(c_2, True, False))
                     If Not c Is Nothing Then
                         ReDim Preserve y(u)
                         If IsError(Application.Match(c.Address(0, 0), y, 0)) Then
                         y(u) = c.Address(0, 0)
                         u = u + 1
                         x(u, 1) = .Replace(c.Address(0, 0), "$1")
                         x(u, 2) = .Replace(c.Address(0, 0), "$2")
                         End If
                     End If
                 Next rng
                If u = 0 Then MsgBox "そのデータはみあたりまへん", vbExclamation: Exit Sub
                Sheets.Add.Name = "dmy"
                With Sheets("dmy")
                    .Range("a1").Resize(u, 2) = x
                    .Range("a1").Resize(u, 2).Sort _
                        key1:=IIf(txt2 = "行", .Range("b1"), .Range("a1")), Order1:=xlAscending, key2:= _
                            IIf(txt2 = "行", .Range("a1"), .Range("b1")), Order2:=xlAscending
                    tbl = .Range("a1").Resize(u, 2)
                    Application.DisplayAlerts = False
                    .Delete
                    Application.DisplayAlerts = True
                End With
                For i = 1 To u
                    ReDim Preserve m(i - 1)
                    m(i - 1) = tbl(i, 1) & tbl(i, 2)
                Next
                flag = True
                b = 0
                Range(m(b)).Activate
            Else
                Cells.Find(What:=txt1, After:=ActiveCell, LookIn:=IIf(cmb1 = "値", xlValues, _
                        xlFormulas), LookAt:=IIf(c_3, xlWhole, xlPart), SearchOrder:=IIf(txt2 = _
                        "行", xlByRows, xlByColumns), SearchDirection:=xlNext, MatchCase:= _
                        IIf(c_1, True, False), MatchByte:=IIf(c_2, True, False)).Activate

            End If
        End If
        If Err.Number = 91 Then
            MsgBox "それはありまへ〜ん", vbExclamation
            Err.Clear
        End If
    End With
    Application.ScreenUpdating = True
    On Error GoTo 0
 End Sub
 Private Sub 全て置き換え_Click()
    Dim txt_data As String, i As Integer, u As Integer, rng As Range, data_1
    Dim c As Range, actvdata As String, data As String, n As Integer, swch_data, f_data
    Dim data_2
    txt_data = Replace(テキスト.Text, "_", "_")
    If Not txt_data Like "*_*" Then
        On Error Resume Next

        Cells.Replace What:=テキスト.Text, Replacement:=txtbox.Text, LookAt:= _
            IIf(c_3, xlWhole, xlPart), SearchOrder:=IIf(cmb = "行", xlByRows, xlByColumns), _
                 MatchCase:=IIf(c_1, True, False), MatchByte:=IIf(c_2, True, False)
        If Err.Number = 1004 Then
            MsgBox "入力された式は成立しません!", vbExclamation
            Err.Clear
            On Error GoTo 0
            Exit Sub
        End If
    Else
        With CreateObject("vbscript.regexp")
            If Replace(txtbox.Text, "_", "_") Like "*_*" Then
                data_1 = Split(txt_data, "_", -1)
                data_2 = Split(Replace(txtbox.Text, "_", "_"), "_", -1)
                If UBound(data_1) <> UBound(data_2) Then
                    MsgBox "置き換えの数がちゃいます!", vbExclamation
                    txtbox.Text = ""
                    txtbox.SetFocus
                Else
                For Each rng In Cells.SpecialCells(IIf(cmb1 = "値", xlCellTypeConstants, xlCellTypeFormulas))
                    swch_data = IIf(cmb1 = "値", rng.Value, rng.Formula)
                    For i = 0 To UBound(data_1)
                        Set c = rng.Find(What:=data_1(i), LookIn:=IIf(cmb1 = "値", xlValues, xlFormulas), _
                            LookAt:=IIf(c_3, xlWhole, xlPart), MatchCase:=IIf(c_1, True, False), _
                                    MatchByte:=IIf(c_2, True, False))
                        If Not c Is Nothing Then
                            If swch_data Like "=*" Then
                                data = StrConv(StrConv(data_1(i), vbNarrow), vbUpperCase)
                                actvdata = swch_data
                            Else
                                If c_1 + c_2 + c_3 = 0 Then
                                    data = StrConv(StrConv(data_1(i), vbWide), vbUpperCase)
                                    actvdata = StrConv(StrConv(swch_data, vbWide), vbUpperCase)
                                End If
                                If c_1 Then
                                    data = StrConv(data_1(i), vbWide)
                                    actvdata = StrConv(swch_data, vbWide)
                                End If
                                If c_2 Then
                                    data = StrConv(data_1(i), vbUpperCase)
                                    actvdata = StrConv(swch_data, vbUpperCase)
                                End If
                                If c_1 And c_2 Then
                                    data = data_1(i)
                                    actvdata = swch_data
                                End If
                                If c_3 Then
                                    If c_1 + c_2 = 0 Then
                                        data = StrConv(StrConv(data_1(i), vbWide), vbUpperCase)
                                        actvdata = StrConv(StrConv(swch_data, vbWide), vbUpperCase)
                                    End If
                                End If
                            End If
                            .Pattern = data
                            .Global = True
                            If .test(actvdata) Then
                                n = WorksheetFunction.Find(data, actvdata, 1)
                                For u = 1 To .Execute(actvdata).Count
                                    On Error Resume Next
                                    f_data = IIf(cmb1 = "値", rng.Value, rng.Formula)
                                    rng = WorksheetFunction.Replace(f_data, WorksheetFunction _
                                            .Find(data, actvdata, n), Len(data), data_2(i))

                                    If swch_data Like "=*" Then
                                        actvdata = rng.Formula
                                    Else
                                        actvdata = IIf(c_1 + c_2 + c_3 = 0, StrConv(StrConv(rng, vbWide), _
                                            vbUpperCase), IIf(c_1 And c_2, rng, IIf(c_1, StrConv(rng, _
                                                vbWide), IIf(c_2, StrConv(rng, vbUpperCase), rng))))

                                    End If
                                    n = WorksheetFunction.Find(data, actvdata, 1 + Len(data_2(i)) - _
                                             Len(data) + 1) + Len(data_2(i)) - Len(data)
                                Next u
                            End If
                        End If
                    Next i
                Next rng
            End If

            Else
            For Each rng In Cells.SpecialCells(IIf(cmb1 = "値", xlCellTypeConstants, xlCellTypeFormulas))
                For i = 0 To UBound(data_1)
                    Set c = rng.Find(What:=data_1(i), LookIn:=IIf(cmb1 = "値", xlValues, xlFormulas), _
                        LookAt:=IIf(c_3, xlWhole, xlPart), MatchCase:=IIf(c_1, True, False), _
                                MatchByte:=IIf(c_2, True, False))
                    If Not c Is Nothing Then
                        If swch_data Like "=*" Then
                            data = StrConv(StrConv(data_1(i), vbNarrow), vbUpperCase)
                            actvdata = swch_data
                        Else
                            If c_1 + c_2 + c_3 = 0 Then
                                data = StrConv(StrConv(data_1(i), vbWide), vbUpperCase)
                                actvdata = StrConv(StrConv(swch_data, vbWide), vbUpperCase)
                            End If
                            If c_1 Then
                                data = StrConv(data_1(i), vbWide)
                                actvdata = StrConv(swch_data, vbWide)
                            End If
                            If c_2 Then
                                data = StrConv(data_1(i), vbUpperCase)
                                actvdata = StrConv(swch_data, vbUpperCase)
                            End If
                            If c_1 And c_2 Then
                                data = data_1(i)
                                actvdata = swch_data
                            End If
                            If c_3 Then
                                If c_1 + c_2 = 0 Then
                                    data = StrConv(StrConv(data_1(i), vbWide), vbUpperCase)
                                    actvdata = StrConv(StrConv(swch_data, vbWide), vbUpperCase)
                                End If
                            End If
                        End If
                        .Pattern = data
                        .Global = True
                        If .test(actvdata) Then
                            n = WorksheetFunction.Find(data, actvdata, 1)
                            For u = 1 To .Execute(actvdata).Count
                                On Error Resume Next
                                f_data = IIf(cmb1 = "値", rng.Value, rng.Formula)
                                rng = WorksheetFunction.Replace(f_data, WorksheetFunction _
                                        .Find(data, actvdata, n), Len(data), txtbox.Text)

                                If swch_data Like "=*" Then
                                    actvdata = rng.Formula
                                Else
                                    actvdata = IIf(c_1 + c_2 + c_3 = 0, StrConv(StrConv(rng, vbWide), _
                                        vbUpperCase), IIf(c_1 And c_2, rng, IIf(c_1, StrConv(rng, _
                                            vbWide), IIf(c_2, StrConv(rng, vbUpperCase), rng))))

                                End If
                                n = WorksheetFunction.Find(data, actvdata, 1 + Len(txtbox.Text) - _
                                         Len(data) + 1) + Len(txtbox.Text) - Len(data)
                            Next u
                        End If
                    End If
                Next i
            Next rng
            End If
        End With
    End If
    txt = True
 End Sub

 Private Sub 置き換え_Click()
    Dim i As Integer, txt_data As String, actvdata As String, data_1, data_2
    Dim data As String, n As Integer, u As Integer, swch_data
    txt_data = Replace(テキスト.Text, "_", "_")
    If flg Then
        If txt_data Like "*_*" Then
            With CreateObject("vbscript.regexp")
                swch_data = IIf(cmb1 = "値", ActiveCell.Value, ActiveCell.Formula)
                actvdata = StrConv(StrConv(swch_data, vbWide), vbUpperCase)
                data_1 = Split(txt_data, "_", -1)
                If Replace(txtbox.Text, "_", "_") Like "*_*" Then
                    data_2 = Split(Replace(txtbox.Text, "_", "_"), "_", -1)
                    If UBound(data_1) <> UBound(data_2) Then
                        MsgBox "置き換えの数がちゃいます!", vbExclamation
                        txtbox.Text = ""
                        txtbox.SetFocus
                    Else
                        For i = 0 To UBound(data_1)
                            data = StrConv(StrConv(data_1(i), vbWide), vbUpperCase)
                                .Pattern = data
                                .Global = True
                                If .test(actvdata) Then
                                    n = 1
                                    For u = 1 To .Execute(actvdata).Count
                                        On Error Resume Next
                                        ActiveCell = WorksheetFunction.Replace(swch_data, WorksheetFunction _
                                            .Find(data, actvdata, n), Len(data), data_2(i))
                                        If Err.Number = 1004 Then
                                            MsgBox "その式は成立しまへん!", vbExclamation
                                            Err.Clear
                                            On Error GoTo 0
                                            Exit Sub
                                        End If
                                        n = WorksheetFunction.Find(data, actvdata, n) + Len(data_2(i)) _
                                                - Len(data) + 1
                                        swch_data = IIf(cmb1 = "値", ActiveCell.Value, ActiveCell.Formula)
                                        actvdata = StrConv(StrConv(swch_data, vbWide), vbUpperCase)
                                    Next u
                                End If
                        Next i

                    End If
                Else
                    For i = 0 To UBound(data_1)
                        data = StrConv(StrConv(data_1(i), vbWide), vbUpperCase)
                            .Pattern = data
                            .Global = True
                            If .test(actvdata) Then
                                n = 1
                                For u = 1 To .Execute(actvdata).Count
                                    ActiveCell = WorksheetFunction.Replace(swch_data, WorksheetFunction _
                                        .Find(data, actvdata, n), Len(data), txtbox.Text)
                                    n = WorksheetFunction.Find(data, actvdata, n) + Len(txtbox.Text) - Len(data) + 1
                                    actvdata = StrConv(StrConv(swch_data, vbWide), vbUpperCase)
                                Next u
                            End If
                    Next i
                End If
            End With
        Else
            On Error Resume Next
            ActiveCell.Replace What:=テキスト.Text, Replacement:=txtbox.Text, _
                LookAt:=IIf(c_3, xlWhole, xlPart), SearchOrder:=IIf(cmb = "行", _
                    xlByRows, xlByColumns), MatchCase:=IIf(c_1, True, False), _
                            MatchByte:=IIf(c_2, True, False)
            ActiveCell.Select
        End If
    Else
        txtbox.Visible = True
        Lbl.Visible = True
        txtbox.SetFocus
        flg = True
        全て置き換え.Visible = True
    End If
    On Error GoTo 0
 End Sub

 Private Sub 閉じる_Click()
    Unload Me
 End Sub
 Private Sub UserForm_Initialize()
    Dim obj As Object
    With Me
       .Width = 330
       .Height = 140
       .Caption = "スペシャル検索"
    End With
    With Controls.Add("forms.label.1", , True)
        .Top = 8
        .Left = 15
        .Height = 12
        .Width = 150
        .Caption = "検索文字列( _ で区切ると複数可能)"
    End With

    Set テキスト = Controls.Add("forms.textbox.1", , True)
    With テキスト
        .Name = "テキスト"
        .Top = 21
        .Left = 12
        .Height = 15
        .TabIndex = 0
        .Width = 220
        .ControlTipText = "複数検索のばやいは 「_」 で区切って入力"
    End With
    Set txtbox = Controls.Add("forms.textbox.1", , True)
    With txtbox
        .Name = "txtbox"
        .Top = 52
        .Left = 12
        .Height = 15
        .Width = 220
        .Visible = False
    End With
    Set Lbl = Controls.Add("Forms.Label.1", , True)
    With Lbl
        .Top = 40
        .Left = 15
        .Height = 12
        .Width = 150
        .Caption = "置き換え文字列"
        .Visible = False
    End With
    With Controls.Add("forms.label.1", , True)
        .Top = 75
        .Height = 12
        .Left = 12
        .Width = 42
        .Caption = "検索方向"
    End With
    Set cmb = Controls.Add("forms.combobox.1", , True)
    With cmb
        .Top = 70
        .Left = 66
        .Height = 18
        .Width = 54
        .AddItem "行"
        .AddItem "列"
        .Text = .List(0)
    End With
    Set check_1 = Controls.Add("forms.checkbox.1", , True)
    With check_1
        .Height = 13
        .Left = 132
        .Top = 68
        .Width = 102
        .Caption = "大文字小文字を区別する"
    End With
    Set check_2 = Controls.Add("forms.checkbox.1", , True)
    With check_2
        .Height = 13
        .Left = 132
        .Top = 82
        .Width = 102
        .Caption = "全角半角を区別する"
    End With
    Set check_3 = Controls.Add("forms.checkbox.1", , True)
    With check_3
        .Height = 13
        .Left = 132
        .Top = 98
        .Width = 102
        .Caption = "完全一致の検索"
    End With
    Set 検索 = Controls.Add("forms.commandbutton.1", , True)
    With 検索
        .Height = 17
        .Left = 260
        .Top = 13
        .Width = 50
        .Caption = "検 索"
        .TabIndex = 1
    End With
    Set 閉じる = Controls.Add("forms.commandbutton.1", , True)
    With 閉じる
        .Height = 17
        .Left = 260
        .Top = 36
        .Width = 50
        .Caption = "閉じる"
    End With
    Set 置き換え = Controls.Add("forms.commandbutton.1", , True)
    With 置き換え
        .Height = 17
        .Left = 260
        .Top = 60
        .Width = 50
        .Caption = "置き換え"
    End With
    Set 全て置き換え = Controls.Add("forms.commandbutton.1", , True)
    With 全て置き換え
        .Height = 17
        .Left = 260
        .Top = 84
        .Width = 50
        .Caption = "全て置き換え"
        .Visible = False
    End With
    Set cmb1 = Controls.Add("forms.combobox.1", , True)
    With cmb1
        .Top = 90
        .Left = 66
        .Height = 18
        .Width = 54
        .AddItem "値"
        .AddItem "数式"
        .Text = .List(0)
    End With
    With Controls.Add("forms.label.1", , True)
        .Top = 95
        .Left = 12
        .Height = 12
        .Width = 42
        .Caption = "対象"
    End With
 End Sub


 皆様ありがとうございます。
 弥太郎さんのはすごいですね。
 勉強不足の私には、半分ぐらいしか理解が出来ませんでした。

 HANAさんの言うとおり確かに、だいたい・・・がくせものですね。

 実際の物の1部です。

 C→CD
 CIF→CL
 R→RG
 RC→RCのまま

 と、言ったようにしたいのですが、今は
 C→CD
 CIF→CDIF
 R→RG
 RC→RGCD

 となっていました。

 独覚さんのLookAt:=xlWholeで対応できました。
 完全一致の変換。新しい知識が増えました。

 ありがとうございます。
 (shinmaipapa)

コメント返信:

[ 一覧(最新更新順) ]


YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki. Modified by kazu.