Excel (VBA)

Excel VBAに関するフォーラムです。
  • 解決済みのトピックにはコメントできません。
このトピックは解決済みです。
質問

 
(Windows 7 Professional : Excel 2010)
replaceでワイルドカードを使用したい
投稿日時: 21/02/11 18:10:59
投稿者: TI

こんばんは。
 
2021/2/1(月)
2021/2/2(火)


 
というデータがあり、曜日の部分(「(月)」等)を削除したいと
考えています。
 
そこで、以下のように記述をしたのですが、曜日の部分が削除
されません。
For i = StartRow To EndRow
         
        Cells(i, 1) = Replace(Cells(i, 1), "(*)", "")
Next
 
ワイルドカードを使用せずに「(月)]、「(火)」等を検索
文字列に指定すると削除されます。
 
いろいろと調べてはいるのですが、どうにも原因がわかりません。
 
どうか、アドバイスをお願いします。

回答
投稿日時: 21/02/11 20:25:27
投稿者: WinArrow
投稿者のウェブサイトに移動

何件あるのかわかりませんが
VBAより、早くて確実な方法を紹介します。
 
一般機能の「区切り位置」というコマンドを使用します。
 
A列の対象セルを選択しておきます。
「データ」タブー「区切り位置」ボタンをクリックします。
最初の画面(1/3)で
「カンマやタブなど〜〜〜」を選択して、「次へ」
(2/3)の画面では、
「その他」を選択し、右側のボックスに「(」を入力して「次へ」
(3/3)の画面では、
1列目を「標準」にすると「日付形式」になります。(推奨)
2列目を選択して「削除する」を選択して「完了」
これで、一括で「曜日」表記が削除できます。
 
なお、1列目は日付形式なので、曜日を表示したければ
セルの書式設定ダイアログで「表示形式」に
yyyy/mm/dd(aaa)
を設定すれば、よいです。
表示形式は計算には使われない(見た目だけ)ので気にすることありません。

投稿日時: 21/02/11 20:45:41
投稿者: TI

ご返信ありがとうございます。
 
早速試してみました。
うまく削除ができました。このようなやり方があることに
びっくりしてしまいました。
 
マクロ記録をしてみたところ、こちらもうまくできました。
 
できれば、ワイルドカードを利用してデータを削除する
方法もわかれば、ありがたいです。
 
最終的な目標としては、元データがCSVデータでして
こちらを読み込んで、不要なデータ(曜日)を削除して
エクセルに展開するというところまで行えればと
考えています。

回答
投稿日時: 21/02/11 21:29:22
投稿者: simple

こうしたことは、その例に限らず一般的な置換と考えても、
いろいろな方法があるでしょうね。
 
一番基本的なのは、カッコの位置を調べて、そこまでを取得する方法です。
(もちろん、これはカッコつき文字が、文字列の最後に来る前提のものです。)

Sub test1()
    Dim i As Long
    Dim s As String
    Dim p As Long

    For i = 1 To 3
        s = Cells(i, 1)
        p = InStr(s, "(")   ' "(" が何文字に表れるか
        If p > 0 Then
            Cells(i, 2) = Left(s, p - 1)
        Else
            Cells(i, 2) = s
        End If
    Next
End Sub

 
次に、「正規表現」と呼ばれるパターンパッチのためのツールを使用するもの。
Sub test2()
    Dim i As Long
    Dim re As Object
    Set re = CreateObject("VBScript.RegExp")
    re.Pattern = "\(.*\)"
    
    For i = 1 To 3
        Cells(i, 2) = re.Replace(Cells(i, 1), "")
    Next
End Sub

これはカッコ付き文字列が、どの位置にあっても変換します。
少し修正すれば、そうしたカッコが複数個あっても変換するようにもできます。
おいおい学習されるとよいかと思います。

回答
投稿日時: 21/02/11 21:54:54
投稿者: simple

念のためメモしますが、
置換の結果確認と原データ保持のため、右の列に書き出しています。
確認ができたら、上書き(結果的にカッコ文字列の削除)してください。
対象範囲ももちろん簡便化しています。

回答
投稿日時: 21/02/11 22:30:19
投稿者: WinArrow
投稿者のウェブサイトに移動

TI さんの引用:

元データがCSVデータでして
こちらを読み込んで、不要なデータ(曜日)を削除して
エクセルに展開するというところまで行えればと
考えています。

 
CSV読込をVBAで実行しているならば、
読み込むコードによってですが、
↑の区切り位置と同じ指定ができるます。
そうすれば、読み込んでから、削除するのではなく
読み込みと同時に削除することができます。

回答
投稿日時: 21/02/11 22:31:00
投稿者: hatena
投稿者のウェブサイトに移動

( より前を取り出せばいいということですね。
Split関数を使うとシンプルに記述できます。
 

For i = StartRow To EndRow         
    Cells(i, 1) =Split(Cells(i, 1), "(")(0)
Next

 
空欄があるとエラーになりますので、もし、空欄の可能性があるなら、
 
For i = StartRow To EndRow         
    Cells(i, 1) =Split(Cells(i, 1) & "(", "(")(0)
Next

回答
投稿日時: 21/02/11 23:03:06
投稿者: WinArrow
投稿者のウェブサイトに移動

引用:

できれば、ワイルドカードを利用してデータを削除する
方法もわかれば、ありがたいです。

Replace関数では、今回の場合、(日)〜(土)までの7個各々の置換しか対応できません。
それよりも、共通の文字列:「(」の前を取り出すといった方法を考えるべきです。
 
 

回答
投稿日時: 21/02/12 07:40:24
投稿者: WinArrow
投稿者のウェブサイトに移動

ワイルドカードは、日本語では「あいまい検索」といいます。
これは一部の文字列を指定する検索の機能であって、
ワイルドカードを指定した置換には適用できないということです。

回答
投稿日時: 21/02/12 09:05:42
投稿者: K.Hiwasa
投稿者のウェブサイトに移動

RangeのReplaceメソッドならワイルドカードが使用できます。
 

Sub test()

  Dim RNG As Range
  Dim StartRow As Long
  Dim EndRow As Long
  
  StartRow = 1
  EndRow = 2
  
  Set RNG = Range(Cells(StartRow, 1), Cells(EndRow, 1))
  
  RNG.Replace "(*)", "", xlPart

  Set RNG = Nothing

End Sub

回答
投稿日時: 21/02/12 10:35:27
投稿者: WinArrow
投稿者のウェブサイトに移動

K.Hiwasa さん、ありがとうございます。
 
私も、ループをやめたら・・・と考え
テストしていたんですが、
LookAt引数の指定を忘れていました。
 
↓のようにすればループせずに置換できます。

    With Range("A1:A3")
        .Replace what:="(*)", replacement:="", Lookat:=xlPart
    End With

投稿日時: 21/02/14 22:49:12
投稿者: TI

皆様、ご返信ありがとうございます。
 
いろいろなやり方があり、本当に驚いております。
 
どの方法でも希望の結果を得ることができました。
まだ、テストの段階ですので、データ量を増やしてみて
それぞれのやり方の処理時間なども比較しながら
最終的な方法を決定したいと思います。
 
また、ワイルドカードでは置換に対応していないと
いうことも勉強になりました。
 
プログラムの勉強を久しぶりに再開しましたが、
やはりとても面白いので、本腰を入れて頑張って
見ようと思います。
 
本当にありがとうございます。