[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]
『置換え』(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.